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.

255 lines (254 loc) 10.9 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.getInnerObjetRuleToApply = exports.createColumnsFromInnerObject = exports.createColumnsFrom = exports.ColumnImpl = void 0; const ITableOrView_1 = require("../utils/ITableOrView"); const values_1 = require("../expressions/values"); const ValueSourceImpl_1 = require("./ValueSourceImpl"); const TypeAdapter_1 = require("../TypeAdapter"); const ProxyTypeAdapter_1 = require("./ProxyTypeAdapter"); const symbols_1 = require("../utils/symbols"); class ColumnImpl extends ValueSourceImpl_1.ValueSourceImpl { constructor(table, name, valueType, valueTypeName, typeAdapter) { super(valueType, valueTypeName, 'required', typeAdapter); this[_a] = true; this.__hasDefault = false; this.__isPrimaryKey = false; this.__isAutogeneratedPrimaryKey = false; this.__isComputed = false; this.__name = name; this.__tableOrView = table; } __toSql(sqlBuilder, params) { return sqlBuilder._appendColumnName(this.__asColumn(), params); } __toSqlForCondition(sqlBuilder, params) { return sqlBuilder._appendColumnNameForCondition(this.__asColumn(), params); } __asColumn() { return this; } __asOptionalColumn() { this.__optionalType = 'optional'; return this; } __asColumnWithDefaultValue() { this.__hasDefault = true; return this; } __asOptionalColumnWithDefaultValue() { this.__optionalType = 'optional'; this.__hasDefault = true; return this; } __asAutogeneratedPrimaryKey() { this.__hasDefault = true; this.__isPrimaryKey = true; this.__isAutogeneratedPrimaryKey = true; return this; } __asAutogeneratedPrimaryKeyBySequence(sequenceName) { this.__hasDefault = true; this.__isPrimaryKey = true; this.__isAutogeneratedPrimaryKey = true; this.__sequenceName = sequenceName; return this; } __asPrimaryKey() { this.__isPrimaryKey = true; return this; } __asComputedColumn() { this.__isComputed = true; return this; } __asOptionalComputedColumn() { this.__isComputed = true; this.__optionalType = 'optional'; return this; } __registerTableOrView(sqlBuilder, requiredTablesOrViews) { (0, ITableOrView_1.__getTableOrViewPrivate)(this.__tableOrView).__registerTableOrView(sqlBuilder, requiredTablesOrViews); } __registerRequiredColumn(_sqlBuilder, requiredColumns, onlyForTablesOrViews) { if (onlyForTablesOrViews.has(this.__tableOrView)) { requiredColumns.add(this); } } __getOldValues(sqlBuilder) { return (0, ITableOrView_1.__getTableOrViewPrivate)(this.__tableOrView).__getOldValues(sqlBuilder); } __getValuesForInsert(sqlBuilder) { return (0, ITableOrView_1.__getTableOrViewPrivate)(this.__tableOrView).__getValuesForInsert(sqlBuilder); } __isAllowed(sqlBuilder) { return (0, ITableOrView_1.__getTableOrViewPrivate)(this.__tableOrView).__isAllowed(sqlBuilder); } } exports.ColumnImpl = ColumnImpl; _a = symbols_1.isColumnObject; function createColumnsFrom(sqlBuilder, columns, target, table) { for (const property in columns) { const column = columns[property]; if ((0, values_1.isValueSource)(column)) { const columnPrivate = (0, values_1.__getValueSourcePrivate)(column); let valueType = columnPrivate.__valueType; let valueTypeName = columnPrivate.__valueTypeName; let typeAdapter = columnPrivate.__typeAdapter; if (typeAdapter instanceof TypeAdapter_1.CustomBooleanTypeAdapter) { // Avoid treat the column as a custom boolean typeAdapter = new ProxyTypeAdapter_1.ProxyTypeAdapter(typeAdapter); } const withColumn = new ColumnImpl(table, property, valueType, valueTypeName, typeAdapter); withColumn.__optionalType = columnPrivate.__optionalType; if (columnPrivate.__aggregatedArrayColumns) { withColumn.__aggregatedArrayColumns = columnPrivate.__aggregatedArrayColumns; withColumn.__aggregatedArrayMode = columnPrivate.__aggregatedArrayMode; } if (columnPrivate.__uuidString) { withColumn.__uuidString = columnPrivate.__uuidString; } target[property] = withColumn; } else { const newTarget = {}; createColumnsFromInnerObject(sqlBuilder, column, target, table, property + '.'); target[property] = newTarget; } } } exports.createColumnsFrom = createColumnsFrom; function createColumnsFromInnerObject(sqlBuilder, columns, target, table, prefix) { const rule = getInnerObjetRuleToApply(sqlBuilder, columns); for (const property in columns) { const column = columns[property]; if ((0, values_1.isValueSource)(column)) { const columnPrivate = (0, values_1.__getValueSourcePrivate)(column); let valueType = columnPrivate.__valueType; let valueTypeName = columnPrivate.__valueTypeName; let typeAdapter = columnPrivate.__typeAdapter; if (typeAdapter instanceof TypeAdapter_1.CustomBooleanTypeAdapter) { // Avoid treat the column as a custom boolean typeAdapter = new ProxyTypeAdapter_1.ProxyTypeAdapter(typeAdapter); } const withColumn = new ColumnImpl(table, prefix + property, valueType, valueTypeName, typeAdapter); let optionalType = columnPrivate.__optionalType; switch (rule) { case 1: // Rule 1, there is requiredInOptionalObject if (optionalType === 'originallyRequired') { optionalType = 'optional'; } break; case 2: // Rule 2: all from the same left join ignoring inner objects if (optionalType === 'originallyRequired') { optionalType = 'requiredInOptionalObject'; } break; case 3: // Rule 3: there is a required property if (optionalType !== 'required') { optionalType = 'optional'; } break; case 4: // Rule 4: the general rule if (optionalType !== 'required') { optionalType = 'optional'; } break; } withColumn.__optionalType = optionalType; if (columnPrivate.__aggregatedArrayColumns) { withColumn.__aggregatedArrayColumns = columnPrivate.__aggregatedArrayColumns; withColumn.__aggregatedArrayMode = columnPrivate.__aggregatedArrayMode; } if (columnPrivate.__uuidString) { withColumn.__uuidString = columnPrivate.__uuidString; } target[property] = withColumn; } else { const newTarget = {}; createColumnsFromInnerObject(sqlBuilder, column, target, table, prefix + property + '.'); target[property] = newTarget; } } } exports.createColumnsFromInnerObject = createColumnsFromInnerObject; function getInnerObjetRuleToApply(sqlBuilder, columns) { let containsRequired = false; let contaisOriginallyRequired = false; let innerObjectsAreRequired = true; for (const property in columns) { const column = columns[property]; if ((0, values_1.isValueSource)(column)) { const columnPrivate = (0, values_1.__getValueSourcePrivate)(column); const optionalType = columnPrivate.__optionalType; switch (optionalType) { case 'requiredInOptionalObject': return 1; // Rule 1, there is requiredInOptionalObject case 'required': containsRequired = true; break; case 'originallyRequired': contaisOriginallyRequired = true; break; default: //do nothing } } else { if (getInnerObjetRuleToApply(sqlBuilder, column) === 3) { // This is the only case where the inner object is required innerObjectsAreRequired = true; } } } if (contaisOriginallyRequired) { let firstRequiredTables = new Set(); let alwaysSameRequiredTablesSize = undefined; for (const property in columns) { const column = columns[property]; if (!(0, values_1.isValueSource)(column)) { // ignore inner objects continue; } const columnPrivate = (0, values_1.__getValueSourcePrivate)(column); if (alwaysSameRequiredTablesSize === undefined) { columnPrivate.__registerTableOrView(sqlBuilder, firstRequiredTables); alwaysSameRequiredTablesSize = true; } else if (alwaysSameRequiredTablesSize) { let valueSourceRequiredTables = new Set(); columnPrivate.__registerTableOrView(sqlBuilder, valueSourceRequiredTables); const initialSize = firstRequiredTables.size; if (initialSize !== valueSourceRequiredTables.size) { alwaysSameRequiredTablesSize = false; } else { valueSourceRequiredTables.forEach(table => { firstRequiredTables.add(table); }); if (initialSize !== firstRequiredTables.size) { alwaysSameRequiredTablesSize = false; } } } } // Evaluate rule 2: all from the same left join ignoring inner objects let onlyOuterJoin = true; firstRequiredTables.forEach(table => { if (!(0, ITableOrView_1.__getTableOrViewPrivate)(table).__forUseInLeftJoin) { onlyOuterJoin = false; } }); if (firstRequiredTables.size <= 0) { onlyOuterJoin = false; } if (alwaysSameRequiredTablesSize && onlyOuterJoin) { return 2; // Rule 2: all from the same left join ignoring inner objects } } if (containsRequired || innerObjectsAreRequired) { return 3; // Rule 3: there is a required property } return 4; // Rule 4: the general rule } exports.getInnerObjetRuleToApply = getInnerObjetRuleToApply;