ddl-manager
Version:
store postgres procedures and triggers in files
179 lines • 6.65 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helperColumnName = exports.getOrderByColumnsRefs = exports.Cache = void 0;
const expression_1 = require("./expression");
const SelectColumn_1 = require("./SelectColumn");
const findDependencies_1 = require("../cache/processor/findDependencies");
const lodash_1 = require("lodash");
class Cache {
constructor(name, forTable, select, withoutTriggers = [], withoutInserts = [], indexes = []) {
this.name = name;
this.for = forTable;
this.select = select;
this.withoutTriggers = withoutTriggers;
this.withoutInserts = withoutInserts;
this.indexes = indexes;
}
// @see also jsonColumnName
static generateJsonHelperColumnName(cacheName) {
return `__${cacheName}_json__`;
}
getIsLastColumnName() {
const helperColumnName = [
"_",
this.name,
"for",
this.for.table.name
].join("_");
return helperColumnName;
}
createSelectForUpdate(aggFunctions) {
if (this.selectForUpdate) {
return this.selectForUpdate;
}
let { select } = this;
select = select.fixArraySearchForDifferentArrayTypes();
if (select.orderBy && this.hasArrayReference()) {
select = replaceOrderByLimitToArrayAgg(select);
select = addAggHelperColumns(this, select);
return select;
}
if (this.hasAgg(aggFunctions)) {
return addAggHelperColumns(this, select);
}
if (select.orderBy) {
return addOrderByHelperColumns(this, select);
}
this.selectForUpdate = select;
return select;
}
equal(otherCache) {
return (this.name === otherCache.name &&
this.for.equal(otherCache.for) &&
this.select.toString() === otherCache.select.toString() &&
this.withoutTriggers.join(",") === otherCache.withoutTriggers.join(",") &&
this.withoutInserts.join(",") === otherCache.withoutInserts.join(",") &&
this.indexes.join(",") === otherCache.indexes.join(","));
}
hasForeignTablesDeps() {
return this.select.from.length > 0;
}
getTargetTablesDepsColumns() {
return findDependencies_1.findDependenciesToCacheTable(this).columns;
}
getFromTable() {
return this.select.getFromTable().table;
}
getFromTableRef() {
return this.select.getFromTable();
}
// @see also isJsonHelperColumn
jsonColumnName() {
return Cache.generateJsonHelperColumnName(this.name);
}
getSourceRowJson(recordAlias) {
const from = this.select.getFromTable().getIdentifier();
const deps = this.getSourceJsonDeps();
const maxColumnsPerCall = 50;
const calls = [];
for (let i = 0, n = deps.length; i < n; i += maxColumnsPerCall) {
const depsPackage = deps.slice(i, i + maxColumnsPerCall);
calls.push(`jsonb_build_object(
${depsPackage.map(column => `'${column}', ${recordAlias || from}.${column}`)}
)`);
}
return calls.join(" || ");
}
getSourceJsonDeps() {
const deps = findDependencies_1.findDependenciesTo(this, this.select.getFromTable(), ["id"]);
return deps;
}
hasArrayReference() {
return this.select.hasArraySearchOperator();
}
hasAgg(aggFunctions) {
return this.select.hasAgg(aggFunctions);
}
getSignature() {
return `cache ${this.name} for ${this.for}`;
}
toString() {
return `
cache ${this.name} for ${this.for} (
${this.select}
)
${this.withoutTriggers.map(onTable => `without triggers on ${onTable}`).join(" ").trim()}
${this.withoutInserts.map(onTable => `without insert case on ${onTable}`).join(" ").trim()}
${this.indexes.join("\n")}
`;
}
}
exports.Cache = Cache;
function replaceOrderByLimitToArrayAgg(select) {
const orderBy = select.getDeterministicOrderBy();
return select.clone({
columns: select.columns.map(selectColumn => selectColumn.clone({
// building expression (like are order by/limit 1):
// (array_agg( source.column order by source.sort ))[1]
expression: new expression_1.Expression([
new expression_1.Expression([
new expression_1.FuncCall("array_agg", [
selectColumn.expression
], undefined, false, orderBy),
], true),
expression_1.Expression.unknown("[1]")
])
})),
orderBy: undefined,
limit: undefined
});
}
function addAggHelperColumns(cache, select) {
const fromRef = cache.select.getFromTable();
const from = fromRef.getIdentifier();
const rowJson = cache.getSourceRowJson();
const deps = cache.getSourceJsonDeps().map(column => new expression_1.ColumnReference(fromRef, column));
const depsMap = lodash_1.fromPairs(deps.map(column => [column.toString(), column]));
return select.clone({
columns: [
...select.columns,
new SelectColumn_1.SelectColumn({
name: cache.jsonColumnName(),
expression: new expression_1.Expression([
expression_1.Expression.unknown(`
('{' || string_agg(
'"' || ${from}.id::text || '":' || ${rowJson}::text,
','
) || '}')
`, depsMap),
expression_1.Expression.unknown("::"),
expression_1.Expression.unknown("jsonb")
])
})
]
});
}
function addOrderByHelperColumns(cache, select) {
const helperColumns = getOrderByColumnsRefs(select).map(columnRef => new SelectColumn_1.SelectColumn({
name: helperColumnName(cache, columnRef.name),
expression: new expression_1.Expression([
new expression_1.ColumnReference(select.getFromTable(), columnRef.name)
])
}));
return select.clone({
columns: [
...select.columns,
...helperColumns
]
});
}
function getOrderByColumnsRefs(select) {
const orderBy = select.getDeterministicOrderBy();
return orderBy.getColumnReferences();
}
exports.getOrderByColumnsRefs = getOrderByColumnsRefs;
function helperColumnName(cache, columnName) {
return `__${cache.name}_${columnName}`;
}
exports.helperColumnName = helperColumnName;
//# sourceMappingURL=Cache.js.map