database-builder
Version:
Library to assist in creating and maintaining SQL commands.
476 lines (475 loc) • 20.8 kB
JavaScript
;
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;