UNPKG

database-builder

Version:

Library to assist in creating and maintaining SQL commands.

476 lines (475 loc) 20.8 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Query = void 0; var join_type_1 = require("../enums/join-type"); var query_readable_builder_1 = require("./query-readable-builder"); var query_builder_1 = require("./query-builder"); var utils_1 = require("../../core/utils"); var order_by_1 = require("../../core/enums/order-by"); var errors_1 = require("../../core/errors"); var column_ref_1 = require("../../core/column-ref"); var sql_base_1 = require("../sql-base"); var model_utils_1 = require("../../core/model-utils"); var key_utils_1 = require("../../core/key-utils"); var rxjs_1 = require("rxjs"); var safe_utils_1 = require("../../safe-utils"); var projections_utils_1 = require("../../core/projections-utils"); var Query = /** @class */ (function (_super) { __extends(Query, _super); function Query(_queryT, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.alias, alias = _c === void 0 ? void 0 : _c, getMapper = _b.getMapper, mapperTable = _b.mapperTable, _d = _b.database, database = _d === void 0 ? void 0 : _d, _e = _b.enableLog, enableLog = _e === void 0 ? true : _e; var _this = _super.call(this, { mapperTable: mapperTable, database: database, enableLog: enableLog }) || this; _this._queryT = _queryT; _this._getMapper = getMapper; _this._queryBuilder = new query_builder_1.QueryBuilder(_queryT, mapperTable, alias, getMapper); _this._queryReadableBuilder = new query_readable_builder_1.QueryReadableBuilder(utils_1.Utils.getMapperTable(_queryT, getMapper).newable, enableLog); return _this; } Query.prototype.clone = function () { return model_utils_1.ModelUtils.cloneDeep(this); }; Query.prototype.compile = function () { var compiled = this.builderCompiled(); var script = [compiled]; return script; }; Query.prototype.ignoreQueryFilters = function () { this._queryBuilder.ignoreQueryFilters(); return this; }; Query.prototype.setParamsQueryFilter = function (params) { this._queryBuilder.setParamsQueryFilter(params); return this; }; /** * @link QueryBuilder */ Query.prototype.alias = function () { return this._queryBuilder.alias; }; Query.prototype.ref = function (expression) { return this._queryBuilder.ref(expression); }; Query.prototype.from = function (query) { this._queryBuilder.from(query); return this; }; Query.prototype.union = function (query) { this._queryBuilder.union(query); return this; }; Query.prototype.unionAll = function (query) { this._queryBuilder.unionAll(query); return this; }; Query.prototype.join = function (queryTJoin, onWhere, join, type, alias, ignoreQueryFilters) { if (type === void 0) { type = join_type_1.JoinType.LEFT; } if (alias === void 0) { alias = void 0; } if (queryTJoin && queryTJoin._builder) { queryTJoin = queryTJoin._builder(); } this._queryBuilder.join(queryTJoin, onWhere, join, utils_1.Utils.getMapperTable(queryTJoin, this._getMapper).mapperTable, type, alias, ignoreQueryFilters); return this; }; Query.prototype.createWhere = function () { return this._queryBuilder.createWhere(); }; Query.prototype.where = function (where) { this._queryBuilder.where(where); return this; }; Query.prototype.whereExp = function (expression) { this._queryBuilder.whereExp(expression); return this; }; /** * @param projectionCallback */ Query.prototype.projection = function (projectionCallback) { this._queryBuilder.projection(projectionCallback); return this; }; Query.prototype.select = function () { var _a; var expressions = []; for (var _i = 0; _i < arguments.length; _i++) { expressions[_i] = arguments[_i]; } (_a = this._queryBuilder).select.apply(_a, expressions); return this; }; Query.prototype.limit = function (limit, offset) { this._queryBuilder.limit(limit, offset); return this; }; Query.prototype.orderBy = function (expression, order) { if (order === void 0) { order = order_by_1.OrderBy.ASC; } this._queryBuilder.orderBy(expression, order); return this; }; Query.prototype.asc = function (expression) { this._queryBuilder.asc(expression); return this; }; Query.prototype.desc = function (expression) { this._queryBuilder.desc(expression); return this; }; Query.prototype.groupBy = function (expression, havingCallback) { this._queryBuilder.groupBy(expression, havingCallback); return this; }; /** * Find projection by alias and result index (base 1...N+1) * @param projectionAlias alias to find the projection * @returns index (base 1...N+1) */ Query.prototype.getIndexProjection = function (projectionAlias) { return this._queryBuilder.getIndexProjection(projectionAlias); }; Query.prototype.toString = function () { return this.compile().map(function (x) { return x.query; }).join("\n"); }; /** * @link QueryReadableBuilder * @param cascade use cascade fetch in `hasMany` mapper (default = true) * @param mapper mapper table metadata * @param database database to execute query * @returns Array of `TType` */ Query.prototype.executeAndRead = function (_a) { var _this = this; var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database, _d = _b.mapperTable, mapperTable = _d === void 0 ? this.getMapper(void 0) : _d; return rxjs_1.Observable.create(function (observer) { _this._queryReadableBuilder.executeAndRead(cascade, _this, mapperTable, _this.getDatabase(database)) .subscribe(function (result) { _this.fetchModels(cascade, result, mapperTable) .subscribe(function (result) { observer.next(result); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * Execute query and parse to @type {TType} * @param cascade use cascade fetch in `hasMany` mapper (default = true) * @returns Array of @type {TType} */ Query.prototype.toList = function (_a) { var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database; return this.executeAndRead({ cascade: cascade, database: database }); }; /** * Execute query and parse to @type {TPrimitiveType} * @param cascade use cascade fetch in `hasMany` mapper (default = true) * @returns first or default @type {TPrimitiveType} */ Query.prototype.toSingle = function (_a) { var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database, where = _b.where, _default = _b._default; if (where) { this.where(where); } return this.limit(1) .toSingleList({ cascade: cascade, database: database }) .pipe((0, rxjs_1.map)(function (result) { return (result && result.length) ? result[0] : _default; })); }; /** * Execute query and parse to @type {TPrimitiveType} * @param cascade use cascade fetch in `hasMany` mapper (default = true) * @returns Array of @type {TPrimitiveType} */ Query.prototype.toSingleList = function (_a) { var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database; return this.mapper(function (r) { return r.single(); }, { cascade: cascade, database: database }); }; /** * Allow each parse items cursor * @param mapper callback mapper item * @param cascade use cascade fetch in `hasMany` mapper (default = true) * @returns Array of @type {T} */ Query.prototype.mapper = function (mapper, _a) { var _this = this; var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database; return new rxjs_1.Observable(function (observer) { _this.execute({ cascade: cascade, database: database }) .subscribe(function (cursors) { var mapperTable = _this.getMapper(void 0, false); if (cursors.length !== 1) { throw new errors_1.DatabaseBuilderError("\"mapper\" is not ready to solve multiple queries in one batch!"); } var resultMain = _this._queryReadableBuilder.mapper(cursors[0], mapperTable, mapper, _this._getMapper, _this._queryBuilder, utils_1.Utils.getMapperTable(_this._queryT, _this._getMapper).newable); _this.fetchModels(cascade, resultMain, mapperTable) .subscribe(function (result) { observer.next(result); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * Get count rows (count by key column) by query * @param where where for apply in query * @returns count items */ Query.prototype.count = function (_a) { var _this = this; var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database, where = _b.where; return new rxjs_1.Observable(function (observer) { var keyColumn = projections_utils_1.ProjectionsUtils.WILDCARD; if (_this.mapperTable && _this.mapperTable.keyColumns().length > 0) { keyColumn = _this.mapperTable.keyColumns()[0].column; } if (where) { _this.where(where); } _this .projection(function (p) { return p.clean().count(keyColumn, "count_id"); }) .mapper(function (r) { return r.get("count_id"); }, { cascade: cascade, database: database }) .subscribe(function (result) { observer.next(result[0]); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * Get first or default item by query * @param where where for apply in query * @param cascade use cascade fetch in `hasMany` mapper (default = true) * @param _default default value if not found any item * @returns first or default item by query */ Query.prototype.firstOrDefault = function (_a) { var _this = this; var _b = _a === void 0 ? {} : _a, _c = _b.cascade, cascade = _c === void 0 ? true : _c, database = _b.database, where = _b.where, _default = _b._default; return rxjs_1.Observable.create(function (observer) { if (where) { _this.where(where); } _this.limit(1) .toList({ cascade: cascade, database: database }) .subscribe(function (result) { observer.next((result && result.length) ? result[0] : _default); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * @deprecated use `.mapper` * Supported up to version 1.0.0 */ Query.prototype.read = function (cursor, newable, mapperTable) { return this._queryReadableBuilder.read(cursor, newable, mapperTable); }; /** * @deprecated use `.mapper` * Supported up to version 1.0.0 */ Query.prototype.toListParse = function (metadataParse) { var _this = this; return rxjs_1.Observable.create(function (observer) { _this.execute() .subscribe(function (cursor) { observer.next(_this.read(cursor, metadataParse.newable, metadataParse.mapperTable)); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * @deprecated use `.mapper` * Supported up to version 1.0.0 */ Query.prototype.toListTo = function (newable, mapperTable) { var _this = this; return rxjs_1.Observable.create(function (observer) { _this.execute() .subscribe(function (cursor) { observer.next(_this.read(cursor, newable, mapperTable)); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * @deprecated use `.mapper` * Supported up to version 1.0.0 */ Query.prototype.toCast = function () { var _this = this; return rxjs_1.Observable.create(function (observer) { _this.execute() .subscribe(function (cursors) { if (cursors.length !== 1) { throw new errors_1.DatabaseBuilderError("\"toCast\" is not ready to solve multiple queries in one batch!"); } observer.next(_this._queryReadableBuilder.toCast(cursors[0])); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * @deprecated use `.mapper` * Supported up to version 1.0.0 */ Query.prototype.map = function (mapper) { var _this = this; return rxjs_1.Observable.create(function (observer) { _this.execute() .subscribe(function (cursors) { if (cursors.length !== 1) { throw new errors_1.DatabaseBuilderError("\"map\" is not ready to solve multiple queries in one batch!"); } observer.next(_this._queryReadableBuilder.map(cursors[0], mapper)); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; /** * @hidden */ Query.prototype._builder = function () { return this._queryBuilder; }; Query.prototype.model = function () { return void 0; }; Query.prototype.builderCompiled = function () { return this._queryBuilder.compile(); }; Query.prototype.resolveDependencyByValue = function (dependency, value, index) { var insert = new query_builder_1.QueryBuilder(void 0, dependency, void 0); return insert.compile(); }; Query.prototype.resolveDependency = function (dependency) { return void 0; }; Query.prototype.checkDatabaseResult = function (promise) { return promise; }; Query.prototype.getMapper = function (mapperTable, throwNotFound) { if (throwNotFound === void 0) { throwNotFound = true; } var result = (mapperTable ? mapperTable : this.mapperTable); if (!result && throwNotFound) { throw new errors_1.DatabaseBuilderError("MapperTable not specified in query. Call 'executeAndRead'."); } return result; }; Query.prototype.fetchModels = function (cascade, models, mapperTable) { var _this = this; var promises = []; models.forEach(function (model) { promises.push(_this.fetchModel(cascade, model, mapperTable)); }); return (0, safe_utils_1.forkJoinSafe)(promises); }; Query.prototype.fetchModel = function (cascade, model, mapperTable) { var _this = this; return new rxjs_1.Observable(function (observer) { var promises = []; mapperTable.dependencies.forEach(function (dependency) { if (cascade) { var queryDependency_1 = new Query(void 0, { getMapper: _this._getMapper, mapperTable: dependency, database: _this.database, enableLog: _this.enableLog }); queryDependency_1.where(function (where) { var columnReference = dependency.getColumnNameByField(function (x) { return x.reference; }); where.equal(new column_ref_1.ColumnRef(columnReference), key_utils_1.KeyUtils.getKey(mapperTable, model)); }); promises.push(rxjs_1.Observable.create(function (observerInner) { queryDependency_1.toList() .subscribe(function (result) { var fieldDependency = mapperTable.columns.find(function (x) { return x.tableReference === dependency.tableName; }).fieldReference; observerInner.next({ field: fieldDependency, value: result.map(function (x) { return x.value; }) }); observerInner.complete(); }, function (err) { observerInner.error(err); observerInner.complete(); }); })); } else { promises.push(rxjs_1.Observable.create(function (observerInner) { var fieldDependency = mapperTable.columns.find(function (x) { return x.tableReference === dependency.tableName; }).fieldReference; observerInner.next({ field: fieldDependency, value: [] }); observerInner.complete(); })); } }); (0, safe_utils_1.forkJoinSafe)(promises) .subscribe(function (result) { result.forEach(function (r) { var fieldArraySplit = r.field.split("[?]."); if (fieldArraySplit.length === 1) { model_utils_1.ModelUtils.set(model, fieldArraySplit[0], r.value); } else { var values = r.value.map(function (value) { var item = {}; model_utils_1.ModelUtils.set(item, fieldArraySplit[1], value); return item; }); model_utils_1.ModelUtils.set(model, fieldArraySplit[0], values); } }); observer.next(model); observer.complete(); }, function (err) { observer.error(err); observer.complete(); }); }); }; Query.prototype.dependencies = function () { return this.mapperTable.dependencies; }; return Query; }(sql_base_1.SqlBase)); exports.Query = Query;