UNPKG

ts-sql-query

Version:

Type-safe SQL query builder like QueryDSL or JOOQ in Java or Linq in .Net for TypeScript with MariaDB, MySql, Oracle, PostgreSql, Sqlite and SqlServer support.

1,196 lines 56.5 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompoundSelectQueryBuilder = exports.SelectQueryBuilder = void 0; const SqlBuilder_1 = require("../sqlBuilders/SqlBuilder"); const ITableOrView_1 = require("../utils/ITableOrView"); const values_1 = require("../expressions/values"); const ITableOrView_2 = require("../utils/ITableOrView"); const values_2 = require("../expressions/values"); const chained_error_1 = require("chained-error"); const ValueSourceImpl_1 = require("../internal/ValueSourceImpl"); const attachSource_1 = require("../utils/attachSource"); const symbols_1 = require("../utils/symbols"); const values_3 = require("../expressions/values"); const WithViewImpl_1 = require("../internal/WithViewImpl"); const ColumnImpl_1 = require("../internal/ColumnImpl"); const View_1 = require("../View"); const ComposeSliptQueryBuilder_1 = require("./ComposeSliptQueryBuilder"); class AbstractSelect extends ComposeSliptQueryBuilder_1.ComposeSplitQueryBuilder { constructor(sqlBuilder) { super(sqlBuilder); this[_a] = true; this.__columns = {}; this.__withs = []; this.__oneColumn = false; // cache this.__query = ''; this.__params = []; } query() { this.__finishJoinHaving(); if (this.__query) { return this.__query; } try { this.__query = this.__sqlBuilder._buildSelect(this.__asSelectData(), this.__params); } catch (e) { throw new chained_error_1.default(e); } return this.__query; } params() { this.__finishJoinHaving(); if (!this.__query) { this.query(); } return this.__params; } executeSelectNoneOrOne() { this.query(); const source = new Error('Query executed at'); (0, ComposeSliptQueryBuilder_1.__setQueryMetadata)(source, this.__params, this.__customization); try { this.__sqlBuilder._resetUnique(); let result; if (this.__oneColumn) { result = this.__sqlBuilder._queryRunner.executeSelectOneColumnOneRow(this.__query, this.__params).then((value) => { const valueSource = this.__columns['result']; if (!(0, values_1.isValueSource)(valueSource)) { throw new Error('The result column must be a ValueSource'); } if (value === undefined) { return null; } return this.__transformValueFromDB(valueSource, value); }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } else { result = this.__sqlBuilder._queryRunner.executeSelectOneRow(this.__query, this.__params).then((row) => { if (row) { return this.__transformRow(row); } else { return null; } }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } return this.__applyCompositions(result, source); } catch (e) { throw new chained_error_1.default(e); } } executeSelectOne() { this.query(); const source = new Error('Query executed at'); (0, ComposeSliptQueryBuilder_1.__setQueryMetadata)(source, this.__params, this.__customization); try { this.__sqlBuilder._resetUnique(); let result; if (this.__oneColumn) { result = this.__sqlBuilder._queryRunner.executeSelectOneColumnOneRow(this.__query, this.__params).then((value) => { const valueSource = this.__columns['result']; if (!(0, values_1.isValueSource)(valueSource)) { throw new Error('The result column must be a ValueSource'); } if (value === undefined) { throw new Error('No result returned by the database'); } return this.__transformValueFromDB(valueSource, value); }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } else { result = this.__sqlBuilder._queryRunner.executeSelectOneRow(this.__query, this.__params).then((row) => { if (row) { return this.__transformRow(row); } else { throw new Error('No result returned by the database'); } }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } return this.__applyCompositions(result, source); } catch (e) { throw new chained_error_1.default(e); } } __executeSelectMany(source) { this.query(); (0, ComposeSliptQueryBuilder_1.__setQueryMetadata)(source, this.__params, this.__customization); try { this.__sqlBuilder._resetUnique(); let result; if (this.__oneColumn) { result = this.__sqlBuilder._queryRunner.executeSelectOneColumnManyRows(this.__query, this.__params).then((values) => { const valueSource = this.__columns['result']; if (!(0, values_1.isValueSource)(valueSource)) { throw new Error('The result column must be a ValueSource'); } return values.map((value) => { if (value === undefined) { value = null; } return this.__transformValueFromDB(valueSource, value); }); }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } else { result = this.__sqlBuilder._queryRunner.executeSelectManyRows(this.__query, this.__params).then((rows) => { return rows.map((row, index) => { return this.__transformRow(row, index); }); }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } return this.__applyCompositions(result, source); } catch (e) { throw new chained_error_1.default(e); } } executeSelectMany() { const source = new Error('Query executed at'); return this.__executeSelectMany(source); } __executeSelectCount(source) { try { this.__sqlBuilder._resetUnique(); const countAll = new ValueSourceImpl_1.AggregateFunctions0ValueSource('_countAll', 'int', 'int', 'required', undefined); const params = []; const query = this.__buildSelectCount(countAll, params); (0, ComposeSliptQueryBuilder_1.__setQueryMetadata)(source, params, this.__customization, true); return this.__sqlBuilder._queryRunner.executeSelectOneColumnOneRow(query, params).then((value) => { return this.__transformValueFromDB(countAll, value, undefined, undefined, true); }).catch((e) => { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); }); } catch (e) { throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source); } } executeSelectPage(extras) { const source = new Error('Query executed at'); if (extras && (extras.count !== undefined && extras.count !== null)) { if (extras.data) { return this.__sqlBuilder._queryRunner.createResolvedPromise({ ...extras, data: extras.data, count: extras.count }); } return this.__executeSelectMany(source).then((data) => { return { ...extras, data, count: extras.count }; }); } if (extras && extras.data) { return this.__executeSelectCount(source).then((count) => { return { ...extras, data: extras.data, count }; }); } const getDataFn = () => { return this.__executeSelectMany(source); }; const getCountFn = () => { return this.__executeSelectCount(source); }; return this.__sqlBuilder._queryRunner.executeCombined(getDataFn, getCountFn).then(([data, count]) => { return { ...extras, data, count }; }); } projectingOptionalValuesAsNullable() { this.__projectOptionalValuesAsNullable = true; return this; } orderBy(column, mode) { this.__finishJoinHaving(); this.__query = ''; if (typeof column === 'string' && !this.__getColumnFromColumnsObject(column)) { throw new Error('The column "' + column + '" is not part of the select clause'); } this.__addOrderBy(column, mode); return this; } __addOrderBy(column, mode) { if (!this.__orderBy) { this.__orderBy = []; } this.__orderBy.push({ expression: column, order: mode || null }); } orderByFromString(orderBy) { this.__finishJoinHaving(); this.__query = ''; const split = orderBy.trim().toLowerCase().replace(/\s+/g, ' ').split(/\s*,\s*/); for (let i = 0, length = split.length; i < length; i++) { const clause = split[i]; const separatorIndex = clause.indexOf(' '); let column; let ordering; if (separatorIndex < 0) { column = clause; ordering = null; } else { column = clause.substring(0, separatorIndex); ordering = clause.substring(separatorIndex + 1); } const realColumnName = this.__getColumnNameFromColumnsObjectLowerCase(column); if (!realColumnName) { throw new Error('The column "' + column + '" is not part of the select clause'); } if (ordering === 'asc') { this.__addOrderBy(realColumnName, 'asc'); } else if (ordering === 'desc') { this.__addOrderBy(realColumnName, 'desc'); } else if (ordering === 'asc nulls first') { this.__addOrderBy(realColumnName, 'asc nulls first'); } else if (ordering === 'desc nulls first') { this.__addOrderBy(realColumnName, 'desc nulls first'); } else if (ordering === 'asc nulls last') { this.__addOrderBy(realColumnName, 'asc nulls last'); } else if (ordering === 'desc nulls last') { this.__addOrderBy(realColumnName, 'desc nulls last'); } else if (ordering === 'insensitive') { this.__addOrderBy(realColumnName, 'insensitive'); } else if (ordering === 'asc insensitive') { this.__addOrderBy(realColumnName, 'asc insensitive'); } else if (ordering === 'desc insensitive') { this.__addOrderBy(realColumnName, 'desc insensitive'); } else if (ordering === 'asc nulls first insensitive') { this.__addOrderBy(realColumnName, 'asc nulls first insensitive'); } else if (ordering === 'desc nulls first insensitive') { this.__addOrderBy(realColumnName, 'desc nulls first insensitive'); } else if (ordering === 'asc nulls last insensitive') { this.__addOrderBy(realColumnName, 'asc nulls last insensitive'); } else if (ordering === 'desc nulls last insensitive') { this.__addOrderBy(realColumnName, 'desc nulls last insensitive'); } else if (!ordering) { this.__addOrderBy(realColumnName); } else { throw new Error('Unknow ordering clause "' + ordering + '" in the order by related to the column "' + column + '"'); } } return this; } orderByFromStringIfValue(orderBy) { if (this.__isValue(orderBy)) { return this.orderByFromString(orderBy); } else { this.__finishJoinHaving(); this.__query = ''; return this; } } orderingSiblingsOnly() { this.__finishJoinHaving(); this.__query = ''; this.__orderingSiblingsOnly = true; return this; } limit(limit) { this.__finishJoinHaving(); this.__query = ''; this.__limit = limit; (0, ITableOrView_2.__addWiths)(limit, this.__sqlBuilder, this.__withs); return this; } limitIfValue(limit) { if (this.__isValue(limit)) { return this.limit(limit); } else { this.__finishJoinHaving(); this.__query = ''; return this; } } offset(offset) { this.__finishJoinHaving(); this.__query = ''; this.__offset = offset; (0, ITableOrView_2.__addWiths)(offset, this.__sqlBuilder, this.__withs); return this; } offsetIfValue(offset) { if (this.__isValue(offset)) { return this.offset(offset); } else { this.__finishJoinHaving(); this.__query = ''; return this; } } __combineSubSelectUsing(select, result) { const selectPrivate = select; if (this.__subSelectUsing) { if (selectPrivate.__subSelectUsing) { result.__subSelectUsing = this.__subSelectUsing.concat(...selectPrivate.__subSelectUsing); } else { result.__subSelectUsing = this.__subSelectUsing.concat(); } } else if (selectPrivate.__subSelectUsing) { result.__subSelectUsing = selectPrivate.__subSelectUsing.concat(); } } union(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'union', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } unionAll(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'unionAll', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } intersect(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'intersect', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } intersectAll(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'intersectAll', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } except(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'except', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } exceptAll(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'exceptAll', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } minus(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'minus', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } minusAll(select) { const result = new CompoundSelectQueryBuilder(this.__sqlBuilder, this.__asSelectData(), 'minusAll', this.__compoundableAsSelectData(select)); this.__combineSubSelectUsing(select, result); return result; } ; __compoundableAsSelectData(select) { return select.__asSelectData(); } __addWiths(sqlBuilder, withs) { this.__finishJoinHaving(); const withViews = this.__withs; for (let i = 0, length = withViews.length; i < length; i++) { const withView = withViews[i]; (0, ITableOrView_2.__getTableOrViewPrivate)(withView).__addWiths(sqlBuilder, withs); } } __registerTableOrView(sqlBuilder, requiredTablesOrViews) { const subSelectUsing = this.__subSelectUsing; if (!subSelectUsing) { return; } for (let i = 0, length = subSelectUsing.length; i < length; i++) { const tableOrView = subSelectUsing[i]; (0, ITableOrView_2.__getTableOrViewPrivate)(tableOrView).__registerTableOrView(sqlBuilder, requiredTablesOrViews); } } __registerRequiredColumn(sqlBuilder, requiredColumns, onlyForTablesOrViews) { const subSelectUsing = this.__subSelectUsing; if (!subSelectUsing) { return; } const newOnly = new Set(); for (let i = 0, length = subSelectUsing.length; i < length; i++) { const tableOrView = subSelectUsing[i]; if (onlyForTablesOrViews.has(tableOrView)) { newOnly.add(tableOrView); } } if (newOnly.size <= 0) { return; } this.__registerRequiredColumnOfColmns(this.__columns, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(this.__orderBy, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(this.__limit, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(this.__offset, sqlBuilder, requiredColumns, newOnly); const customization = this.__customization; if (customization) { (0, ITableOrView_1.__registerRequiredColumn)(customization.beforeWithQuery, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.beforeQuery, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.afterSelectKeyword, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.beforeColumns, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.customWindow, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.beforeOrderByItems, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.afterOrderByItems, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.afterQuery, sqlBuilder, requiredColumns, newOnly); (0, ITableOrView_1.__registerRequiredColumn)(customization.afterWithQuery, sqlBuilder, requiredColumns, newOnly); } this.__registerRequiredColumnInSelect(sqlBuilder, requiredColumns, newOnly); } __getOldValues(sqlBuilder) { const subSelectUsing = this.__subSelectUsing; if (!subSelectUsing) { return undefined; } for (let i = 0, length = subSelectUsing.length; i < length; i++) { const tableOrView = subSelectUsing[i]; const result = (0, ITableOrView_2.__getTableOrViewPrivate)(tableOrView).__getOldValues(sqlBuilder); if (result) { return result; } } return undefined; } __getValuesForInsert(sqlBuilder) { const subSelectUsing = this.__subSelectUsing; if (!subSelectUsing) { return undefined; } for (let i = 0, length = subSelectUsing.length; i < length; i++) { const tableOrView = subSelectUsing[i]; const result = (0, ITableOrView_2.__getTableOrViewPrivate)(tableOrView).__getValuesForInsert(sqlBuilder); if (result) { return result; } } return undefined; } __toSql(sqlBuilder, params) { this.__finishJoinHaving(); return sqlBuilder._buildInlineSelect(this.__asSelectData(), params); } __toSqlForCondition(sqlBuilder, params) { this.__finishJoinHaving(); return sqlBuilder._buildInlineSelect(this.__asSelectData(), params); } forUseInQueryAs(as) { const recursiveView = this.__recursiveView; if (recursiveView) { recursiveView.__name = as; this.__recursiveInternalView.__name = as; this.__recursiveView = undefined; this.__recursiveInternalView = undefined; this.__recursiveSelect = undefined; return recursiveView; } return new WithViewImpl_1.WithViewImpl(this.__sqlBuilder, as, this.__asSelectData()); } forUseAsInlineQueryValue() { return new ValueSourceImpl_1.InlineSelectValueSource(this.__asSelectData(), !!this.__requiredResult); } forUseAsInlineAggregatedArrayValue() { const selectData = this.__asSelectData(); selectData.__asInlineAggregatedArrayValue = true; let aggregatedArrayColumns; if (this.__oneColumn) { aggregatedArrayColumns = this.__columns['result']; } else { aggregatedArrayColumns = this.__columns; } const result = new ValueSourceImpl_1.AggregateSelectValueSource(selectData, aggregatedArrayColumns, 'ResultObject', 'required'); if (this.__projectOptionalValuesAsNullable) { return result.projectingOptionalValuesAsNullable(); } else { return result; } } __buildRecursive(fn, unionAll) { const sqlBuilder = this.__sqlBuilder; const name = 'recursive_select_' + sqlBuilder._generateUnique(); const recursiveInternalView = new WithViewImpl_1.WithViewImpl(this.__sqlBuilder, name, this); recursiveInternalView.__ignoreWith = true; let recursiveInternalSelect; if (unionAll) { recursiveInternalSelect = this.unionAll(fn(recursiveInternalView)); } else { recursiveInternalSelect = this.union(fn(recursiveInternalView)); } const recursiveView = new WithViewImpl_1.WithViewImpl(this.__sqlBuilder, name, recursiveInternalSelect); recursiveView.__recursive = true; const recursiveSelect = new SelectQueryBuilder(this.__sqlBuilder, [recursiveView], false); const columns = recursiveSelect.__columns; const currentColumns = this.__columns; for (let columnName in currentColumns) { columns[columnName] = recursiveView[columnName]; } recursiveSelect.__subSelectUsing = this.__subSelectUsing; recursiveSelect.__projectOptionalValuesAsNullable = this.__projectOptionalValuesAsNullable; this.__recursiveInternalView = recursiveInternalView; this.__recursiveView = recursiveView; this.__recursiveSelect = recursiveSelect.__asSelectData(); // __asSelectData is important here to detect the required tables } recursiveUnion(fn) { this.__buildRecursive(fn, false); return this; } recursiveUnionAll(fn) { this.__buildRecursive(fn, true); return this; } __buildRecursiveFn(fn) { return (view) => { const current = this; const result = new SelectQueryBuilder(this.__sqlBuilder, current.__tablesOrViews, false); result.__columns = current.__columns; result.__withs = current.__withs.concat(); result.__joins = current.__joins.concat(); result.__subSelectUsing = this.__subSelectUsing; result.join(view).on(fn(view)).__finishJoinHaving(); result.__projectOptionalValuesAsNullable = this.__projectOptionalValuesAsNullable; return result; }; } recursiveUnionOn(fn) { this.__buildRecursive(this.__buildRecursiveFn(fn), false); return this; } recursiveUnionAllOn(fn) { this.__buildRecursive(this.__buildRecursiveFn(fn), true); return this; } customizeQuery(customization) { this.__customization = customization; (0, ITableOrView_2.__addWiths)(customization.beforeWithQuery, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.beforeQuery, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.afterSelectKeyword, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.beforeColumns, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.customWindow, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.beforeOrderByItems, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.afterOrderByItems, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.afterQuery, this.__sqlBuilder, this.__withs); (0, ITableOrView_2.__addWiths)(customization.afterWithQuery, this.__sqlBuilder, this.__withs); return this; } } _a = symbols_1.isSelectQueryObject; class SelectQueryBuilder extends AbstractSelect { constructor(sqlBuilder, tables, distinct) { super(sqlBuilder); this.__type = 'plain'; this.__joins = []; this.__groupBy = []; this.__inHaving = false; this.__hasOptionalJoin = false; this.__tablesOrViews = tables; this.__distinct = distinct; for (let i = 0, length = tables.length; i < length; i++) { const table = tables[i]; (0, ITableOrView_2.__getTableOrViewPrivate)(table).__addWiths(sqlBuilder, this.__withs); } } __registerRequiredColumnInSelect(sqlBuilder, requiredColumns, onlyForTablesOrViews) { const tablesOrViews = this.__tablesOrViews; for (let i = 0, length = tablesOrViews.length; i < length; i++) { (0, ITableOrView_1.__registerRequiredColumn)(tablesOrViews[i], sqlBuilder, requiredColumns, onlyForTablesOrViews); } const joins = this.__joins; for (let i = 0, length = joins.length; i < length; i++) { const join = joins[i]; (0, ITableOrView_1.__registerRequiredColumn)(join.__tableOrView, sqlBuilder, requiredColumns, onlyForTablesOrViews); (0, ITableOrView_1.__registerRequiredColumn)(join.__on, sqlBuilder, requiredColumns, onlyForTablesOrViews); } (0, ITableOrView_1.__registerRequiredColumn)(this.__where, sqlBuilder, requiredColumns, onlyForTablesOrViews); (0, ITableOrView_1.__registerRequiredColumn)(this.__having, sqlBuilder, requiredColumns, onlyForTablesOrViews); const groupBy = this.__groupBy; for (let i = 0, length = groupBy.length; i < length; i++) { (0, ITableOrView_1.__registerRequiredColumn)(groupBy[i], sqlBuilder, requiredColumns, onlyForTablesOrViews); } } __buildSelectCount(countAll, params) { const recursiveSelect = this.__recursiveSelect; if (recursiveSelect) { return recursiveSelect.__buildSelectCount(countAll, params); } if (this.__distinct || this.__groupBy.length > 0) { const data = { ...this.__asSelectData() }; // Ensure any missing initialization and create a copy of the data delete data.__limit; delete data.__offset; const withView = new WithViewImpl_1.WithViewImpl(this.__sqlBuilder, 'result_for_count', data); const withs = []; withView.__addWiths(this.__sqlBuilder, withs); const selectCountData = { [symbols_1.isSelectQueryObject]: true, __type: 'plain', __distinct: false, __columns: { '': countAll }, __oneColumn: true, __tablesOrViews: [withView], __joins: [], __where: undefined, __groupBy: [], __withs: withs, __subSelectUsing: this.__subSelectUsing, __requiredTablesOrViews: this.__requiredTablesOrViews }; return this.__sqlBuilder._buildSelect(selectCountData, params); } this.__asSelectData(); // Ensure any missing initialization const selectCountData = { [symbols_1.isSelectQueryObject]: true, __type: 'plain', __distinct: false, __columns: { '': countAll }, __oneColumn: true, __tablesOrViews: this.__tablesOrViews, __joins: this.__joins, __where: this.__where, __groupBy: [], __withs: this.__withs, __subSelectUsing: this.__subSelectUsing, __requiredTablesOrViews: this.__requiredTablesOrViews }; return this.__sqlBuilder._buildSelect(selectCountData, params); } select(columns) { this.__finishJoinHaving(); this.__query = ''; this.__columns = columns; this.__registerTableOrViewWithOfColumns(columns, this.__withs); return this; } selectOneColumn(column) { this.__finishJoinHaving(); this.__query = ''; this.__oneColumn = true; this.__columns = { 'result': column }; (0, values_2.__getValueSourcePrivate)(column).__addWiths(this.__sqlBuilder, this.__withs); return this; } selectCountAll() { this.__requiredResult = true; const column = new ValueSourceImpl_1.AggregateFunctions0ValueSource('_countAll', 'int', 'int', 'required', undefined); this.__finishJoinHaving(); this.__query = ''; this.__oneColumn = true; this.__columns = { 'result': column }; (0, values_2.__getValueSourcePrivate)(column).__addWiths(this.__sqlBuilder, this.__withs); return this; } from(table) { this.__finishJoinHaving(); this.__query = ''; this.__tablesOrViews.push(table); (0, ITableOrView_2.__getTableOrViewPrivate)(table).__addWiths(this.__sqlBuilder, this.__withs); return this; } join(table) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'join', __tableOrView: table }; (0, ITableOrView_2.__getTableOrViewPrivate)(table).__addWiths(this.__sqlBuilder, this.__withs); return this; } innerJoin(table) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'innerJoin', __tableOrView: table }; (0, ITableOrView_2.__getTableOrViewPrivate)(table).__addWiths(this.__sqlBuilder, this.__withs); return this; } leftJoin(source) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'leftJoin', __tableOrView: source }; (0, ITableOrView_2.__getTableOrViewPrivate)(source).__addWiths(this.__sqlBuilder, this.__withs); return this; } leftOuterJoin(source) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'leftOuterJoin', __tableOrView: source }; (0, ITableOrView_2.__getTableOrViewPrivate)(source).__addWiths(this.__sqlBuilder, this.__withs); return this; } optionalJoin(table) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'join', __tableOrView: table, __optional: true }; this.__hasOptionalJoin = true; (0, ITableOrView_2.__getTableOrViewPrivate)(table).__addWiths(this.__sqlBuilder, this.__withs); return this; } optionalInnerJoin(table) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'innerJoin', __tableOrView: table, __optional: true }; this.__hasOptionalJoin = true; (0, ITableOrView_2.__getTableOrViewPrivate)(table).__addWiths(this.__sqlBuilder, this.__withs); return this; } optionalLeftJoin(source) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'leftJoin', __tableOrView: source, __optional: true }; this.__hasOptionalJoin = true; (0, ITableOrView_2.__getTableOrViewPrivate)(source).__addWiths(this.__sqlBuilder, this.__withs); return this; } optionalLeftOuterJoin(source) { this.__finishJoinHaving(); this.__query = ''; if (this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin = { __joinType: 'leftOuterJoin', __tableOrView: source, __optional: true }; this.__hasOptionalJoin = true; (0, ITableOrView_2.__getTableOrViewPrivate)(source).__addWiths(this.__sqlBuilder, this.__withs); return this; } dynamicOn() { this.__query = ''; return this; } on(condition) { this.__query = ''; if (!this.__lastJoin) { throw new Error('Illegal state'); } this.__lastJoin.__on = (0, values_3.asAlwaysIfValueSource)(condition); (0, values_2.__getValueSourcePrivate)(condition).__addWiths(this.__sqlBuilder, this.__withs); return this; } __finishJoinHaving() { if (this.__lastJoin) { this.__joins.push(this.__lastJoin); this.__lastJoin = undefined; } this.__inHaving = false; } dynamicWhere() { this.__finishJoinHaving(); this.__query = ''; return this; } where(condition) { this.__finishJoinHaving(); this.__query = ''; if (this.__where) { throw new Error('Illegal state'); } this.__where = (0, values_3.asAlwaysIfValueSource)(condition); (0, values_2.__getValueSourcePrivate)(condition).__addWiths(this.__sqlBuilder, this.__withs); return this; } and(condition) { this.__query = ''; (0, values_2.__getValueSourcePrivate)(condition).__addWiths(this.__sqlBuilder, this.__withs); if (this.__lastJoin) { if (this.__lastJoin.__on) { this.__lastJoin.__on = this.__lastJoin.__on.and((0, values_3.asAlwaysIfValueSource)(condition)); } else { this.__lastJoin.__on = (0, values_3.asAlwaysIfValueSource)(condition); } return this; } if (this.__inHaving) { if (this.__having) { this.__having = this.__having.and((0, values_3.asAlwaysIfValueSource)(condition)); } else { this.__having = (0, values_3.asAlwaysIfValueSource)(condition); } return this; } if (this.__where) { this.__where = this.__where.and((0, values_3.asAlwaysIfValueSource)(condition)); } else { this.__where = (0, values_3.asAlwaysIfValueSource)(condition); } return this; } or(condition) { this.__query = ''; (0, values_2.__getValueSourcePrivate)(condition).__addWiths(this.__sqlBuilder, this.__withs); if (this.__lastJoin) { if (this.__lastJoin.__on) { this.__lastJoin.__on = this.__lastJoin.__on.or((0, values_3.asAlwaysIfValueSource)(condition)); } else { this.__lastJoin.__on = (0, values_3.asAlwaysIfValueSource)(condition); } return this; } if (this.__inHaving) { if (this.__having) { this.__having = this.__having.or((0, values_3.asAlwaysIfValueSource)(condition)); } else { this.__having = (0, values_3.asAlwaysIfValueSource)(condition); } return this; } if (this.__where) { this.__where = this.__where.or((0, values_3.asAlwaysIfValueSource)(condition)); } else { this.__where = (0, values_3.asAlwaysIfValueSource)(condition); } return this; } dynamicHaving() { this.__finishJoinHaving(); this.__query = ''; this.__inHaving = true; return this; } having(condition) { this.__finishJoinHaving(); this.__query = ''; this.__inHaving = true; if (this.__having) { throw new Error('Illegal state'); } this.__having = (0, values_3.asAlwaysIfValueSource)(condition); (0, values_2.__getValueSourcePrivate)(condition).__addWiths(this.__sqlBuilder, this.__withs); return this; } groupBy(...columns) { this.__finishJoinHaving(); this.__query = ''; for (let i = 0, length = columns.length; i < length; i++) { const column = columns[i]; if ((0, values_1.isValueSource)(column)) { this.__groupBy.push(column); (0, ITableOrView_2.__addWiths)(column, this.__sqlBuilder, this.__withs); } else { const valueSource = this.__getColumnFromColumnsObject(column); if (!valueSource) { throw new Error('The column "' + column + '" is not part of the select clause'); } this.__groupBy.push(valueSource); } } return this; } startWith(condition) { this.__finishJoinHaving(); this.__query = ''; if (this.__startWith) { throw new Error('Illegal state'); } this.__startWith = (0, values_3.asAlwaysIfValueSource)(condition); (0, values_2.__getValueSourcePrivate)(condition).__addWiths(this.__sqlBuilder, this.__withs); return this; } connectBy(condition) { this.__finishJoinHaving(); this.__query = ''; if (this.__connectBy) { throw new Error('Illegal state'); } function prior(column) { return column.__prior(); } const connectBy = (0, values_3.asAlwaysIfValueSource)(condition(prior)); this.__connectBy = connectBy; (0, values_2.__getValueSourcePrivate)(connectBy).__addWiths(this.__sqlBuilder, this.__withs); return this; } connectByNoCycle(condition) { this.__finishJoinHaving(); this.__query = ''; if (this.__connectBy) { throw new Error('Illegal state'); } function prior(column) { return column.__prior(); } const connectBy = (0, values_3.asAlwaysIfValueSource)(condition(prior)); this.__connectBy = connectBy; this.__connectByNoCycle = true; (0, values_2.__getValueSourcePrivate)(connectBy).__addWiths(this.__sqlBuilder, this.__withs); return this; } __asSelectData() { const recursiveSelect = this.__recursiveSelect; if (recursiveSelect) { return recursiveSelect; } if (this.__hasOptionalJoin && !this.__requiredTablesOrViews) { this.__requiredTablesOrViews = this.__generateRequiredTableOrView(); } return this; } __generateRequiredTableOrView() { const requiredTableOrView = new Set(); this.__registerTableOrViewOfColumns(this.__columns, requiredTableOrView); const where = this.__where; if (where) { (0, values_2.__getValueSourcePrivate)(where).__registerTableOrView(this.__sqlBuilder, requiredTableOrView); } const groupBy = this.__groupBy; for (let i = 0, lenght = groupBy.length; i < lenght; i++) { const value = groupBy[i]; (0, values_2.__getValueSourcePrivate)(value).__registerTableOrView(this.__sqlBuilder, requiredTableOrView); } const having = this.__having; if (having) { (0, values_2.__getValueSourcePrivate)(having).__registerTableOrView(this.__sqlBuilder, requiredTableOrView); } const joins = this.__joins; for (let i = 0, lenght = groupBy.length; i < lenght; i++) { const join = joins[i]; const on = join.__on; if (!join.__optional && on) { (0, values_2.__getValueSourcePrivate)(on).__registerTableOrView(this.__sqlBuilder, requiredTableOrView); } } const customization = this.__customization; if (customization) { (0, ITableOrView_1.__registerTableOrView)(customization.beforeWithQuery, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.beforeQuery, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.afterSelectKeyword, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.beforeColumns, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.customWindow, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.beforeOrderByItems, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.afterOrderByItems, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.afterQuery, this.__sqlBuilder, requiredTableOrView); (0, ITableOrView_1.__registerTableOrView)(customization.afterWithQuery, this.__sqlBuilder, requiredTableOrView); } let registeredCount = requiredTableOrView.size; let updatedCount = requiredTableOrView.size; let whileItearionCount = 0; do { if (whileItearionCount > 1000) { throw new Error('Unable to discover all optional joins'); } registeredCount = updatedCount; for (let i = 0, lenght = joins.length; i < lenght; i++) { const join = joins[i]; const on = join.__on; if (join.__optional && on && requiredTableOrView.has(join.__tableOrView)) { (0, values_2.__getValueSourcePrivate)(on).__registerTableOrView(this.__sqlBuilder, requiredTableOrView); } } updatedCount = requiredTableOrView.size; whileItearionCount++; } while (registeredCount !== updatedCount); return requiredTableOrView; } __getOldValues(sqlBuilder) { let result = super.__getOldValues(this.__sqlBuilder); if (result) { return result; } const tablesOrViews = this.__tablesOrViews; for (let i = 0, length = tablesOrViews.length; i < length; i++) { const tableOrView = tablesOrViews[i]; result = (0, ITableOrView_2.__getTableOrViewPrivate)(tableOrView).__getOldValues(sqlBuilder); if (result) { return result; } } return undefined; } __getValuesForInsert(sqlBuilder) { let result = super.__getValuesForInsert(sqlBuilder); if (result) { return result; } const tablesOrViews = this.__tablesOrViews; for (let i = 0, length = tablesOrViews.length; i < length; i++) { const tableOrView = tablesOrViews[i]; result = (0, ITableOrView_2.__getTableOrViewPrivate)(tableOrView).__getValuesForInsert(sqlBuilder); if (result) { return result; } } return undefined; } __isAllowed(sqlBuilder) { let result; const subSelectUsing = this.__subSelectUsing; if (subSelectUsing) { for (let i = 0, length = subSelectUsing.length; i < length; i++) { result = (0, ITableOrView_2.__getTableOrViewPrivate)(subSelectUsing[i]).__isAllowed(sqlBuilder); if (!result) { return false; } } } const tablesOrViews = this.__tablesOrViews; if (tablesOrViews) { for (let i = 0, length = tablesOrViews.length; i < length; i++) { result = (0, ITableOrView_2.__getTableOrViewPrivate)(tablesOrViews[i]).__isAllowed(sqlBuilder); if (!result) { return false; } } } const joins = this.__joins; if (joins) { for (let i = 0, length = joins.length; i < length; i++) { const join = joins[i]; result = (0, ITableOrView_2.__getTableOrViewPrivate)(join.__tableOrView).__isAllowed(sqlBuilder); if (!result) { return false; } if (join.__on) { result = (0, values_2.__getValueSourcePrivate)(join.__on).__isAllowed(sqlBuilder); if (!result) { return false; } } } } if (this.__where) { result = (0, values_2.__getValueSourcePrivate)(this.__where).__isAllowed(sqlBuilder); if (!result) { return false; } } if (this.__having) { result = (0, values_2.__getValueSourcePrivate)(this.__having).__isAllowed(sqlBuilder); if (!result) { return false; } } const groupBy = this.__groupBy; if (groupBy) { for (let i = 0, length = groupBy.length; i < length; i++) { result = (0, values_2.__getValueSourcePrivate)(groupBy[i]).__isAllowed(sqlBuilder); if (!result) { return false; } } } if (this.__columns) { result = (0, SqlBuilder_1.isAllowedQueryColumns)(this.__columns, sqlBuilder); if (!result) { return false; } } result = (0, ITableOrView_1.__isAllowed)(this.__limit, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__offset, sqlBuilder); if (!result) { return false; } if (this.__customization) { result = (0, ITableOrView_1.__isAllowed)(this.__customization.beforeWithQuery, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.beforeQuery, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.afterSelectKeyword, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.beforeColumns, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.customWindow, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.beforeOrderByItems, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.afterOrderByItems, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.afterQuery, sqlBuilder); if (!result) { return false; } result = (0, ITableOrView_1.__isAllowed)(this.__customization.afterWithQuery, sqlBuilder); if (!result) { return false; } } return true; } } exports.SelectQueryBuilder = SelectQueryBuilder; class CompoundSelectQueryBuilder extends AbstractSele