UNPKG

rawsql-ts

Version:

High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.

141 lines 5.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SelectBodyExtractor = void 0; const CreateTableQuery_1 = require("../models/CreateTableQuery"); const InsertQuery_1 = require("../models/InsertQuery"); const Lexeme_1 = require("../models/Lexeme"); const ValuesQuery_1 = require("../models/ValuesQuery"); const Clause_1 = require("../models/Clause"); const FullNameParser_1 = require("../parsers/FullNameParser"); const SelectQueryParser_1 = require("../parsers/SelectQueryParser"); const SqlParser_1 = require("../parsers/SqlParser"); const SqlTokenizer_1 = require("../parsers/SqlTokenizer"); class SelectBodyExtractor { static extract(input) { if (typeof input === "string") { return this.extractFromSql(input); } return this.extractFromStatement(input); } static extractFromSql(sql) { const lexemes = new SqlTokenizer_1.SqlTokenizer(sql).readLexemes(); if (this.isCreateViewStatement(lexemes)) { return this.extractCreateViewFromLexemes(lexemes); } return this.extractFromStatement(SqlParser_1.SqlParser.parse(sql)); } static extractFromStatement(statement) { if (statement instanceof CreateTableQuery_1.CreateTableQuery) { const targetName = this.createTableTargetName(statement); if (!statement.asSelectQuery) { return this.unsupported(targetName); } return { supported: true, kind: "create-table-as", targetName, selectQuery: statement.asSelectQuery }; } if (statement instanceof InsertQuery_1.InsertQuery) { const targetName = this.insertTargetName(statement); if (!statement.selectQuery || statement.selectQuery instanceof ValuesQuery_1.ValuesQuery) { return this.unsupported(targetName); } return { supported: true, kind: "insert-select", targetName, selectQuery: statement.selectQuery }; } return { supported: false, kind: null, targetName: null, selectQuery: null, reason: "Statement type is not supported." }; } static extractCreateViewFromLexemes(lexemes) { var _a, _b, _c, _d, _e, _f; let idx = 0; idx++; // CREATE const materialized = ((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) === "materialized"; if (materialized) { idx++; } if (((_b = lexemes[idx]) === null || _b === void 0 ? void 0 : _b.value.toLowerCase()) !== "view") { return this.unsupported(null, "Statement type is not supported."); } idx++; if (((_c = lexemes[idx]) === null || _c === void 0 ? void 0 : _c.value.toLowerCase()) === "if not exists") { idx++; } const targetResult = FullNameParser_1.FullNameParser.parseFromLexeme(lexemes, idx); idx = targetResult.newIndex; const targetName = [...((_d = targetResult.namespaces) !== null && _d !== void 0 ? _d : []), targetResult.name.name].join("."); if (((_e = lexemes[idx]) === null || _e === void 0 ? void 0 : _e.type) === Lexeme_1.TokenType.OpenParen) { idx = this.consumeBalancedParentheses(lexemes, idx); } if (((_f = lexemes[idx]) === null || _f === void 0 ? void 0 : _f.value.toLowerCase()) !== "as") { return this.unsupported(targetName); } idx++; const selectResult = SelectQueryParser_1.SelectQueryParser.parseFromLexeme(lexemes, idx); return { supported: true, kind: materialized ? "create-materialized-view" : "create-view", targetName, selectQuery: selectResult.value }; } static isCreateViewStatement(lexemes) { var _a, _b, _c; if (((_a = lexemes[0]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) !== "create") { return false; } const second = (_b = lexemes[1]) === null || _b === void 0 ? void 0 : _b.value.toLowerCase(); const third = (_c = lexemes[2]) === null || _c === void 0 ? void 0 : _c.value.toLowerCase(); return second === "view" || (second === "materialized" && third === "view"); } static consumeBalancedParentheses(lexemes, index) { let idx = index; let depth = 0; while (idx < lexemes.length) { if (lexemes[idx].type === Lexeme_1.TokenType.OpenParen) { depth++; } else if (lexemes[idx].type === Lexeme_1.TokenType.CloseParen) { depth--; if (depth === 0) { return idx + 1; } } idx++; } return idx; } static createTableTargetName(query) { var _a; return [...((_a = query.namespaces) !== null && _a !== void 0 ? _a : []), query.tableName.name].join("."); } static insertTargetName(query) { const source = query.insertClause.source; if (source.datasource instanceof Clause_1.TableSource) { return source.datasource.getSourceName(); } return source.getAliasName(); } static unsupported(targetName, reason = "No embedded SELECT body found.") { return { supported: false, kind: null, targetName, selectQuery: null, reason }; } } exports.SelectBodyExtractor = SelectBodyExtractor; //# sourceMappingURL=SelectBodyExtractor.js.map