ddl-manager
Version:
store postgres procedures and triggers in files
239 lines • 8.35 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Select = void 0;
const AbstractAstElement_1 = require("./AbstractAstElement");
const Expression_1 = require("./expression/Expression");
const From_1 = require("./From");
const SelectColumn_1 = require("./SelectColumn");
const TableReference_1 = require("../database/schema/TableReference");
const fixArraySearchForDifferentArrayTypes_1 = require("../cache/trigger-builder/condition/fixArraySearchForDifferentArrayTypes");
const expression_1 = require("./expression");
const Exists_1 = require("./expression/Exists");
const assert_1 = require("assert");
class Select extends AbstractAstElement_1.AbstractAstElement {
constructor(params = {
columns: [],
from: []
}) {
super();
Object.assign(this, params);
if (params.orderBy) {
this.orderBy = params.orderBy;
}
this.forUpdate = !!params.forUpdate;
}
static notExists(from, where, as) {
return new Select({
columns: [new SelectColumn_1.SelectColumn({
name: as,
expression: new Expression_1.Expression([
expression_1.UnknownExpressionElement.fromSql(`not`),
new Exists_1.Exists({
select: new Select({
columns: [],
from: [new From_1.From({ source: from })],
where
})
})
])
})],
from: []
});
}
addColumn(newColumn) {
const clone = this.clone({
columns: [
...this.columns.map(column => column.clone()),
newColumn
]
});
return clone;
}
addFrom(newFrom) {
const clone = this.clone({
from: [
...this.from.map(from => from.clone()),
newFrom
]
});
return clone;
}
addWhere(newWhere) {
const clone = this.clone({
where: newWhere
});
return clone;
}
addOrderBy(orderBy) {
const clone = this.clone({
orderBy
});
return clone;
}
setLimit(limit) {
const clone = this.clone({
limit
});
return clone;
}
clone(params = {}) {
const clone = new Select(Object.assign({ columns: this.columns.map(column => column.clone()), from: this.from.map(from => from.clone()), where: this.where ? this.where.clone() : undefined, orderBy: this.orderBy ? this.orderBy.clone() : undefined, limit: this.limit, forUpdate: "forUpdate" in params ? params.forUpdate : this.forUpdate }, params));
return clone;
}
hasArraySearchOperator() {
var _a;
return (_a = this.where) === null || _a === void 0 ? void 0 : _a.hasArraySearchOperator();
}
hasAgg(aggFunctions) {
return this.columns.some(column => column.getAggregations(aggFunctions).length > 0);
}
fixArraySearchForDifferentArrayTypes(fromTable) {
var _a;
if ((_a = this.where) === null || _a === void 0 ? void 0 : _a.hasArraySearchOperator()) {
return this.clone({
where: fixArraySearchForDifferentArrayTypes_1.fixArraySearchForDifferentArrayTypes(fromTable !== null && fromTable !== void 0 ? fromTable : this.getFromTable(), this.where)
});
}
return this;
}
findTableReference(filter) {
const outputTableRef = this.getAllTableReferences().find(tableRef => tableRef.matched(filter));
return outputTableRef;
}
replaceTable(replaceTable, toTable) {
return this.clone({
columns: this.columns.map(column => column.replaceTable(replaceTable, toTable)),
from: this.from.map(from => from.replaceTable(replaceTable, toTable)),
where: (this.where ?
this.where.replaceTable(replaceTable, toTable) :
undefined),
orderBy: (this.orderBy ?
this.orderBy.replaceTable(replaceTable, toTable) :
undefined),
});
}
equalSource(select) {
if (this.where && select.where) {
this.where.equal(select.where);
}
if (this.orderBy && select.orderBy) {
this.orderBy.equal(select.orderBy);
}
return (this.from.length === select.from.length &&
this.from.every((fromItem, i) => fromItem.equal(select.from[i]))
&&
equal(this.where, select.where)
&&
equal(this.orderBy, select.orderBy)
&&
this.limit === select.limit);
}
template(spaces) {
return [
spaces + "select",
...this.printColumns(spaces),
...this.printFrom(spaces),
...(this.where ? [
spaces + "where",
this.where.toSQL(spaces.plusOneLevel())
] : []),
...(this.orderBy ?
[this.orderBy.toSQL(spaces)] :
[]),
...(this.limit ? [
spaces + `limit ${this.limit}`
] : []),
...(this.forUpdate ? [
spaces + "for update" + (this.intoRow ? "" : ";")
] : []),
...(this.intoRow ? [
spaces + `into ${this.intoRow};`
] : [])
];
}
printColumns(spaces) {
if (this.columns.length === 0) {
return [];
}
const nextSpaces = spaces.plusOneLevel();
const output = this.columns[0].template(nextSpaces);
for (const column of this.columns.slice(1)) {
output[output.length - 1] = output[output.length - 1] + ",";
output.push(...column.template(nextSpaces));
}
return output;
}
printFrom(spaces) {
if (this.from.length === 0) {
return [];
}
const output = [
...this.from[0].template(spaces)
];
output[0] = `${spaces}from ${output[0].trim()}`;
for (const from of this.from.slice(1)) {
output.push(spaces + ",");
output.push(...from.template(spaces.plusOneLevel()));
}
return output;
}
getAllColumnReferences() {
const allReferences = [];
for (const column of this.columns) {
allReferences.push(...column.expression.getColumnReferences());
}
for (const fromItem of this.from) {
for (const join of fromItem.joins) {
allReferences.push(...join.on.getColumnReferences());
}
}
if (this.where) {
allReferences.push(...this.where.getColumnReferences());
}
if (this.orderBy) {
allReferences.push(...this.orderBy.getColumnReferences());
}
return allReferences;
}
getAllTableReferences() {
const allReferences = [];
for (const fromItem of this.from) {
if (fromItem.source instanceof TableReference_1.TableReference) {
allReferences.push(fromItem.source);
}
for (const join of fromItem.joins) {
if (join.table instanceof TableReference_1.TableReference) {
allReferences.push(join.table);
}
}
}
return allReferences;
}
getFromTableId() {
return this.getFromTable().table;
}
getFromTable() {
assert_1.strict.equal(this.from.length, 1, "expected only one from");
assert_1.strict.ok(this.from[0].source instanceof TableReference_1.TableReference, "expected from table");
return this.from[0].source;
}
getDeterministicOrderBy() {
const orderBy = this.orderBy;
if (!orderBy || orderBy.hasIdSort()) {
return orderBy;
}
const from = this.getFromTable();
return orderBy.addIdSort(from);
}
}
exports.Select = Select;
function equal(a, b) {
if (a && b) {
return a.equal(b);
}
if (!a && !b) {
return true;
}
return false;
}
//# sourceMappingURL=Select.js.map