UNPKG

ts-sql

Version:

An SQL builder in Typescript. This project is heavily inspired by [XQL](/extjs/xql). A big shout out to @exjs and @kobalicek for this amazing project.

164 lines 7.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const queryVisitor_1 = require("./queryVisitor"); class CompilationContext { constructor(currentNode) { this.currentNode = currentNode; this.parentNode = undefined; this.queryString = ""; } } exports.CompilationContext = CompilationContext; class QueryCompiler extends queryVisitor_1.QueryVisitor { constructor(dialect, query, contextBuilder = CompilationContext) { super(dialect, query, contextBuilder); this.dialect = dialect; this.visitSqlRoot = (context, node) => { context.queryString = node.statements.map(s => this.visitNode(context, s).queryString).join(this.delimiter + " "); return context; }; this.visitQueryExpression = (context, node) => { let query = "SELECT "; let elementStrings = []; if (node.selectAll) { elementStrings.push("*"); } query += elementStrings.concat(node.elements.map(v => this.visitNode(context, v).queryString)).join(", "); if (node.from) { query += " " + this.visitNode(context, node.from).queryString; } if (node.orderBy) { query += " " + this.visitNode(context, node.orderBy).queryString; } if (node.limit) { query += " " + this.visitNode(context, node.limit).queryString; } context.queryString = query; return context; }; this.visitConstant = (context, node) => { if (node.value !== "NULL" && node.value !== "NOT NULL" && typeof node.value === "string") { context.queryString = "'" + node.value + "'"; } else { context.queryString = node.value.toString(); } return context; }; this.visitFromClause = (context, node) => { let fromClause = node.tables.map(t => this.visitNode(context, t).queryString).join(", "); fromClause = "FROM " + fromClause; if (node.where) { fromClause += " " + this.visitNode(context, node.where).queryString; } if (node.groupBy) { fromClause += " " + this.visitNode(context, node.groupBy).queryString; } if (node.having) { fromClause += " HAVING " + this.visitNode(context, node.having).queryString; } context.queryString = fromClause; return context; }; this.visitTableSource = (context, node) => { let table = this.visitNode(context, node.tableSourceItem).queryString; let joins = node.joins ? node.joins.map(j => this.visitNode(context, j).queryString) : []; joins = [table].concat(joins); context.queryString = joins.join(" "); return context; }; this.visitJoinClause = (context, node) => { let joinClause = (node.joinType ? node.joinType + " " : "") + "JOIN "; joinClause += this.visitNode(context, node.joinWith).queryString; if (node.on) { joinClause += " ON " + this.visitNode(context, node.on).queryString; } context.queryString = joinClause; return context; }; this.visitTableSpec = (context, node) => { context.queryString = node.tableName.toString(); return context; }; this.visitGroupByClause = (context, node) => { let groupByClause = "GROUP BY " + node.items.map(i => this.visitNode(context, i).queryString).join(", "); context.queryString = groupByClause; return context; }; this.visitAliasedTerm = (context, node) => { let termQuery = this.visitNode(context, node.term).queryString; context.queryString = node.alias ? termQuery + " AS " + node.alias : termQuery; return context; }; this.visitSimpleFunctionCall = (context, node) => { let func = node.name + "(" + (node.args || []).map(a => this.visitNode(context, a).queryString).join(", ") + ")"; context.queryString = func; return context; }; this.visitBinaryPredicate = (context, node) => { context.queryString = "(" + this.visitNode(context, node.left).queryString + " " + node.operator.toString() + " " + this.visitNode(context, node.right).queryString + ")"; return context; }; this.visitLikePredicate = (context, node) => { context.queryString = "(" + this.visitNode(context, node.left).queryString + (node.negate ? " NOT LIKE " : " LIKE ") + this.visitNode(context, node.right).queryString + ")"; return context; }; this.visitColumnName = (context, node) => { context.queryString = node.table ? node.table.toString() + "." + node.name.toString() : node.name.toString(); return context; }; this.visitWhereClause = (context, node) => { context.queryString = "WHERE " + this.visitNode(context, node.expression).queryString; return context; }; this.visitOrderByClause = (context, node) => { context.queryString = "ORDER BY " + node.expressions.map(oe => this.visitNode(context, oe).queryString).join(", "); return context; }; this.visitOrderByExpression = (context, node) => { context.queryString = this.visitNode(context, node.expression).queryString + (node.descending ? " DESC " : " ASC "); return context; }; this.visitLimitClause = (context, node) => { context.queryString = "LIMIT " + node.limit.toString() + (node.offset ? node.offset.toString() : ""); return context; }; this.visitBinaryExpression = (context, node) => { context.queryString = "(" + this.visitNode(context, node.left).queryString + " " + node.operator.toString() + " " + this.visitNode(context, node.right).queryString + ")"; return context; }; this.delimiter = ";"; } compile() { let context = this.visit(); return context.queryString; } } exports.QueryCompiler = QueryCompiler; class MySQLQueryCompiler extends QueryCompiler { constructor(query) { super("MySQL", query, CompilationContext); // Customize any other instance properties here, e.g. this.delimiter = "GO"; // For SQL Server (T-SQL) } } exports.MySQLQueryCompiler = MySQLQueryCompiler; //# sourceMappingURL=queryCompiler.js.map