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.

84 lines 3.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ast = require("./astsql"); class GenericQueryContext { constructor(currentNode) { this.currentNode = currentNode; } } class QueryVisitor { constructor(dialect, query, contextBuilder) { this.dialect = dialect; this.query = query; this.visitStarted = false; this._contextBuilder = contextBuilder || GenericQueryContext; if (this.dialect !== query.dialect) { throw Error("Mismatched query dialects."); } } // Derived classes must call this to start the visiting process visit() { if (this.visitStarted) { throw Error("Visit already initiated"); } this.visitStarted = true; let context = this.buildContext(); context = this.visitNode(context, this.query); return context; } // Dispatcher visitNode(context, node) { let previousParent = context.parentNode; let previousCurrent = context.currentNode; if (context.currentNode !== node) { context.parentNode = context.currentNode; context.currentNode = node; } context = this.doVisitNode(context, node); context.parentNode = previousParent; context.currentNode = previousCurrent; return context; } // Generic visit method. The visiting process falls back to this if it doesn't find a visit<NodeType> method // e.g. visitSelectStatement or visitQueryExpression visitGenericNode(context, node) { let anyNode = node; for (let p in anyNode) { if (this.shouldVisitNode(anyNode[p])) { context = this.visitNode(context, anyNode[p]); } else if (Array.isArray(anyNode[p])) { for (let elem of anyNode[p]) { if (this.shouldVisitNode(elem)) { context = this.visitNode(context, elem); } } } else { // throw Error("Unknown element requested to be visited"); // console.log(`WARNING: Skipping visiting unknown element ${p}`); } } return context; } // Context builder buildContext() { return new this._contextBuilder(this.query); } // Determines whether this object should be visited shouldVisitNode(node) { return node && (node instanceof ast.SqlAstNode || node.nodeType); } // Determines which visit method to call and calls here doVisitNode(context, node) { let nodeType = ast.SqlAstNode.getNodeType(node); let visitorMethod = "visit" + nodeType; let visitor = this; if (visitor[visitorMethod] && typeof visitor[visitorMethod] === "function") { return visitor[visitorMethod](context, node); } return this.visitGenericNode(context, node); } } exports.QueryVisitor = QueryVisitor; //# sourceMappingURL=queryVisitor.js.map