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
JavaScript
"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