UNPKG

ng-db-helper

Version:

Simple db helper for typescript like an orm with plugable connectors.

321 lines 13.9 kB
import { QueryResultWrapper } from './query-result-wrapper'; import { UnsatisfiedRequirementError, QueryError } from 'ts-db-helper'; import { Observable } from 'rxjs/Observable'; /** * @class CordovaSqliteConnector * * @description * This class is a default connector for rdb module see {@link NgDbHelperModuleConfig} * This class provides config key to add copy informations. * * This default connector allow query to database provided with cordova-sqlite-storage * use {@link CordovaSqliteConnectorConfiguration} to override default migrations logics. * * To understand QueryConnectors or ModelMigrations see respectively {@link QueryConnectors}, * {@link ModelMigrations} and configuration default script configuration * * Requirements: cordova, cordova-plugin-file, cordova-sqlite-storage * * @example * ```typescript * const connectorConfig = new CordovaSqliteConnectorConfiguration(); * // configure db name on device * connectorConfig.dbName = app.sqlite; * // add config to connector * const connector = CordovaSqliteConnector(connectorConfig); * // create module config * const config = new NgDbHelperModuleConfig(); * config.queryConnector = connector; * config.modelMigration = connector; * config.version = '1'; * // add config to module with forRoot method * ``` * * @author Olivier Margarit * @since 0.1 */ var CordovaSqliteConnector = (function () { /** * @constructor * @throws {UnsatisfiedRequirementError} thrown if cordova is missing * connector start logic after 'deviceready' signal firing. * * @param {CordovaSqliteConnectorConfiguration} config configuration of the connector, * see {@link CordovaSqliteConnectorConfiguration} * and connector documentation header. */ function CordovaSqliteConnector(config) { var _this = this; this.config = config; /** * @private * @property {boolean} ready flag updated with connector state to indicate that connector can query */ this.ready = false; this.supportRowid = true; if (!window.cordova) { throw (new UnsatisfiedRequirementError('You use cordova connector but cordova is not present !')); } document.addEventListener('deviceready', function () { if (_this.checkRequirements()) { _this.ready = true; } else { // requirements is missing, module could not be ready _this.ready = false; } // callback onReady subscribers if (_this.onReadyObserver) { _this.onReadyObserver.next(_this.ready); _this.onReadyObserver.complete(); } }); } Object.defineProperty(CordovaSqliteConnector.prototype, "db", { /** * @private * @property {SQLiteDatabase} db getter that open database on demand */ get: function () { if (!this.dbValue) { this.dbValue = window .sqlitePlugin.openDatabase({ name: this.config.dbName, location: this.config.location }); } return this.dbValue; }, enumerable: true, configurable: true }); /** * @private * @method checkRequirements check if all platform requirement are satisfied * * @throws {UnsatisfiedRequirementError} log error if cordova-plugin-file or cordova-sqlite-storage is missing */ CordovaSqliteConnector.prototype.checkRequirements = function () { var isRequirementVerified = true; if (!window.resolveLocalFileSystemURL) { var err = new UnsatisfiedRequirementError('CordovaSqliteConnector needs cordova-plugin-file !'); console.error(err); isRequirementVerified = false; } if (!window.sqlitePlugin) { var err = new UnsatisfiedRequirementError('CordovaSqliteConnector needs cordova-sqlite-storage !'); console.error(err); isRequirementVerified = false; } return isRequirementVerified; }; /** * @public * @method query connector method to fire query * * @param {DbQuery} dbQuery DbQuery object containing query and query params. * see {@link DbQuery} * * @return {Observable<QueryResult<any>>} passing {@link QueryResult<any>} on query success * passing {@link QueryError} on query error */ CordovaSqliteConnector.prototype.query = function (dbQuery) { var _this = this; return Observable.create(function (observer) { var q = dbQuery.query; if (dbQuery.type === 'SELECT' && dbQuery.query.toUpperCase().indexOf('LIMIT') < 0 && dbQuery.query.toUpperCase().indexOf('OFFSET') < 0) { var offset = dbQuery.page * dbQuery.size; q += ' LIMIT ' + (offset + dbQuery.size); q += ' OFFSET ' + offset; } if (_this.db) { _this.db.executeSql(q, dbQuery.params, function (results) { observer.next(new QueryResultWrapper(results)); observer.complete(); }, function (err) { return observer.error(new QueryError(err.message, q, dbQuery.params ? dbQuery.params.join(', ') : '')); }); } else { observer.error(new QueryError('no database opened', q, dbQuery.params ? dbQuery.params.join(', ') : '')); } }); }; /** * @public * @method queryBatch make multiple queries in an unique transaction * * @param {DbQuery} dbQueries multiple queries to run in the same transaction * * @return {Observable<QueryResult<any>>} passing {@link QueryResult<any>} on query success * passing {@link QueryError} on query error */ CordovaSqliteConnector.prototype.queryBatch = function (dbQueries) { var _this = this; var queries = []; for (var _i = 0, dbQueries_1 = dbQueries; _i < dbQueries_1.length; _i++) { var dbQuery = dbQueries_1[_i]; queries.push([dbQuery.query, dbQuery.params]); } return Observable.create(function (observer) { if (_this.db) { _this.db.sqlBatch(queries, function (results) { observer.next(new QueryResultWrapper(results)); observer.complete(); }, function (err) { return observer.error(new QueryError(err.message, '', '')); }); } else { observer.error(new QueryError('no database opened', '', '')); } }); }; /** * @public * @method isReady to check if module is ready, if not, caller should * subscribe to {@link CordovaSqliteConnector.onReady} * * @return {boolean} should be true if connector can query else false */ CordovaSqliteConnector.prototype.isReady = function () { return this.ready; }; /** * @public * @method onReady should be subscribed if connector is not ready * if connector is ready, observable is immediatly called, else all check will * be done after 'deviceready' signal * * @return {Observable<boolean>} passing true if connector is ready * passing false if connector will never be ready */ CordovaSqliteConnector.prototype.onReady = function () { var _this = this; return Observable.create(function (observer) { if (_this.ready) { observer.next(_this.ready); observer.complete(); } else { _this.onReadyObserver = observer; } }); }; /** * @public * @method getDbVersion called to check db version, should be called only if connector * is ready. * * @return {Observable<string>} passing string version after version is checked */ CordovaSqliteConnector.prototype.getDbVersion = function () { var _this = this; return Observable.create(function (observer) { if (_this.db) { _this.db.executeSql('PRAGMA user_version;', [], function (results) { if (results.rows.length) { observer.next(results.rows.item(0)); } else { observer.next(''); } observer.complete(); }, function (err) { return observer.error(err); }); } else { observer.next(''); observer.complete(); } }); }; /** * @private * @method isDbCreated is private method to check if db is created before copy * * @return {Observable<boolean>} passing true if db file is present * passing false if db file is missing */ CordovaSqliteConnector.prototype.isDbCreated = function () { var _this = this; var targetDirName = window.cordova.file.dataDirectory; if (window.device.platform === 'Android') { targetDirName = window.cordova.file.applicationStorageDirectory + 'databases/'; console.log('platform is android'); console.log('targetDirName: ' + targetDirName); } return Observable.create(function (observer) { var onTargetDirResolved = function (targetDir) { _this.targetDir = targetDir; targetDir.getFile(_this.config.dbName, {}, function () { _this.dbValue = window.sqlitePlugin .openDatabase({ name: _this.config.dbName, location: _this.config.location }); observer.next(true); observer.complete(); }, function () { observer.next(false); observer.complete(); }); }; window.resolveLocalFileSystemURL(targetDirName, onTargetDirResolved, function (err) { if (window.device.platform === 'Android') { window .resolveLocalFileSystemURL(window.cordova.file.applicationStorageDirectory, function (dir) { dir.getDirectory('databases', { create: true }, function (entry) { return onTargetDirResolved(entry); }, function (error) { return observer.error(error); }); }, function (error) { return observer.error(error); }); } else { observer.error(err); } }); }); }; /** * @public * @method initModel is implemented method from ModelMigration, see {@link ModelMigration} to understand usage. * {@link CordovaSqliteConnectorConfiguration.doCopyDb} is checked: * - if true datamodel is initialized by copy or using config * - if false {@link CordovaSqliteConnectorConfiguration.initDataModel} is called * * @param {DataModel} dataModel data model generated with model annotations * * @return {Observable<any>} resolved on initModel finish */ CordovaSqliteConnector.prototype.initModel = function (dataModel) { var _this = this; if (this.config.doCopyDb) { var sourceFileName_1 = window.cordova.file.applicationDirectory + this.config.sourceDbPath + this.config.sourceDbName; return Observable.create(function (observer) { _this.isDbCreated().subscribe(function (isCreated) { if (isCreated) { observer.next(null); observer.complete(); } else { window.resolveLocalFileSystemURL(sourceFileName_1, function (sourceFile) { sourceFile.copyTo(_this.targetDir, _this.config.dbName, function () { observer.next(null); observer.complete(); }, function (err) { return observer.error(err); }); }, function (err) { return observer.error(err); }); } }, function (err) { return observer.error(err); }); }); } else { return this.config.initDataModel(dataModel, this.db); } }; /** * @public * @method upgradeModel is implemented method from ModelMigration, see {@link ModelMigration} to understand usage. * directly call {@link CordovaSqliteConnectorConfiguration.upgradeDataModel} * * @param {DataModel} dataModel data model generated with model annotations * @param {string} oldVersion old model version * * @return {Observable<any>} resolved on upgradeModel finish */ CordovaSqliteConnector.prototype.upgradeModel = function (dataModel, oldVersion) { return this.config.upgradeDataModel(dataModel, this.db); }; return CordovaSqliteConnector; }()); export { CordovaSqliteConnector }; //# sourceMappingURL=cordova-sqlite-connector.js.map