UNPKG

ts-db-helper

Version:
208 lines 7.99 kB
import { QueryError } from '../../errors/query.error'; import { QueryManager } from '../../managers/query-manager'; import { Observable } from 'rxjs/Observable'; import { ModelManager } from '../../managers/model-manager'; import { DbQuery } from '../db-query.model'; import 'rxjs/add/observable/combineLatest'; import 'rxjs/add/operator/map'; /** * @public * @class QueryInsert * * @description * For design reasons this class should not be used directly. Use this class with {@link Insert} function. * Prefer use of save() method instead of Insert for a single entry. * Insert optimize multiple entry insertion with bulk mecanisme for example. * * @param T @extends DbHelperModel a model declared with table and column annotations * * @example * ```typescript * // Create new model instance * const todo = new Todo(); * // manipulates todo instance and then insert it * Insert(todo).exec().subscribe((qr: QueryResult<any>) => { * // do something after insertion * }, (err) => { * // manage error * }); * * // it is simplier to use the save methode for a single entry * todo.save() * * // Insertion should be used for multiple model insertion * const todos = <Todo[]>[]; * // provide and edi.subscribe((qr: QueryResult<any>) => { * // do something after insertion * }, (err) => { * // manage error * });t new entries * Insert(todos).exec().subscribe((qr: QueryResult<any>) => { * // do something after insertion * }, (err) => { * // manage error * }); * ``` * * @author Olivier Margarit * @since 0.1 */ var QueryInsert = /** @class */ (function () { /** * @public * @constructor should not be use directly, see class header * * @param {T | Array<T>} model DbHelper model or list of models */ function QueryInsert(model) { this.model = model; /** * @private * @constant {string} type statement type */ this.type = 'INSERT'; } /** * @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. */ QueryInsert.prototype.build = function () { var table; var dbQuery = new DbQuery(); if (Array.isArray(this.model)) { if (this.model.length) { table = ModelManager.getInstance().getModel(this.model[0]); } else { return dbQuery; } } else { table = ModelManager.getInstance().getModel(this.model); } dbQuery.table = table.name; dbQuery.type = this.type; var columns = []; for (var _i = 0, _a = table.columnList; _i < _a.length; _i++) { var column = _a[_i]; columns.push(column.name); } dbQuery.query += this.type + ' INTO ' + table.name + ' (`' + columns.join('`, `') + '`) VALUES '; var items = Array.isArray(this.model) ? this.model : [this.model]; var valuesStrings = []; var parameters = []; for (var _b = 0, items_1 = items; _b < items_1.length; _b++) { var item = items_1[_b]; var interrogationMarks = []; for (var _c = 0, _d = table.columnList; _c < _d.length; _c++) { var column = _d[_c]; var value = item.getColumnValue(column.name); if (value === undefined) { parameters.push(null); item.setFieldValue(column.field, null); } else { parameters.push(value); } interrogationMarks.push('?'); } valuesStrings.push('(' + interrogationMarks.join(', ') + ')'); } dbQuery.query += valuesStrings.join(', '); dbQuery.params = dbQuery.params.concat(parameters); return dbQuery; }; /** * @public * @method exec to execute the query and asynchronously retreive result. * * @return {Observable<QueryResult<any>>} observable to subscribe and manage results */ QueryInsert.prototype.exec = function () { var _this = this; var observable = null; if (Array.isArray(this.model)) { // check if array is to big for insertion var table = void 0; if (this.model.length) { table = ModelManager.getInstance().getModel(this.model[0]); } else { throw (new QueryError('Try to insert empty array', '', '')); } var maxItemNumberPerRequest = Math.floor(QueryInsert.SQLITE_PRAMS_LIMIT / table.columnList.length); var numberOfParts = Math.floor(this.model.length / maxItemNumberPerRequest) + 1; if (numberOfParts > 1) { // Array is to big, subsequent insert queries will be created and executed var observables = []; for (var i = 0; i < numberOfParts; i += 1) { var start = i * maxItemNumberPerRequest; var nextIndex = start + maxItemNumberPerRequest; var end = nextIndex < this.model.length ? nextIndex : this.model.length; if (start >= end) { break; } var insert = (new QueryInsert(this.model.slice(start, end))); observables.push(insert.exec()); } observable = Observable.combineLatest(observables).map(function (qrs) { var rowsAffected = 0; var insertId; for (var _i = 0, qrs_1 = qrs; _i < qrs_1.length; _i++) { var qr = qrs_1[_i]; rowsAffected += qr.rowsAffected; if (qr && qr.insertId || qr.insertId === 0) { insertId = Math.max(insertId ? insertId : 0, qr.insertId); } } return { rowsAffected: rowsAffected, insertId: insertId, rows: { length: 0, item: function (i) { return null; }, toArray: function () { return []; } } }; }); } } if (!observable) { // this is not a too big array, so the query can simply be executed observable = QueryManager.getInstance().query(this.build()); observable.map(function (qr) { if (Array.isArray(_this.model)) { for (var _i = 0, _a = _this.model; _i < _a.length; _i++) { var model = _a[_i]; model.$$inserted = true; model.$$isModified = false; } } else { _this.model.$$inserted = true; _this.model.$$isModified = false; } return qr; }); } return observable; }; /** * @private * @static * @constant {number} SQLITE_PRAMS_LIMIT is a standard SQLite driver limit * this parameter will probably be customizable in a futrue * release */ QueryInsert.SQLITE_PRAMS_LIMIT = 999; return QueryInsert; }()); export { QueryInsert }; //# sourceMappingURL=query-insert.model.js.map