@sequeljs/ast
Version:
A SQL AST manager for JavaScript
248 lines • 8.23 kB
JavaScript
"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