UNPKG

yalento

Version:

An awesome integration of Google Firebase for Angular and Node

328 lines (327 loc) 13.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuerySubject = void 0; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const QueryPaginator_1 = require("./query/QueryPaginator"); //eslint-disable-next-line @typescript-eslint/no-var-requires const alasql = require('alasql'); /** * INTERNAL USE ONLY */ class QuerySubject { /** * * @param repository * @param sql * @param paginatorDefaults */ constructor(repository, sql, paginatorDefaults) { this.repository = repository; this._lastExecStatement = ''; this._subscriptions = []; this._repositoryLastCount = 0; this.uuid = ''; this.queryCallbackChanges$ = new rxjs_1.BehaviorSubject({}); this.paginator = new QueryPaginator_1.QueryPaginator(this); if (sql) { this._sql = sql; } if (paginatorDefaults) { this._paginatorDefaults = paginatorDefaults; } this.setPaginatorDefaults(this._paginatorDefaults, this._sql); this.observeStatement(this._sql); this.observeQueryCallbackChanges(this._sql).then().catch(); } unsubscribe() { this._subscriptions.forEach((sub) => { sub.unsubscribe(); }); } getSql() { return this._sql; } getSqlSelectParsed(sql) { let statement = ''; const params = this.getEvaluatedSqlParams(sql); const querySelect = 'SELECT * FROM tmptablenametmp'; if (!sql) { sql = {}; } if (sql.where) { statement += ' WHERE ' + sql.where; } let selectSqlStatement = alasql.parse(querySelect + statement, params).toString(); if (params) { params.forEach((value, index) => { selectSqlStatement = selectSqlStatement.replace('$' + index, typeof value === 'string' ? "'" + value + "'" : value); }); } let ownerWhere = ''; if (this.getRepository().isPrivateMode()) { ownerWhere += ' `__owner.' + this.getUserUuid() + '` = true '; } else { ownerWhere += ' `__owner.EVERYBODY` = true '; } if (sql.excludeWhereIamOwner === true) { ownerWhere += ' AND `__owner.' + this.getUserUuid() + '` IS NULL '; } if (sql.includeWhereIamOwner === true) { ownerWhere += ' AND `__owner.' + this.getUserUuid() + '` = true '; } if (sql.where) { selectSqlStatement = querySelect + ' WHERE (' + ownerWhere + ') AND (' + selectSqlStatement.substr(querySelect.length + 6) + ')'; } else { selectSqlStatement = selectSqlStatement + ' WHERE ' + ownerWhere; } return selectSqlStatement.replace(/tmptablenametmp/g, this.repository.getClassName()); } /** * * @param sql * @param skipConnectors * @param skipGeolocation */ execStatement(sql, skipConnectors, skipGeolocation) { return __awaiter(this, void 0, void 0, function* () { this.uuid = this.getRepository().getUserUuid(); if (((sql && sql.excludeWhereIamOwner === true) || (sql && sql.includeWhereIamOwner === true) || this.getRepository().isPrivateMode()) && this.uuid === null) { yield this.getRepository().getUserUuidObservable().pipe(operators_1.take(1)).toPromise(); this.uuid = this.getRepository().getUserUuid(); } let statement = ''; const selectSqlStatement = this.getSqlSelectParsed(sql); const params = this.getEvaluatedSqlParams(sql); if (selectSqlStatement.indexOf('LIKE null') > 0) { return rxjs_1.of([]).toPromise(); } if (!skipConnectors && this._lastExecStatement !== selectSqlStatement + this.repository.getGeoQuery()) { this.repository.loadQueryFromConnectors(selectSqlStatement); this._lastExecStatement = selectSqlStatement + this.repository.getGeoQuery(); } if (this._repositoryLastCount === 0 && this.repository.count() === 0) { return rxjs_1.of([]).toPromise(); } this._repositoryLastCount = this.repository.count(); if (!sql) { sql = {}; } if (this.repository.getGeoQuery() && !skipGeolocation) { statement += ' WHERE __removed = false ' + this.repository.getGeoQuery() + ' AND ( '; } else { statement += ' WHERE __removed = false AND ( '; } if (this.getRepository().isPrivateMode()) { statement += '"' + this.getUserUuid() + '" IN __owner '; } else { statement += '"EVERYBODY" IN __owner '; if (this.getUserUuid() !== 'null') { statement += ' OR "' + this.getUserUuid() + '" IN __owner '; } } statement += ' ) '; if (sql.where) { statement += ' AND (' + sql.where + ')'; } if (sql.excludeWhereIamOwner === true) { statement += ' AND "' + this.getUserUuid() + '" IN __owner = false'; } if (sql.includeWhereIamOwner === true) { statement += ' AND "' + this.getUserUuid() + '" IN __owner = true'; } if (this.getPaginator().getPageSortProperty() !== '' && this.getPaginator().getPageSortDirection() !== '') { statement += ' ORDER BY ' + this.getPaginator().getPageSortProperty() + ' ' + this.getPaginator().getPageSortDirection(); } else if (sql.orderBy) { statement += ' ORDER BY ' + sql.orderBy; } statement = this.replaceStatement(statement); const resultsAll = alasql('SELECT * FROM ' + this.repository.getTableName() + ' ' + statement, params).map((d) => d._ref); const count = alasql('SELECT COUNT(*) as c FROM ' + this.repository.getTableName() + ' ' + statement, params)[0]['c']; if (sql.limit && !this.getPaginator().hasPageSizeChanges()) { statement += ' LIMIT ' + sql.limit; } else if (this.getPaginator().getPageSize()) { statement += ' LIMIT ' + this.getPaginator().getPageSize(); } if (sql.offset) { if (sql.limit === undefined) { statement += ' LIMIT 1'; } statement += ' OFFSET ' + sql.offset; } else { if (count && this.getPaginator().getPageIndex() * this.getPaginator().getPageSize() > count) { this.getPaginator().setPageIndex(Math.floor(count / this.getPaginator().getPageSize())); } if (this.getPaginator().getPageIndex() * this.getPaginator().getPageSize()) { statement += ' OFFSET ' + this.getPaginator().getPageIndex() * this.getPaginator().getPageSize(); } } const results = alasql('SELECT _ref FROM ' + this.repository.getTableName() + ' ' + statement, params).map((d) => d._ref); this._lastExecStatement = selectSqlStatement; this.updateQueryCallbackChanges({ resultsAll: resultsAll, results: results, count: count, }); return rxjs_1.of(results).toPromise(); }); } /** * get behaviour subject */ getPaginator() { return this.paginator; } /** * update query callback changes */ updateQueryCallbackChanges(changes) { if (Object.keys(changes).length > 0) { this.queryCallbackChanges$.next(changes); } } /** * get query callback changes observer */ getQueryCallbackChanges() { return this.queryCallbackChanges$; } /** * */ getRepository() { return this.repository; } /** * */ getUserUuid() { return this.getRepository().getUserUuid(); } /** * * @param sql */ getEvaluatedSqlParams(sql) { let params = sql && sql.params !== undefined ? sql.params : null; if (params) { const tmpParams = []; params.forEach((param) => { if (param && typeof param === 'object' && param.asObservable !== undefined && typeof param.asObservable === 'function' && typeof param.getValue === 'function') { tmpParams.push(param.getValue()); } else { tmpParams.push(param); } }); params = tmpParams; } return params; } /** * * @param paginatorDefaults * @param sql */ setPaginatorDefaults(paginatorDefaults, sql) { if (paginatorDefaults && paginatorDefaults.pageSizeOptions) { this.getPaginator().setPageSizeOptions(paginatorDefaults.pageSizeOptions); if (paginatorDefaults.pageSize === undefined) { this.getPaginator().setPageSize(paginatorDefaults.pageSizeOptions[0]); } } if (paginatorDefaults && paginatorDefaults.pageSort) { this.getPaginator().setPageSort(paginatorDefaults.pageSort); } if (paginatorDefaults && paginatorDefaults.pageSize) { this.getPaginator().setPageSize(paginatorDefaults.pageSize, true); if (this.getPaginator().getPageSizeOptions().indexOf(this.getPaginator().getPageSize()) < 0) { this.getPaginator().addPageSizeOption(paginatorDefaults.pageSize); } } else if (sql && sql.limit) { this.getPaginator().setPageSize(sql.limit, true); } } /** * observe and re-execute statement on any changes * @param sql */ observeStatement(sql) { if (sql && sql.params) { sql.params.forEach((param) => { if (param && typeof param === 'object' && param.asObservable !== undefined && typeof param.asObservable === 'function') { this._subscriptions.push(param.asObservable().subscribe(() => { this.updateQueryCallbackChanges({ selectSqlStatement: true }); })); } }); } return; } /** * observe queryCallbackChanges$ */ observeQueryCallbackChanges(sql) { return new Promise((resolve) => { this._subscriptions.push(this.queryCallbackChanges$.subscribe((changes) => __awaiter(this, void 0, void 0, function* () { if (changes.geoLocationChanged || changes.dataAdded || changes.dataRemoved || changes.dataUpdated || changes.pageSize !== undefined || changes.pageIndex !== undefined || changes.pageSort !== undefined || changes.selectSqlStatement !== undefined) { if (changes.geoLocationChanged) { this._lastExecStatement = ''; } this.execStatement(sql); } }))); }); } /** * * @param statement */ replaceStatement(statement) { this.repository.getClassProperties().forEach((property) => { statement = statement.replace(new RegExp('\\(' + property.name + '->', 'gm'), '(_ref->' + property.name + '->'); statement = statement.replace(new RegExp(' ' + property.name + '->', 'gm'), ' _ref->' + property.name + '->'); statement = statement.replace(new RegExp(' ' + property.name + ' ', 'gm'), ' _ref->' + property.name + ' '); statement = statement.replace(new RegExp('\\(' + property.name + ' ', 'gm'), '(_ref->' + property.name + ' '); }); statement = statement.replace('__distance', '_ref->__distance'); return statement; } } exports.QuerySubject = QuerySubject;