UNPKG

nativescript-sqlite

Version:

A sqlite NativeScript module for Android and iOS

1,187 lines (1,047 loc) 34.8 kB
/************************************************************************************** * (c) 2015-2021, Master Technology * Licensed under the MIT license or contact me for a support, changes, enhancements, * and/or if you require a commercial licensing * * Any questions please feel free to put a issue up on github * Nathan@master-technology.com http://nativescript.tools * Version 2.7.0 - Android *************************************************************************************/ /* global global, require, module */ "use strict"; const appModule = require("@nativescript/core/application"); const fsModule = require("@nativescript/core/file-system"); //import * as appModule from '@nativescript/core/application'; //import * as fsModule from '@nativescript/core/file-system'; /*jshint undef: true */ /*global java, android, Promise */ // Needed for Creating Database - Android Specific flag //var CREATEIFNEEDED = 0x10000000; // Used to track any plugin Init let _DatabasePluginInits = []; /*** * Parses a Row of data into a JS Array (as Native) * @param cursor {Object} * @returns {Array} */ function DBGetRowArrayNative(cursor) { //noinspection JSUnresolvedFunction let count = cursor.getColumnCount(); let results = []; for (let i=0;i<count;i++) { const type = cursor.getType(i); switch (type) { case 0: // NULL results.push(null); break; case 1: // Integer //noinspection JSUnresolvedFunction results.push(cursor.getLong(i)); break; case 2: // Float //noinspection JSUnresolvedFunction results.push(cursor.getFloat(i)); break; case 3: // String //noinspection JSUnresolvedFunction results.push(cursor.getString(i)); break; case 4: // Blob // noinspection JSCheckFunctionSignatures results.push(cursor.getBlob(i)); break; default: throw new Error('SQLITE - Unknown Field Type ' + type); } } return results; } /*** * Parses a Row of data into a JS Array (as String) * @param cursor * @returns {Array} */ function DBGetRowArrayString(cursor) { //noinspection JSUnresolvedFunction let count = cursor.getColumnCount(); let results = []; for (let i=0;i<count;i++) { const type = cursor.getType(i); switch (type) { case 0: // NULL results.push(null); break; case 1: // Integer //noinspection JSUnresolvedFunction results.push(cursor.getString(i)); break; case 2: // Float //noinspection JSUnresolvedFunction results.push(cursor.getString(i)); break; case 3: // String //noinspection JSUnresolvedFunction results.push(cursor.getString(i)); break; case 4: // Blob // noinspection JSCheckFunctionSignatures results.push(cursor.getBlob(i)); break; default: throw new Error('SQLITE - Unknown Field Type ' + type); } } return results; } /*** * Parses a Row of data into a JS Object (as Native) * @param cursor * @returns {{}} */ function DBGetRowObjectNative(cursor) { //noinspection JSUnresolvedFunction const count = cursor.getColumnCount(); let results = {}; for (let i=0;i<count;i++) { const type = cursor.getType(i); //noinspection JSUnresolvedFunction const name = cursor.getColumnName(i); switch (type) { case 0: // NULL results[name] = null; break; case 1: // Integer //noinspection JSUnresolvedFunction results[name] = cursor.getLong(i); break; case 2: // Float //noinspection JSUnresolvedFunction results[name] = cursor.getFloat(i); break; case 3: // String //noinspection JSUnresolvedFunction results[name] = cursor.getString(i); break; case 4: // Blob // noinspection JSCheckFunctionSignatures results[name] = cursor.getBlob(i); break; default: throw new Error('SQLITE - Unknown Field Type '+ type); } } return results; } /*** * Parses a Row of data into a JS Object (as String) * @param cursor * @returns {{}} */ function DBGetRowObjectString(cursor) { //noinspection JSUnresolvedFunction const count = cursor.getColumnCount(); let results = {}; for (let i=0;i<count;i++) { const type = cursor.getType(i); //noinspection JSUnresolvedFunction const name = cursor.getColumnName(i); switch (type) { case 0: // NULL results[name] = null; break; case 1: // Integer //noinspection JSUnresolvedFunction results[name] = cursor.getString(i); break; case 2: // Float //noinspection JSUnresolvedFunction results[name] = cursor.getString(i); break; case 3: // String //noinspection JSUnresolvedFunction results[name] = cursor.getString(i); break; case 4: // Blob // noinspection JSCheckFunctionSignatures results[name] = cursor.getBlob(i); break; default: throw new Error('SQLITE - Unknown Field Type '+ type); } } return results; } // Default Resultset engine let DBGetRowResults = DBGetRowArrayNative; function setResultValueTypeEngine(resultType, valueType) { if (resultType === Database.RESULTSASOBJECT) { if (valueType === Database.VALUESARENATIVE) { DBGetRowResults = DBGetRowObjectNative; } else { DBGetRowResults = DBGetRowObjectString; } } else { // RESULTSASARRAY if (valueType === Database.VALUESARENATIVE) { DBGetRowResults = DBGetRowArrayNative; } else { DBGetRowResults = DBGetRowArrayString; } } } /*** * Database Constructor * @param dbname - Database Name * @param callback - Callback when Done * @param options * @returns {Promise} object * @constructor */ function Database(dbname, options, callback) { if (!(this instanceof Database)) { // jshint ignore:line //noinspection JSValidateTypes return new Database(dbname, options, callback); } this._messageHandlers = []; this._isOpen = false; this._resultType = Database.RESULTSASARRAY; this._valuesType = Database.VALUESARENATIVE; if (typeof options === 'function') { callback = options; //noinspection JSUnusedAssignment options = {}; } else { //noinspection JSUnusedAssignment options = options || {}; } this._options = options; // Check to see if it has a path, or if it is a relative dbname // dbname = "" - Temporary Database // dbname = ":memory:" = memory database if (dbname !== "" && dbname !== ":memory:") { //noinspection JSUnresolvedFunction dbname = _getContext().getDatabasePath(dbname).getAbsolutePath().toString(); let path = dbname.substr(0, dbname.lastIndexOf('/') + 1); // Create "databases" folder if it is missing. This causes issues on Emulators if it is missing // So we create it if it is missing try { //noinspection JSUnresolvedFunction,JSUnresolvedVariable let javaFile = new java.io.File(path); if (!javaFile.exists()) { //noinspection JSUnresolvedFunction javaFile.mkdirs(); //noinspection JSUnresolvedFunction javaFile.setReadable(true); //noinspection JSUnresolvedFunction javaFile.setWritable(true); } } catch (err) { console.info("SQLITE.CONSTRUCTOR - Creating DB Folder Error", err); } } const self = this; return new Promise(function (resolve, reject) { try { let flags = 0; if (typeof options.androidFlags !== 'undefined') { flags = options.androidFlags; } self._db = self._openDatabase(dbname, flags, options, _getContext()); } catch (err) { console.error("SQLITE.CONSTRUCTOR - Open DB Error", err); if (callback) { callback(err, null); } reject(err); return; } self._isOpen = true; let doneCnt = _DatabasePluginInits.length, doneHandled = 0; const done = function (err) { if (err) { doneHandled = doneCnt; // We don't want any more triggers after this if (callback) { callback(err, null); } reject(err); return; } doneHandled++; if (doneHandled === doneCnt) { if (callback) { callback(null, self); } resolve(self); } }; if (doneCnt) { try { for (let i = 0; i < doneCnt; i++) { _DatabasePluginInits[i].call(self, options, done); } } catch (err) { done(err); } } else { if (callback) { callback(null, self); } resolve(self); } }); } /** * Function to handle opening Database * @param dbName * @param flags * @private */ Database.prototype._openDatabase = function(dbName, flags) { if (dbName === ":memory:") { //noinspection JSUnresolvedVariable return android.database.sqlite.SQLiteDatabase.create(null); } else { //noinspection JSUnresolvedVariable,JSUnresolvedFunction return android.database.sqlite.SQLiteDatabase.openDatabase(dbName, null, flags | 0x10000000); } }; /*** * Constant that this structure is a sqlite structure * @type {boolean} */ Database.prototype._isSqlite = true; /*** * This gets or sets the database version * @param valueOrCallback to set or callback(err, version) * @returns Promise */ Database.prototype.version = function(valueOrCallback) { return new Promise((resolve, reject) => { if (typeof valueOrCallback === 'function') { this.get('PRAGMA user_version', function (err, data) { const value = data && parseInt(data[0], 10); valueOrCallback(err, value); if (err) { reject(err); } else resolve(value); }, Database.RESULTSASARRAY); } else if (!isNaN(valueOrCallback + 0)) { this.execSQL('PRAGMA user_version=' + (valueOrCallback + 0).toString()).then(resolve, reject); } else { this.get('PRAGMA user_version', undefined, undefined, Database.RESULTSASARRAY).then((data) => { resolve(data && parseInt(data[0], 10)) }).catch(reject); } }); }; /*** * Is the database currently open * @returns {boolean} - true if the db is open */ Database.prototype.isOpen = function() { return this._isOpen; }; /*** * Gets/Sets whether you get Arrays or Objects for the row values * @param value - Database.RESULTSASARRAY or Database.RESULTSASOBJECT * @returns {number} - Database.RESULTSASARRAY or Database.RESULTSASOBJECT */ Database.prototype.resultType = function(value) { if (value === Database.RESULTSASARRAY) { this._resultType = Database.RESULTSASARRAY; setResultValueTypeEngine(this._resultType, this._valuesType); } else if (value === Database.RESULTSASOBJECT) { this._resultType = Database.RESULTSASOBJECT; setResultValueTypeEngine(this._resultType, this._valuesType); } return this._resultType; }; /*** * Gets/Sets whether you get Native or Strings for the row values * @param value - Database.VALUESARENATIVE or Database.VALUESARESTRINGS * @returns {number} - Database.VALUESARENATIVE or Database.VALUESARESTRINGS */ Database.prototype.valueType = function(value) { if (value === Database.VALUESARENATIVE) { this._valuesType = Database.VALUESARENATIVE; setResultValueTypeEngine(this._resultType, this._valuesType); } else if (value === Database.VALUESARESTRINGS) { this._valuesType = Database.VALUESARESTRINGS; setResultValueTypeEngine(this._resultType, this._valuesType); } return this._valuesType; }; // noinspection JSUnusedLocalSymbols /** * Dummy transaction function for public version * @param callback * @returns {Promise} */ Database.prototype.begin = function(callback) { throw new Error("Transactions are a Commercial version feature."); }; // noinspection JSUnusedLocalSymbols /** * Dummy prepare function for public version * @param sql * @returns {*} */ Database.prototype.prepare = function(sql) { throw new Error("Prepared statements are a Commercial version feature."); }; // noinspection JSUnusedLocalSymbols /** * Dummy sync enable tracking function for public version * @returns {*} */ Database.prototype.enableTracking = function(tables, options, callback) { throw new Error("Table sync is a Commercial version feature."); }; /*** * Closes this database, any queries after this will fail with an error * @param callback */ Database.prototype.close = function(callback) { const self = this; return new Promise(function(resolve, reject) { if (!self._isOpen) { if (callback) { callback('SQLITE.CLOSE - Database is already closed'); } reject('SQLITE.CLOSE - Database is already closed'); return; } self._db.close(); self._isOpen = false; if (callback) { callback(null, null); } resolve(); }); }; /*** * Exec SQL * @param sql - sql to use * @param params - optional array of parameters * @param callback - (err, result) - can be last_row_id for insert, and rows affected for update/delete * @returns Promise */ Database.prototype.execSQL = function(sql, params, callback) { if (typeof params === 'function') { callback = params; params = undefined; } const self = this; return new Promise(function(resolve, reject) { let hasCallback = true; if (typeof callback !== 'function') { callback = reject; hasCallback = false; } if (!self._isOpen) { callback("SQLITE.EXECSQL - Database is not open"); return; } // Need to see if we have to run any status queries afterwords let flags = 0; let test = sql.trim().substr(0, 7).toLowerCase(); if (test === 'insert ') { flags = 1; } else if (test === 'update ' || test === 'delete ') { flags = 2; } try { if (params !== undefined) { self._db.execSQL(sql, self._toStringArray(params)); } else { self._db.execSQL(sql); } } catch (Err) { callback(Err, null); return; } switch (flags) { case 0: if (hasCallback) { callback(null, null); } resolve(null); break; case 1: // noinspection JSIgnoredPromiseFromCall self.get('select last_insert_rowid()', function (err, data) { if (hasCallback) { callback(err, data && data[0]); } if (err) { reject(err); } else { resolve(data && data[0]); } }, Database.RESULTSASARRAY | Database.VALUESARENATIVE); break; case 2: // noinspection JSIgnoredPromiseFromCall self.get('select changes()', function (err, data) { if (hasCallback) { callback(err, data && data[0]); } if (err) { reject(err); } else { resolve(data && data[0]); } }, Database.RESULTSASARRAY | Database.VALUESARENATIVE); break; default: resolve(); } }); }; /*** * Get the first record result set * @param sql - sql to run * @param params - optional * @param callback - callback (error, results) * @param mode - allows you to manually override the results set to be a array or object * @returns Promise */ Database.prototype.get = function(sql, params, callback, mode) { if (typeof params === 'function') { mode = callback; callback = params; params = undefined; } const self = this; return new Promise(function(resolve, reject) { let hasCallback = true; if (typeof callback !== 'function') { callback = reject; hasCallback = false; } if (!self._isOpen) { callback("SQLITE.GET - Database is not open", null); return; } let cursor; try { if (params !== undefined) { //noinspection JSUnresolvedFunction cursor = self._db.rawQuery(sql, self._toStringArray(params)); } else { //noinspection JSUnresolvedFunction cursor = self._db.rawQuery(sql, null); } } catch (err) { callback(err, null); return; } // No Records // noinspection JSUnresolvedFunction if (cursor.getCount() === 0) { cursor.close(); if (hasCallback) { callback(null, null); } resolve(null); return; } let results; const resultEngine = self._getResultEngine(mode); try { //noinspection JSUnresolvedFunction cursor.moveToFirst(); results = resultEngine(cursor); cursor.close(); } catch (err) { callback(err, null); return; } if (hasCallback) { callback(null, results); } resolve(results); }); }; Database.prototype._getResultEngine = function(mode) { if (mode == null || mode === 0) { mode = this._resultType | this._valuesType; } let resultType = (mode & (Database.RESULTSASARRAY|Database.RESULTSASOBJECT)); if (resultType === 0) { resultType = this._resultType; } let valueType = (mode & (Database.VALUESARENATIVE|Database.VALUESARESTRINGS)); if (valueType === 0) { valueType = this._valuesType; } if (resultType === Database.RESULTSASOBJECT) { if (valueType === Database.VALUESARESTRINGS) { return DBGetRowObjectString; } else { return DBGetRowObjectNative; } } else { if (valueType === Database.VALUESARESTRINGS) { return DBGetRowArrayString; } else { return DBGetRowArrayNative; } } }; /*** * This returns the entire result set in a array of rows * @param sql - Sql to run * @param params - optional * @param callback - (err, results) * @param mode - Allow you to force a specific mode * @returns Promise */ Database.prototype.all = function(sql, params, callback, mode) { if (typeof params === 'function') { mode = callback; callback = params; params = undefined; } const self = this; return new Promise(function(resolve, reject) { let hasCallback = true; if (typeof callback !== 'function') { callback = reject; hasCallback = false; } if (!self._isOpen) { callback("SQLITE.ALL - Database is not open"); return; } let cursor, count; try { if (params !== undefined) { //noinspection JSUnresolvedFunction cursor = self._db.rawQuery(sql, self._toStringArray(params)); } else { //noinspection JSUnresolvedFunction cursor = self._db.rawQuery(sql, null); } // noinspection JSUnresolvedFunction count = cursor.getCount(); } catch (err) { callback(err); return; } // No Records if (count === 0) { cursor.close(); if (hasCallback) { callback(null, []); } resolve([]); return; } //noinspection JSUnresolvedFunction cursor.moveToFirst(); const resultEngine = self._getResultEngine(mode); let results = []; try { for (let i = 0; i < count; i++) { const data = resultEngine(cursor); // jshint ignore:line results.push(data); //noinspection JSUnresolvedFunction cursor.moveToNext(); } cursor.close(); } catch (err) { callback(err); return; } if (hasCallback) { callback(null, results); } resolve(results); }); }; /*** * This sends each row of the result set to the "Callback" and at the end calls the complete callback upon completion * @param sql - sql to run * @param params - optional * @param callback - callback (err, rowsResult) * @param complete - callback (err, recordCount) * @returns Promise */ Database.prototype.each = function(sql, params, callback, complete) { if (typeof params === 'function') { complete = callback; callback = params; params = undefined; } // Callback is required if (typeof callback !== 'function') { throw new Error("SQLITE.EACH - requires a callback"); } const self = this; return new Promise(function (resolve, reject) { // Set the error Callback let errorCB = complete || callback; let cursor, count; try { if (params !== undefined) { //noinspection JSUnresolvedFunction cursor = self._db.rawQuery(sql, self._toStringArray(params)); } else { //noinspection JSUnresolvedFunction cursor = self._db.rawQuery(sql, null); } // noinspection JSUnresolvedFunction count = cursor.getCount(); } catch (err) { errorCB(err, null); reject(err); return; } // No Records if (count === 0) { cursor.close(); if (complete) { complete(null, 0); } resolve(0); return; } //noinspection JSUnresolvedFunction cursor.moveToFirst(); try { for (let i = 0; i < count; i++) { const data = DBGetRowResults(cursor); // jshint ignore:line callback(null, data); //noinspection JSUnresolvedFunction cursor.moveToNext(); } cursor.close(); } catch (err) { errorCB(err, null); reject(err); return; } if (complete) { complete(null, count); } resolve(count); }); }; /*** * Converts a Mixed Array to a String Array * @param paramsIn * @returns {Array} * @private */ Database.prototype._toStringArray = function(paramsIn) { let stringParams = [], params; if (Object.prototype.toString.apply(paramsIn) !== '[object Array]') { params = [paramsIn]; } else { params = paramsIn; } const count = params.length; for (let i = 0; i < count; ++i) { if (params[i] == null) { // jshint ignore:line stringParams.push(null); } else if (params[i].getClass) { switch (params[i].getClass().getSimpleName()) { case "ByteArrayOutputStream": stringParams.push(params[i].toByteArray()); break; case "byte[]": stringParams.push(params[i]); break; default: console.warn("Unknown Java class:", params[i].getClass().getSimpleName(), "Converting to string"); stringParams.push(params[i].toString()); } } else { stringParams.push(params[i].toString()); } } return stringParams; }; Database.prototype.notify = function(type, message) { if (typeof global.postMessage === 'function') { postMessage({id: -2, type: type, message: message}); } else { console.error("SQLite: Not in a thread"); // Local Notify this._notify(type, message); } }; Database.prototype._notify = function(type, message) { if (type == null || typeof this._messageHandlers[type] === "undefined") { return; } let handlers = this._messageHandlers[type]; try { for (let i = 0; i < handlers; i++) { handlers[i](message, type, this); } } catch (err) { console.error("SQLite: Error in user code ", err, err.stack); } } Database.prototype.addMessageHandler = function(type, callback) { if (typeof this._messageHandlers[type] === 'undefined') { this._messageHandlers[type] = []; } this._messageHandlers[type].push(callback); }; Database.prototype.removeMessageHandler = function(type, callback) { if (type != null && typeof this._messageHandlers[type] === "undefined") { console.error("SQLite: This message handler " + type + " does not exist."); return; } if (callback) { // Remove all message handles that match this callback & this db... for (let i = 0; i < this._messageHandlers[type].length; i++) { if (this._messageHandlers[type][i].callback === callback) { this._messageHandlers[type].splice(i, 1); i--; } } } else if (type != null) { // Remove all message handlers for this type this._messageHandlers[type] = []; } else { // Remove all message handlers for this database this._messageHandlers = []; } }; /*** * Is this a SQLite object * @param obj - possible sqlite object to check * @returns {boolean} */ Database.isSqlite = function(obj) { return obj && obj._isSqlite; }; /** * Does this database exist on disk * @param name * @returns {*} */ Database.exists = function(name) { //noinspection JSUnresolvedFunction const dbName = _getContext().getDatabasePath(name).getAbsolutePath(); // noinspection JSUnresolvedFunction,JSUnresolvedVariable const dbFile = new java.io.File(dbName); // noinspection JSUnresolvedFunction return dbFile.exists(); }; /** * Delete the database file if it exists * @param name */ Database.deleteDatabase = function(name) { //noinspection JSUnresolvedFunction const dbName = _getContext().getDatabasePath(name).getAbsolutePath(); // noinspection JSUnresolvedFunction,JSUnresolvedVariable let dbFile = new java.io.File(dbName); if (dbFile.exists()) { dbFile.delete(); // noinspection JSUnresolvedFunction,JSUnresolvedVariable dbFile = new java.io.File(dbName + '-journal'); if (dbFile.exists()) { dbFile.delete(); } } }; Database.manualBackup = function(name) { const dbName = _getContext().getDatabasePath(name).getAbsolutePath(); let dbFile = new java.io.File(dbName); let myInput = new java.io.FileInputStream(dbName); if (dbFile.exists()) { // Attempt to use the local app directory version // noinspection JSUnresolvedFunction,JSUnresolvedVariable const outPath = android.os.Environment.getExternalStoragePublicDirectory (android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/" + name; let myOutput = new java.io.FileOutputStream( outPath ); let success = true; try { //transfer bytes from the input file to the output file //noinspection JSUnresolvedFunction,JSUnresolvedVariable let buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.class.getField("TYPE").get(null), 1024); let length; while ((length = myInput.read(buffer)) > 0) { // noinspection JSUnresolvedFunction myOutput.write(buffer, 0, length); } } catch (err) { success = false; } //Close the streams // noinspection JSUnresolvedFunction myOutput.flush(); // noinspection JSUnresolvedFunction myOutput.close(); myInput.close(); return success; } }; /** * Copy the database from the install location * @param name * @param destName - Optional DB Destination Name */ Database.copyDatabase = function (name, destName) { //Open your local db as the input stream let myInput; try { let sourcePath, tempName; if (name.indexOf('/') === -1) { sourcePath = fsModule.knownFolders.currentApp().path + '/'; tempName = name; } else { sourcePath = name.substr(0, name.lastIndexOf('/') + 1); tempName = name.substr(sourcePath.length); } // Attempt to use the local app directory version // noinspection JSUnresolvedFunction,JSUnresolvedVariable myInput = new java.io.FileInputStream(sourcePath + tempName); } catch (err) { // Use the Assets version // noinspection JSUnresolvedFunction myInput = _getContext().getAssets().open("app/" + name); } if (name.indexOf('/') >= 0) { name = name.substring(name.lastIndexOf('/') + 1); } // If we don't have a destName set; use Name if (!destName) { destName = name; } else if (destName.indexOf("/") >= 0) { destName = destName.substring(destName.lastIndexOf('/') + 1); } //noinspection JSUnresolvedFunction const dbName = _getContext().getDatabasePath(destName).getAbsolutePath(); const path = dbName.substr(0, dbName.lastIndexOf('/') + 1); // Create "databases" folder if it is missing. This causes issues on Emulators if it is missing // So we create it if it is missing try { // noinspection JSUnresolvedFunction,JSUnresolvedVariable const javaFile = new java.io.File(path); //noinspection JSUnresolvedFunction if (!javaFile.exists()) { //noinspection JSUnresolvedFunction javaFile.mkdirs(); //noinspection JSUnresolvedFunction javaFile.setReadable(true); //noinspection JSUnresolvedFunction javaFile.setWritable(true); } } catch (err) { console.info("SQLITE - COPYDATABASE - Creating DB Folder Error", err); } //Open the empty db as the output stream // noinspection JSUnresolvedFunction,JSUnresolvedVariable const myOutput = new java.io.FileOutputStream(dbName); let success = true; try { //transfer bytes from the input file to the output file //noinspection JSUnresolvedFunction,JSUnresolvedVariable let buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.class.getField("TYPE").get(null), 1024); let length; while ((length = myInput.read(buffer)) > 0) { // noinspection JSUnresolvedFunction myOutput.write(buffer, 0, length); } } catch (err) { success = false; } //Close the streams // noinspection JSUnresolvedFunction myOutput.flush(); // noinspection JSUnresolvedFunction myOutput.close(); myInput.close(); return success; }; // Literal Defines Database.prototype.RESULTSASARRAY = Database.RESULTSASARRAY = 1; Database.prototype.RESULTSASOBJECT = Database.RESULTSASOBJECT = 2; Database.prototype.VALUESARENATIVE = Database.VALUESARENATIVE = 4; Database.prototype.VALUESARESTRINGS = Database.VALUESARESTRINGS = 8; TryLoadingCommercialPlugin(); TryLoadingEncryptionPlugin(); TryLoadingSyncPlugin(); module.exports = Database; /** * gets the current application context * @returns {*} * @private */ function _getContext() { try { if (appModule.android.context) { return (appModule.android.context); } if (typeof appModule.getNativeApplication === 'function') { let ctx = appModule.getNativeApplication(); if (ctx) { return ctx; } } } catch (err) { console.log("SQLITE: Using Fallback"); // In some cases Multidex has been the report // the getNativeApplication calls .getInstance which fails } //noinspection JSUnresolvedFunction,JSUnresolvedVariable let ctx = java.lang.Class.forName("android.app.AppGlobals").getMethod("getInitialApplication", null).invoke(null, null); if (ctx) return ctx; //noinspection JSUnresolvedFunction,JSUnresolvedVariable ctx = java.lang.Class.forName("android.app.ActivityThread").getMethod("currentApplication", null).invoke(null, null); return ctx; } /** Uses a SQLite Plugin **/ function UsePlugin(loadedSrc, DBModule) { if (loadedSrc.prototypes) { for (let key in loadedSrc.prototypes) { if (!loadedSrc.prototypes.hasOwnProperty(key)) { continue; } if (DBModule.prototype[key]) { DBModule.prototype["_"+key] = DBModule.prototype[key]; } DBModule.prototype[key] = loadedSrc.prototypes[key]; } } if (loadedSrc.statics) { for (let key in loadedSrc.statics) { if (!loadedSrc.statics.hasOwnProperty(key)) { continue; } DBModule[key] = loadedSrc.statics[key]; } } if (typeof loadedSrc.init === 'function') { _DatabasePluginInits.push(loadedSrc.init); } } function TryLoadingCommercialPlugin() { try { const sqlCom = require('nativescript-sqlite-commercial'); UsePlugin(sqlCom, Database); } catch (e) { /* Do Nothing if it doesn't exist as it is an optional plugin */ } } function TryLoadingEncryptionPlugin() { try { const sqlEnc = require('nativescript-sqlite-encrypted'); UsePlugin(sqlEnc, Database); } catch (e) { /* Do Nothing if it doesn't exist as it is an optional plugin */ } } function TryLoadingSyncPlugin() { try { const sqlSync = require('nativescript-sqlite-sync'); UsePlugin(sqlSync, Database); } catch (e) { /* Do Nothing if it doesn't exist as it is an optional plugin */ } }