UNPKG

ts-db-helper

Version:
362 lines 12.5 kB
import { DbColumn } from '../structure/db-column.model'; import { ModelResult } from './model-result.model'; import { DbTable } from '../structure/db-table.model'; import { QueryManager } from '../../managers/query-manager'; import { ModelManager } from '../../managers/model-manager'; import { DbQuery } from '../db-query.model'; import { ClauseGroup } from './clause-group.model'; /** * @public * @class QuerySelect * * @description * For design reasons this class should not be used directly. Use this class with {@link Select} function. * * @param T @extends DbHelperModel a model declared with table and column annotations * * @example * ```typescript * // select todos * Select(Todo).where({isDone: false}}).exec().subscribe((qr: QueryResult<Todo>) => { * // do something with the result... * }, (err) => { * // do something with the error... * }); * ``` * * @author Olivier Margarit * @since 0.1 */ var QuerySelect = /** @class */ (function () { /** * @public * @constructor should not be use directly, see class header * * @param {{new(): T}} model extention */ function QuerySelect(model) { this.model = model; /** * @private * @constant {string} type query type */ this.type = 'SELECT'; /** * @private * @property {Array<IJoin>} joins list of join for the query */ this.joins = []; /** * @private * @property size, the number of element returned by the select query */ this.size = 1000; /** * @private * @property {number} page the paginated number of the query select */ this.page = 0; /** * @private * @property {string} alias the query alias to prevent column collision */ this.alias = ''; } /** * @public * @method copy method to copy QuerySelect * * @return {QuerySelect<T>} the query select copy * * @since 0.2 */ QuerySelect.prototype.copy = function () { var q = (new QuerySelect(this.model)).where(this.whereClauses).join(this.joins).groupBy(this.grpBy).orderBy(this.ordrBy); if (this.proj) { q.projection(this.proj); } return q; }; /** * @public * @method projection customize the select column of the QueryResult * for performance optimization if needed. * * @param {Array<string>} proj the projection * * @return {QuerySelect<T>} this instance to chain query instructions */ QuerySelect.prototype.projection = function (proj) { this.proj = proj; return this; }; /** * @public * @method join add query join to query select * * @param {IJoin|Array<IJoin>} joinQuery join query or list of join queries * * @return {QuerySelect<T>} the instance itself to chain operation */ QuerySelect.prototype.join = function (joinQuery) { var joins; if (!Array.isArray(joinQuery)) { joins = [joinQuery]; } else { joins = joinQuery; } for (var _i = 0, joins_1 = joins; _i < joins_1.length; _i++) { var jq = joins_1[_i]; if (!jq) { continue; } if (!jq.alias) { jq.alias = 'join_' + this.joins.length; } this.joins.push(jq); } return this; }; /** * @public * @method where is the method to add clauses to the where statement of the query * see {@link Clause} or {@link ClauseGroup} or {@link CompositeClause} * * @param {Clause|Clause[]|CompositeClause|ClauseGroup|{[index: string]: any}} clauses where clauses * * @return {QuerySelect<T>} this instance to chain query instructions */ QuerySelect.prototype.where = function (clauses) { if (!this.whereClauses) { this.whereClauses = new ClauseGroup(); } this.whereClauses.add(clauses); return this; }; /** * @public * @method groupBy add group by instructions to the query * * @param {string} group string whith the column to group by * * @return {QuerySelect<T>} this instance to chain query instructions */ QuerySelect.prototype.groupBy = function (group) { this.grpBy = group; return this; }; /** * @public * @method orderBy add order by instructions to the query * * @param {string} order string whith the column to order by * * @return {QuerySelect<T>} this instance to chain query instructions */ QuerySelect.prototype.orderBy = function (order) { this.ordrBy = order; return this; }; /** * @public * @method setPage set the page result for pagination * * @param {number} page page number of the result * * @return {QuerySelect<T>} this instance to chain query instructions */ QuerySelect.prototype.setPage = function (page) { this.page = page; return this; }; /** * @public * @method setSize set the size of the page result for pagination * * @param {number} size page size number of the result * * @return {QuerySelect<T>} this instance to chain query instructions */ QuerySelect.prototype.setSize = function (size) { this.size = size; return this; }; QuerySelect.prototype.getSize = function () { return this.size; }; QuerySelect.prototype.getPage = function () { return this.page; }; /** * @public * @method getProjectedTable get virtual table representing the result table expected * * @return {DbTable} the virtual table */ QuerySelect.prototype.getProjectedTable = function () { var srcTable = ModelManager.getInstance().getModel(this.model); var table = new DbTable(); table.name = srcTable.name; table.modelName = srcTable.modelName; if (this.proj) { var projection = this.proj.slice(); for (var _i = 0, _a = srcTable.columnList; _i < _a.length; _i++) { var column = _a[_i]; var index = projection.indexOf(column.name); if (index >= 0) { table.columns[column.name] = column; table.fields[column.field] = column; table.columnList.push(column); projection.slice(index, 1); } } for (var _b = 0, projection_1 = projection; _b < projection_1.length; _b++) { var name = projection_1[_b]; var dbColumn = new DbColumn(name); dbColumn.field = name; table.columns[dbColumn.name] = dbColumn; table.columnList.push(dbColumn); table.fields[dbColumn.field] = dbColumn; } } else { for (var _c = 0, _d = srcTable.columnList; _c < _d.length; _c++) { var column = _d[_c]; table.columnList.push(column); table.columns[column.name] = column; table.fields[column.field] = column; } if (table.columns.hasOwnProperty('rowid')) { var rowidColumn = new DbColumn('rowid'); rowidColumn.indexed = true; rowidColumn.autoIncrement = true; rowidColumn.field = '$$rowid'; rowidColumn.type = 'integer'; table.columns[rowidColumn.name] = rowidColumn; table.columnList.push(rowidColumn); table.fields[rowidColumn.field] = rowidColumn; } } if (this.joins) { for (var _e = 0, _f = this.joins; _e < _f.length; _e++) { var joinQuery = _f[_e]; var joinTable = joinQuery.getProjectedTable(); for (var _g = 0, _h = joinTable.columnList; _g < _h.length; _g++) { var column = _h[_g]; var joinColumn = column.fromAlias(joinQuery.alias); table.columnList.push(joinColumn); table.columns[joinColumn.name] = joinColumn; table.fields[joinColumn.field] = joinColumn; } } } return table; }; /** * @private * @method getJoinProjection get the projection of join query * * @return {string} the projection */ QuerySelect.prototype.getJoinProjection = function () { var joinProjection = ''; if (this.joins) { var columns = []; for (var _i = 0, _a = this.joins; _i < _a.length; _i++) { var joinQuery = _a[_i]; var joinTable = joinQuery.getProjectedTable(); for (var _b = 0, _c = joinTable.columnList; _b < _c.length; _b++) { var column = _c[_b]; columns.push(joinQuery.alias + '.' + column.name); } } joinProjection = columns.join(', '); } return joinProjection; }; /** * @public * @method build should be removed to be a part of the private API * * @return {DbQuery} of the query with the string part and * clauses params. */ QuerySelect.prototype.build = function () { var dbQuery = new DbQuery(); dbQuery.page = this.page; dbQuery.size = this.size; dbQuery.table = ModelManager.getInstance().getModel(this.model).name; dbQuery.type = this.type; dbQuery.query += this.type; if (this.proj) { dbQuery.query += ' '; for (var i = 0; i < this.proj.length; i++) { var item = this.proj[i]; if (item.trim().indexOf('(') >= 0) { dbQuery.query += item; } else { dbQuery.query += ' `' + item + '`'; } if (i < this.proj.length - 1) { dbQuery.query += ', '; } } } else if (QueryManager.getInstance().supportRowid) { dbQuery.query += ' rowid, *'; } else { dbQuery.query += ' *'; } if (this.joins && this.joins.length && !this.proj) { dbQuery.query += ', ' + this.getJoinProjection(); } dbQuery.query += ' FROM ' + dbQuery.table; for (var _i = 0, _a = this.joins; _i < _a.length; _i++) { var joinQuery = _a[_i]; dbQuery.append(joinQuery.build()); } if (this.whereClauses) { var w = this.whereClauses.build(); if (w && w.content) { dbQuery.query += ' WHERE'; dbQuery.append(w); } } if (this.grpBy) { dbQuery.query += ' GROUP BY ' + this.grpBy; } if (this.ordrBy) { dbQuery.query += ' ORDER BY ' + this.ordrBy; } return dbQuery; }; /** * @public * @method exec to execute the query and asynchronously retreive result. * * @return {Observable<QueryResult<T>>} observable to subscribe and retrieve typed result */ QuerySelect.prototype.exec = function () { var _this = this; return QueryManager.getInstance().query(this.build()).map(function (qr) { return new ModelResult(qr, _this.model, _this.proj); }); }; /** * @public * @method exec to execute the query and asynchronously retreive result. * * @return {Observable<QueryResult<any>>} observable to subscribe and retrieve result * * @since 0.2 */ QuerySelect.prototype.execRaw = function () { return QueryManager.getInstance().query(this.build()); }; return QuerySelect; }()); export { QuerySelect }; //# sourceMappingURL=query-select.model.js.map