UNPKG

@sequeljs/ast

Version:

A SQL AST manager for JavaScript

248 lines 8.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const SQLString_1 = require("../collectors/SQLString"); const EmptyJoinError_1 = require("../errors/EmptyJoinError"); const EngineNotSetError_1 = require("../errors/EngineNotSetError"); const VisitorNotSetError_1 = require("../errors/VisitorNotSetError"); const Comment_1 = require("../nodes/Comment"); const Distinct_1 = require("../nodes/Distinct"); const DistinctOn_1 = require("../nodes/DistinctOn"); const Except_1 = require("../nodes/Except"); const Exists_1 = require("../nodes/Exists"); const Group_1 = require("../nodes/Group"); const InnerJoin_1 = require("../nodes/InnerJoin"); const Intersect_1 = require("../nodes/Intersect"); const Join_1 = require("../nodes/Join"); const Lateral_1 = require("../nodes/Lateral"); const Limit_1 = require("../nodes/Limit"); const Lock_1 = require("../nodes/Lock"); const NamedWindow_1 = require("../nodes/NamedWindow"); const Offset_1 = require("../nodes/Offset"); const On_1 = require("../nodes/On"); const OptimizerHints_1 = require("../nodes/OptimizerHints"); const OuterJoin_1 = require("../nodes/OuterJoin"); const SQLLiteral_1 = require("../nodes/SQLLiteral"); const SelectStatement_1 = require("../nodes/SelectStatement"); const StringJoin_1 = require("../nodes/StringJoin"); const Union_1 = require("../nodes/Union"); const UnionAll_1 = require("../nodes/UnionAll"); const With_1 = require("../nodes/With"); const WithRecursive_1 = require("../nodes/WithRecursive"); const WhereSQL_1 = require("../visitors/WhereSQL"); const SequelAST_1 = require("../SequelAST"); const TreeManager_1 = require("./TreeManager"); class SelectManager extends TreeManager_1.default { get constraints() { return this.ctx.wheres; } get froms() { return this.ast.cores.map((c) => c.from).filter(Boolean); } get joinSources() { return this.ctx.source.right; } get limit() { return this.ast.limit && this.ast.limit.expr; } set limit(limit) { this.take(limit); } get locked() { return this.ast.lock; } get offset() { return this.ast.offset && this.ast.offset.expr; } set offset(amount) { this.skip(amount); } get orders() { return this.ast.orders; } get projections() { return this.ctx.projections; } set projections(projections) { this.ctx.projections = projections; } get source() { return this.ctx.source; } get taken() { return this.limit; } constructor(table = null) { super(new SelectStatement_1.default()); this.ctx = this.ast.cores[this.ast.cores.length - 1]; this.from(table); } collapse(exprs) { let expressions = exprs; expressions = expressions.filter(Boolean).map((expr) => { if (typeof expr === 'string') { return new SQLLiteral_1.default(expr); } return expr; }); if (expressions.length === 1) { return expressions[0]; } return this.createAnd(expressions); } as(other) { return this.createTableAlias(this.grouping(this.ast), new SQLLiteral_1.default(other)); } comment(...values) { this.ctx.comment = new Comment_1.default(values); return this; } distinct(value = true) { this.ctx.setQuantifier = value ? new Distinct_1.default() : null; return this; } distinctOn(value) { this.ctx.setQuantifier = value ? new DistinctOn_1.default(value) : null; return this; } except(other) { return new Except_1.default(this.ast, other.ast); } exists() { return new Exists_1.default(this.ast); } from(table) { if (table instanceof Join_1.default) { this.ctx.source.right.push(table); } else if (typeof table === 'string') { this.ctx.source.left = new SQLLiteral_1.default(table); } else { this.ctx.source.left = table; } return this; } group(...columns) { columns.forEach((column) => { let col = column; if (typeof col === 'string') { col = new SQLLiteral_1.default(col); } this.ctx.groups.push(new Group_1.default(col)); }); return this; } having(expr) { this.ctx.havings.push(expr); return this; } intersect(other) { return new Intersect_1.default(this.ast, other.ast); } join(relation, klass = InnerJoin_1.default) { if (relation === null) { return this; } let Klass = klass; let rel = relation; if (typeof rel === 'string' || rel instanceof SQLLiteral_1.default) { rel = new SQLLiteral_1.default(rel); if (rel.length <= 0) { throw new EmptyJoinError_1.default(); } Klass = StringJoin_1.default; } this.ctx.source.right.push(this.createJoin(rel, null, Klass)); return this; } lateral(tableName = null) { const base = tableName ? this.as(tableName) : this.ast; return new Lateral_1.default(base); } lock(locking = new SQLLiteral_1.default('FOR UPDATE')) { let lock = locking; if (lock === true) { lock = new SQLLiteral_1.default('FOR UPDATE'); } else if (typeof lock === 'string' || lock instanceof SQLLiteral_1.default) { lock = new SQLLiteral_1.default(lock); } this.ast.lock = new Lock_1.default(lock); return this; } minus(other) { return this.except(other); } on(...exprs) { this.ctx.source.right[this.ctx.source.right.length - 1].right = new On_1.default(this.collapse(exprs)); return this; } optimizerHints(...hints) { if (hints.length > 0) { this.ctx.optimizerHints = new OptimizerHints_1.default(hints); } return this; } order(...expr) { this.ast.orders.push(...expr.map((e) => (typeof e === 'string' ? new SQLLiteral_1.default(e) : e))); return this; } outerJoin(relation) { return this.join(relation, OuterJoin_1.default); } project(...projections) { this.ctx.projections.push(...projections.map((p) => typeof p === 'string' ? new SQLLiteral_1.default(p) : p)); return this; } skip(amount) { this.ast.offset = amount ? new Offset_1.default(amount) : null; return this; } take(limit) { if (limit) { this.ast.limit = new Limit_1.default(limit); } else { this.ast.limit = null; } return this; } union(other) { return new Union_1.default(this.ast, other.ast); } unionAll(other) { return new UnionAll_1.default(this.ast, other.ast); } whereSQL(engine = undefined) { let currentEngine = engine; if (typeof currentEngine === 'undefined') { currentEngine = SequelAST_1.default.engine; } if (!currentEngine) { throw new EngineNotSetError_1.default(); } if (this.ctx.wheres.length <= 0) { return null; } if (!currentEngine.connection.visitor) { throw new VisitorNotSetError_1.default(); } const visitor = new WhereSQL_1.default(currentEngine.connection.visitor, currentEngine.connection); return new SQLLiteral_1.default(visitor.accept(this.ctx, new SQLString_1.default()).value); } window(name) { const window = new NamedWindow_1.default(name); this.ctx.windows.push(window); return window; } with(...subqueries) { this.ast.with = new With_1.default(subqueries.reduce((acc, val) => acc.concat(val), [])); return this; } withRecursive(...subqueries) { this.ast.with = new WithRecursive_1.default(subqueries.reduce((acc, val) => acc.concat(val), [])); return this; } } exports.default = SelectManager; //# sourceMappingURL=SelectManager.js.map