Socket
Socket
Sign inDemoInstall

@capacitor-community/sqlite

Package Overview
Dependencies
Maintainers
14
Versions
241
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@capacitor-community/sqlite - npm Package Compare versions

Comparing version 2.4.2-5 to 2.4.2-6

ios/Plugin/Utils/UtilsConnection.swift

9

CHANGELOG.md

@@ -0,1 +1,8 @@

## 2.4.2-6 (2020-10-16)
### Added Features
- Add addUpgradeStatement for version upgrade (iOS & Electron)
- Add UgradeDatabaseVersion.md documentation
## 2.4.2-5 (2020-10-08)

@@ -15,3 +22,3 @@

### ### Added Features
### Added Features

@@ -18,0 +25,0 @@ - Add docgen to generate API documentation

84

dist/esm/definitions.d.ts

@@ -10,3 +10,3 @@ declare module '@capacitor/core' {

*
* @param options The echo options
* @param options: capEchoOptions
* @return Promise<{ value: string }

@@ -18,4 +18,4 @@ * @since 0.0.1

* Open a SQLite database
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 0.0.1

@@ -26,4 +26,4 @@ */

* Close a SQLite database
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 0.0.1

@@ -34,4 +34,4 @@ */

* Execute a Batch of Raw Statements as String
* @param {capSQLiteExecuteOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteExecuteOptions
* @returns Promise<capSQLiteChanges>
* @since 0.0.1

@@ -42,4 +42,4 @@ */

* Execute a Set of Raw Statements as Array of CapSQLiteSet
* @param {capSQLiteSetOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteSetOptions
* @returns Promise<capSQLiteChanges>
* @since 2.2.0-2

@@ -50,4 +50,4 @@ */

* Execute a Single Statement
* @param {capSQLiteRunOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteRunOptions
* @returns Promise<capSQLiteChanges>
* @since 0.0.1

@@ -58,4 +58,4 @@ */

* Query a Single Statement
* @param {capSQLiteQueryOptions} options
* @returns {Promise<capSQLiteValues>}
* @param options: capSQLiteQueryOptions
* @returns Promise<capSQLiteValues>
* @since 0.0.1

@@ -66,4 +66,4 @@ */

* Check is a SQLite database exists
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 2.0.1-1

@@ -74,4 +74,4 @@ */

* Delete a SQLite database
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 0.0.1

@@ -82,4 +82,4 @@ */

* Is Json Object Valid
* @param {capSQLiteImportOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteImportOptions
* @returns Promise<capSQLiteResult>
* @since 2.0.1-1

@@ -90,4 +90,4 @@ */

* Import from Json Object
* @param {capSQLiteImportOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteImportOptions
* @returns Promise<capSQLiteChanges>
* @since 2.0.0-3

@@ -98,4 +98,4 @@ */

* Export to Json Object
* @param {capSQLiteExportOptions} options
* @returns {Promise<capSQLiteJson>}
* @param options: capSQLiteExportOptions
* @returns Promise<capSQLiteJson>
* @since 2.0.1-1

@@ -106,3 +106,3 @@ */

* Create a synchronization table
* @returns {Promise<capSQLiteChanges>}
* @returns Promise<capSQLiteChanges>
* @since 2.0.1-1

@@ -113,7 +113,14 @@ */

* Set the synchronization date
* @param {capSQLiteSyncDateOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteSyncDateOptions
* @returns Promise<capSQLiteResult>
* @since 2.0.1-1
*/
setSyncDate(options: capSQLiteSyncDateOptions): Promise<capSQLiteResult>;
/**
* Add the upgrade Statement for database version upgrading
* @param options: capSQLiteUpgradeOptions
* @returns Promise<capSQLiteResult>
* @since 2.4.2-6 iOS & Electron
*/
addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<capSQLiteResult>;
}

@@ -132,2 +139,6 @@ export interface capEchoOptions {

/**
* The database version
*/
version?: number;
/**
* Set to true (database encryption) / false

@@ -208,2 +219,13 @@ * - Open method only

}
export interface capSQLiteUpgradeOptions {
/**
* The database name
*/
database?: string;
/**
* The upgrade options for version upgrade
* Array of length 1 to easiest the iOS plugin
*/
upgrade?: capSQLiteVersionUpgrade[];
}
export interface capEchoResult {

@@ -261,2 +283,6 @@ /**

/**
* The database version
*/
version: number;
/**
* Set to true (database encryption) / false

@@ -317,1 +343,7 @@ */

}
export interface capSQLiteVersionUpgrade {
fromVersion: number;
toVersion: number;
statement: string;
set?: capSQLiteSet[];
}
import { WebPlugin } from '@capacitor/core';
import { CapacitorSQLitePlugin, capEchoOptions, capSQLiteOptions, capSQLiteExecuteOptions, capSQLiteSetOptions, capSQLiteRunOptions, capSQLiteQueryOptions, capSQLiteImportOptions, capSQLiteExportOptions, capSQLiteSyncDateOptions, capEchoResult, capSQLiteResult, capSQLiteChanges, capSQLiteValues, capSQLiteJson } from './definitions';
import { CapacitorSQLitePlugin, capEchoOptions, capSQLiteOptions, capSQLiteExecuteOptions, capSQLiteSetOptions, capSQLiteRunOptions, capSQLiteQueryOptions, capSQLiteImportOptions, capSQLiteExportOptions, capSQLiteSyncDateOptions, capEchoResult, capSQLiteResult, capSQLiteChanges, capSQLiteValues, capSQLiteJson, capSQLiteUpgradeOptions } from './definitions';
export declare class CapacitorSQLiteWeb extends WebPlugin implements CapacitorSQLitePlugin {

@@ -19,4 +19,5 @@ constructor();

setSyncDate(options: capSQLiteSyncDateOptions): Promise<capSQLiteResult>;
addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<capSQLiteResult>;
}
declare const CapacitorSQLite: CapacitorSQLiteWeb;
export { CapacitorSQLite };

@@ -102,2 +102,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

}
addUpgradeStatement(options) {
return __awaiter(this, void 0, void 0, function* () {
console.log('addUpgradeStatement', options);
return Promise.reject('Not implemented on Web Platform');
});
}
}

@@ -104,0 +110,0 @@ const CapacitorSQLite = new CapacitorSQLiteWeb();

@@ -104,2 +104,8 @@ var capacitorPlugin = (function (exports, core) {

}
addUpgradeStatement(options) {
return __awaiter(this, void 0, void 0, function* () {
console.log('addUpgradeStatement', options);
return Promise.reject('Not implemented on Web Platform');
});
}
}

@@ -106,0 +112,0 @@ const CapacitorSQLite = new CapacitorSQLiteWeb();

@@ -1,2 +0,2 @@

import { JsonSQLite } from '../definitions';
import { JsonSQLite, capSQLiteVersionUpgrade } from '../definitions';
export declare class DatabaseSQLiteHelper {

@@ -6,4 +6,9 @@ isOpen: boolean;

private _databaseName;
private _databaseVersion;
private _upgradeStatements;
private _alterTables;
private _commonColumns;
private _utils;
constructor(dbName: string);
constructor(dbName: string, dbVersion: number, upgradeStatements: Record<string, Record<number, capSQLiteVersionUpgrade>>);
setup(): Promise<any>;
private _openDB;

@@ -16,2 +21,3 @@ createSyncTable(): Promise<any>;

execSet(set: Array<any>): Promise<any>;
private executeSet;
run(statement: string, values: Array<any>): Promise<any>;

@@ -40,2 +46,19 @@ private prepare;

private getSyncDate;
private getDBVersion;
private updateDatabaseVersion;
private onUpgrade;
private dropTempTables;
private backupTables;
private backupTable;
private dropAll;
private dropTables;
private dropIndexes;
private dropTriggers;
private findCommonColumns;
private getTablesNames;
private updateNewTablesData;
private arraysIntersection;
private backupDB;
private restoreDB;
private isDB;
}

@@ -5,9 +5,12 @@ import { __awaiter } from "tslib";

export class DatabaseSQLiteHelper {
constructor(dbName /*, encrypted:boolean = false, mode:string = "no-encryption",
secret:string = "",newsecret:string=""*/) {
constructor(dbName, dbVersion = 1, upgradeStatements) {
this.isOpen = false;
this.NodeFs = null;
this._alterTables = {};
this._commonColumns = {};
this.NodeFs = require('fs');
this._utils = new UtilsSQLite();
this._databaseName = dbName;
this._databaseVersion = dbVersion;
this._upgradeStatements = upgradeStatements;
// this._encrypted = encrypted;

@@ -17,14 +20,76 @@ // this._mode = mode;

// this._newsecret = newsecret;
this._openDB();
}
setup() {
return __awaiter(this, void 0, void 0, function* () {
yield this._openDB();
});
}
_openDB() {
const db = this._utils.connection(this._databaseName, false /*,this._secret*/);
if (db != null) {
this.isOpen = true;
db.close();
}
else {
this.isOpen = false;
console.log('openDB: Error Database connection failed');
}
return __awaiter(this, void 0, void 0, function* () {
const db = this._utils.connection(this._databaseName, false /*,this._secret*/);
if (db != null) {
this.isOpen = true;
// check if the database got a version
let curVersion = yield this.getDBVersion(db);
console.log('openDB: curVersion ', curVersion);
if (curVersion === -1 || curVersion === 0) {
yield this.updateDatabaseVersion(db, 1);
curVersion = yield this.getDBVersion(db);
console.log('openDB: After updateDatabaseVersion curVersion ', curVersion);
}
// check if the database version is Ok
console.log('openDB: curVersion ' +
curVersion +
' databaseVersion ' +
this._databaseVersion);
console.log('this._databaseName ', this._databaseName);
console.log('this._upgradeStatements ', this._upgradeStatements);
if (curVersion !== this._databaseVersion) {
// version not ok
if (this._databaseVersion < curVersion) {
this.isOpen = false;
console.log('openDB: Error Database version lower than current version');
}
else if (Object.keys(this._upgradeStatements).length === 0 ||
Object.keys(this._upgradeStatements[this._databaseName]).length === 0) {
this.isOpen = false;
console.log('openDB: Error No upgrade statements found for that database');
}
else {
// backup the current version
const backup = yield this.backupDB(this._databaseName);
if (backup) {
// upgrade version process
let res = yield this.onUpgrade(this._databaseName, db, curVersion, this._databaseVersion);
if (res) {
this.isOpen = true;
}
else {
this.isOpen = false;
console.log('openDB: Error Failed on database version ' + 'upgrading');
// restore the old version
const restore = yield this.restoreDB(this._databaseName);
if (!restore) {
console.log('openDB: Error Failed on database version ' + 'restoring');
}
}
}
else {
this.isOpen = false;
console.log('openDB: Error Failed on database version ' + 'backup');
}
// delete the backup file
const retDel = yield this.deleteDB(`backup-${this._databaseName}`);
if (!retDel) {
console.log('openDB: Error Failed on deleting backup ');
}
}
}
db.close();
}
else {
this.isOpen = false;
console.log('openDB: Error Database connection failed');
}
});
}

@@ -69,3 +134,4 @@ createSyncTable() {

const sDate = Math.round(new Date(syncDate).getTime() / 1000);
const stmt = `UPDATE sync_table SET sync_date = ${sDate} WHERE id = 1;`;
let stmt = `UPDATE sync_table SET sync_date = ${sDate} `;
stmt += `WHERE id = 1;`;
const retRes = yield this.execute(db, stmt);

@@ -146,16 +212,7 @@ if (retRes.changes != -1)

}
for (let i = 0; i < set.length; i++) {
const statement = 'statement' in set[i] ? set[i].statement : null;
const values = 'values' in set[i] && set[i].values.length > 0 ? set[i].values : null;
if (statement == null || values == null) {
console.log('execSet: Error statement or values are null');
db.close();
resolve(retRes);
}
lastId = yield this.prepare(db, statement, values);
if (lastId === -1) {
console.log('execSet: Error return lastId= -1');
db.close();
resolve(retRes);
}
retRes = yield this.executeSet(db, set);
if (retRes.changes === -1) {
console.log('executeSet: Error executeSet failed');
db.close();
return retRes;
}

@@ -174,2 +231,30 @@ retB = yield this.endTransaction(db);

}
executeSet(db, set) {
return __awaiter(this, void 0, void 0, function* () {
let lastId = -1;
let retRes = { changes: -1, lastId: lastId };
if (db === null) {
this.isOpen = false;
console.log('executeSet: Error Database connection failed');
return retRes;
}
for (let i = 0; i < set.length; i++) {
const statement = 'statement' in set[i] ? set[i].statement : null;
const values = 'values' in set[i] && set[i].values.length > 0 ? set[i].values : null;
if (statement == null || values == null) {
console.log('executeSet: Error statement or values are null');
return retRes;
}
lastId = yield this.prepare(db, statement, values);
if (lastId === -1) {
console.log('executeSet: Error return lastId= -1');
return retRes;
}
}
const changes = yield this.dbChanges(db);
retRes.changes = changes;
retRes.lastId = lastId;
return retRes;
});
}
run(statement, values) {

@@ -327,2 +412,3 @@ return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {

retJson.database = this._databaseName.slice(0, -9);
retJson.version = this._databaseVersion;
retJson.encrypted = false;

@@ -350,10 +436,17 @@ retJson.mode = mode;

let isIndexes = false;
// set PRAGMA
let pragmas = `
PRAGMA user_version = 1;
PRAGMA foreign_keys = ON;
`;
const pchanges = yield this.exec(pragmas);
const version = jsonData.version;
// set Foreign Keys PRAGMA
let pragmas = 'PRAGMA foreign_keys = ON;';
let pchanges = yield this.exec(pragmas);
if (pchanges === -1)
resolve(-1);
// DROP ALL when mode="full"
if (jsonData.mode === 'full') {
// set User Version PRAGMA
let pragmas = `PRAGMA user_version = ${version};`;
pchanges = yield this.exec(pragmas);
if (pchanges === -1)
resolve(-1);
yield this.dropAll();
}
// create the database schema

@@ -366,4 +459,2 @@ let statements = [];

isSchema = true;
if (jsonData.mode === 'full')
statements.push(`DROP TABLE IF EXISTS ${jsonData.tables[i].name};`);
// create table

@@ -391,3 +482,10 @@ statements.push(`CREATE TABLE IF NOT EXISTS ${jsonData.tables[i].name} (`);

// create trigger last_modified associated with the table
statements.push(`CREATE TRIGGER IF NOT EXISTS ${jsonData.tables[i].name}_trigger_last_modified AFTER UPDATE ON ${jsonData.tables[i].name} FOR EACH ROW WHEN NEW.last_modified <= OLD.last_modified BEGIN UPDATE ${jsonData.tables[i].name} SET last_modified = (strftime('%s','now')) WHERE id=OLD.id; END;`);
let trig = 'CREATE TRIGGER IF NOT EXISTS ';
trig += `${jsonData.tables[i].name}_trigger_last_modified `;
trig += `AFTER UPDATE ON ${jsonData.tables[i].name} `;
trig += 'FOR EACH ROW WHEN NEW.last_modified <= ';
trig += 'OLD.last_modified BEGIN UPDATE ';
trig += `${jsonData.tables[i].name} SET last_modified = `;
trig += "(strftime('%s','now')) WHERE id=OLD.id; END;";
statements.push(trig);
}

@@ -446,3 +544,4 @@ if (jsonData.tables[i].indexes != null &&

if (tableColumnTypes.length === 0) {
console.log(`Error: Table ${jsonData.tables[i].name} info does not exist`);
console.log(`Error: Table ${jsonData.tables[i].name} ` +
'info does not exist');
success = false;

@@ -458,3 +557,4 @@ break;

tableColumnTypes.length) {
console.log(`Error: Table ${jsonData.tables[i].name} values row ${j} not correct length`);
console.log(`Error: Table ${jsonData.tables[i].name} ` +
`values row ${j} not correct length`);
success = false;

@@ -466,3 +566,4 @@ break;

if (!isColumnTypes) {
console.log(`Error: Table ${jsonData.tables[i].name} values row ${j} not correct types`);
console.log(`Error: Table ${jsonData.tables[i].name} ` +
`values row ${j} not correct types`);
success = false;

@@ -478,3 +579,5 @@ break;

const questionMarkString = yield this.createQuestionMarkString(tableColumnNames.length);
stmt = `INSERT INTO ${jsonData.tables[i].name} (${nameString}) VALUES (`;
stmt =
`INSERT INTO ${jsonData.tables[i].name} (` +
`${nameString}) VALUES (`;
stmt += `${questionMarkString});`;

@@ -486,8 +589,11 @@ }

if (setString.length === 0) {
console.log(`Error: Table ${jsonData.tables[i].name} values row ${j} not set to String`);
console.log(`Error: Table ${jsonData.tables[i].name} ` +
`values row ${j} not set to String`);
success = false;
break;
}
stmt = `UPDATE ${jsonData.tables[i].name} SET ${setString} WHERE `;
stmt += `${tableColumnNames[0]} = ${jsonData.tables[i].values[j][0]};`;
stmt =
`UPDATE ${jsonData.tables[i].name} SET ` +
`${setString} WHERE ${tableColumnNames[0]} = ` +
`${jsonData.tables[i].values[j][0]};`;
}

@@ -525,3 +631,4 @@ const lastId = yield this.prepare(db, stmt, jsonData.tables[i].values[j]);

let ret = false;
const query = `SELECT name FROM sqlite_master WHERE type='table' AND name='${tableName}';`;
const query = `SELECT name FROM sqlite_master WHERE ` +
`type='table' AND name='${tableName}';`;
const resQuery = yield this.select(db, query, []);

@@ -602,3 +709,4 @@ if (resQuery.length > 0)

let ret = false;
const query = `SELECT ${firstColumnName} FROM ${dbName} WHERE ${firstColumnName} = ${key};`;
const query = `SELECT ${firstColumnName} FROM ` +
`${dbName} WHERE ${firstColumnName} = ${key};`;
const resQuery = yield this.select(db, query, []);

@@ -651,3 +759,3 @@ if (resQuery.length === 1)

if (err) {
console.log(`exec: Error Begin Transaction failed : ${err.message}`);
console.log(`exec: Error Begin Transaction failed : ` + `${err.message}`);
resolve(false);

@@ -666,3 +774,3 @@ }

if (err) {
console.log(`exec: Error End Transaction failed : ${err.message}`);
console.log(`exec: Error End Transaction failed : ` + `${err.message}`);
resolve(false);

@@ -683,3 +791,3 @@ }

this.isOpen = false;
console.log('createJsonTables: Error Database connection failed');
console.log('createJsonTables: ' + 'Error Database connection failed');
resolve(false);

@@ -689,6 +797,7 @@ }

let stmt = "SELECT name,sql FROM sqlite_master WHERE type = 'table' ";
stmt += "AND name NOT LIKE 'sqlite_%' AND name NOT LIKE 'sync_table';";
stmt += "AND name NOT LIKE 'sqlite_%' ";
stmt += "AND name NOT LIKE 'sync_table';";
let tables = yield this.select(db, stmt, []);
if (tables.length === 0) {
console.log("createJsonTables: Error get table's names failed");
console.log('createJsonTables: ' + "Error get table's names failed");
resolve(false);

@@ -701,7 +810,8 @@ }

if (syncDate != -1) {
// take the tables which have been modified or created since last sync
// take the tables which have been modified or
// created since last sync
modTables = yield this.getTableModified(db, tables, syncDate);
}
else {
console.log('createJsonTables: Error did not find a sync_date');
console.log('createJsonTables: ' + 'Error did not find a sync_date');
resolve(false);

@@ -755,3 +865,4 @@ }

stmt = 'SELECT name,tbl_name,sql FROM sqlite_master WHERE ';
stmt += `type = 'index' AND tbl_name = '${table.name}' AND sql NOTNULL;`;
stmt += `type = 'index' AND tbl_name = '${table.name}' `;
stmt += `AND sql NOTNULL;`;
const retIndexes = yield this.select(db, stmt, []);

@@ -773,3 +884,4 @@ if (retIndexes.length > 0) {

else {
console.log("createJsonTables: Error indexes table name doesn't match");
console.log('createJsonTables: ' +
"Error indexes table name doesn't match");
success = false;

@@ -780,3 +892,3 @@ break;

else {
console.log('createJsonTables: Error in creating indexes');
console.log('createJsonTables: ' + 'Error in creating indexes');
success = false;

@@ -799,3 +911,5 @@ break;

if (syncDate != 0) {
stmt = `SELECT * FROM ${table.name} WHERE last_modified > ${syncDate};`;
stmt =
`SELECT * FROM ${table.name} ` +
`WHERE last_modified > ${syncDate};`;
}

@@ -825,3 +939,3 @@ else {

(!isSchema && !isIndexes && !isValues)) {
console.log('createJsonTables: Error table is not a jsonTable');
console.log('createJsonTables: ' + 'Error table is not a jsonTable');
success = false;

@@ -853,3 +967,5 @@ break;

// get total count of modified since last sync
stmt = `SELECT count(*) FROM ${tables[i].name} WHERE last_modified > ${syncDate};`;
stmt =
`SELECT count(*) FROM ${tables[i].name} ` +
`WHERE last_modified > ${syncDate};`;
retQuery = yield this.select(db, stmt, []);

@@ -890,3 +1006,468 @@ if (retQuery.length != 1)

}
getDBVersion(db) {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
const query = `PRAGMA user_version;`;
const resQuery = yield this.select(db, query, []);
if (resQuery.length > 0) {
return resolve(resQuery[0].user_version);
}
else {
return resolve(-1);
}
}));
}
updateDatabaseVersion(db, newVersion) {
return __awaiter(this, void 0, void 0, function* () {
let pragmas = `
PRAGMA user_version = ${newVersion};
`;
const pchanges = yield this.execute(db, pragmas);
return pchanges;
});
}
onUpgrade(dbName, db, currentVersion, targetVersion) {
return __awaiter(this, void 0, void 0, function* () {
/**
* When upgrade statements for current database are missing
*/
if (!this._upgradeStatements[dbName]) {
console.log(`Error PRAGMA user_version failed : Version mismatch! Expec
ted Version ${targetVersion} found Version ${currentVersion}. Mi
ssing Upgrade Statements for Database '${dbName}' Vers
ion ${currentVersion}.`);
return false;
}
else if (!this._upgradeStatements[dbName][currentVersion]) {
/**
* When upgrade statements for current version are missing
*/
console.log(`Error PRAGMA user_version failed : Version mismatch! Expected V
ersion ${targetVersion} found Version ${currentVersion}. Miss
ing Upgrade Statements for Database '${dbName}' Versi
on ${currentVersion}.`);
return false;
}
const upgrade = this._upgradeStatements[dbName][currentVersion];
/**
* When the version after an upgrade would be greater
* than the targeted version
*/
if (targetVersion < upgrade.toVersion) {
console.log(`Error PRAGMA user_version failed : Version mismatch! Expect
ed Version ${targetVersion} found Version ${currentVersion}. Up
grade Statement would upgrade to version ${upgrade.toVersion}, b
ut target version is ${targetVersion}.`);
return false;
}
// set PRAGMA
let pragmas = `
PRAGMA foreign_keys = OFF;
`;
let pchanges = yield this.execute(db, pragmas);
if (pchanges === -1) {
console.log('onUpgrade: Error in setting ' + 'PRAGMA foreign_keys = OFF');
return false;
}
// Here we assume all the tables schema are given in
// the upgrade statement
if (upgrade.statement) {
// -> backup all existing tables "tableName" in "temp_tableName"
let retB = yield this.backupTables(db);
if (!retB) {
console.log('onUpgrade Error in backuping existing tables');
return false;
}
// -> Drop all Indexes
retB = yield this.dropIndexes(db);
if (!retB) {
console.log('onUpgrade Error in dropping indexes');
return false;
}
// -> Drop all Triggers
retB = yield this.dropTriggers(db);
if (!retB) {
console.log('onUpgrade Error in dropping triggers');
return false;
}
// -> Create new tables from upgrade.statement
const result = yield this.execute(db, upgrade.statement);
if (result.changes < 0) {
console.log(`onUpgrade Error in creating tables `);
return false;
}
// -> Create the list of table's common fields
retB = yield this.findCommonColumns(db);
if (!retB) {
console.log('onUpgrade Error in findCommonColumns');
return false;
}
// -> Update the new table's data from old table's data
retB = yield this.updateNewTablesData(db);
if (!retB) {
console.log('onUpgrade Error in updateNewTablesData');
return false;
}
// -> Drop _temp_tables
retB = yield this.dropTempTables(db);
if (!retB) {
console.log('onUpgrade Error in dropTempTables');
return false;
}
// -> Do some cleanup
this._alterTables = {};
this._commonColumns = {};
// here we assume that the Set contains only
// - the data for new tables as INSERT statements
// - the data for new columns in existing tables
// as UPDATE statements
if (upgrade.set) {
// -> load new data
const result = yield this.executeSet(db, upgrade.set);
if (result.changes < 0) {
console.log('onUpgrade Error executeSet Failed');
return false;
}
}
// -> update database version
yield this.updateDatabaseVersion(db, upgrade.toVersion);
// -> update syncDate if any
const isExists = yield this.isTableExists(db, 'sync_table');
if (isExists) {
const sDate = Math.round(new Date().getTime() / 1000);
let stmt = `UPDATE sync_table SET sync_date = ${sDate} `;
stmt += `WHERE id = 1;`;
const retRes = yield this.execute(db, stmt);
if (retRes.changes === -1) {
let message = 'onUpgrade: Update sync_date failed ';
console.log(message);
return false;
}
}
}
else {
let message = 'onUpgrade: No statement given in ';
message += 'upgradeStatements object';
console.log(message);
return false;
}
// set PRAGMA
pragmas = `
PRAGMA foreign_keys = ON;
`;
pchanges = yield this.execute(db, pragmas);
if (pchanges === -1) {
console.log('onUpgrade: Error in setting ' + 'PRAGMA foreign_keys = ON');
return false;
}
return true;
});
}
dropTempTables(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
const tempTables = Object.keys(this._alterTables);
const statements = [];
for (let i = 0; i < tempTables.length; i++) {
const stmt = `DROP TABLE IF EXISTS _temp_${tempTables[i]};`;
statements.push(stmt);
}
const pchanges = yield this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropTempTables: Error execute failed');
resolve(false);
}
resolve(true);
}));
});
}
backupTables(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
const tables = yield this.getTablesNames(db);
if (tables.length === 0) {
console.log("backupTables: Error get table's names failed");
resolve(false);
}
for (let i = 0; i < tables.length; i++) {
const retB = yield this.backupTable(db, tables[i].name);
if (!retB) {
console.log('backupTables: Error backupTable failed');
resolve(false);
}
}
resolve(true);
}));
});
}
backupTable(db, tableName) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
let retB = yield this.beginTransaction(db);
if (!retB) {
console.log('backupTable: Error beginTransaction failed');
resolve(false);
}
// get the column's name
const tableNamesTypes = yield this.getTableColumnNamesTypes(db, tableName);
this._alterTables[tableName] = tableNamesTypes.names;
// prefix the table with _temp_
let stmt = `ALTER TABLE ${tableName} RENAME TO _temp_${tableName};`;
const pchanges = yield this.execute(db, stmt);
if (pchanges.changes === -1) {
console.log('backupTable: Error execute failed');
resolve(false);
}
retB = yield this.endTransaction(db);
if (!retB) {
console.log('backupTable: Error endTransaction failed');
resolve(false);
}
resolve(true);
}));
});
}
dropAll() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
// Drop All Tables
const db = this._utils.connection(this._databaseName, false /*,this._secret*/);
if (db === null) {
this.isOpen = false;
console.log('dropAll: Error Database connection failed');
resolve(false);
}
let retB = yield this.dropTables(db);
if (!retB)
resolve(false);
// Drop All Indexes
retB = yield this.dropIndexes(db);
if (!retB)
resolve(false);
// Drop All Triggers
retB = yield this.dropTriggers(db);
if (!retB)
resolve(false);
// VACCUUM
yield this.execute(db, 'VACUUM;');
db.close();
return true;
}));
});
}
dropTables(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
// get the table's names
const tables = yield this.getTablesNames(db);
let statements = [];
for (let i = 0; i < tables.length; i++) {
const stmt = `DROP TABLE IF EXISTS ${tables[i].name};`;
statements.push(stmt);
}
if (statements.length > 0) {
const pchanges = yield this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropTables: Error execute failed');
resolve(false);
}
}
resolve(true);
}));
});
}
dropIndexes(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
// get the index's names
let stmt = "SELECT name FROM sqlite_master WHERE type = 'index' ";
stmt += "AND name NOT LIKE 'sqlite_%';";
let indexes = yield this.select(db, stmt, []);
if (indexes.length === 0) {
console.log("dropIndexes: Error get index's names failed");
resolve(false);
}
let statements = [];
for (let i = 0; i < indexes.length; i++) {
const stmt = `DROP INDEX IF EXISTS ${indexes[i].name};`;
statements.push(stmt);
}
if (statements.length > 0) {
const pchanges = yield this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropIndexes: Error execute failed');
resolve(false);
}
}
resolve(true);
}));
});
}
dropTriggers(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
// get the index's names
let stmt = "SELECT name FROM sqlite_master WHERE type = 'trigger';";
let triggers = yield this.select(db, stmt, []);
if (triggers.length === 0) {
console.log("dropTriggers: Error get index's names failed");
resolve(false);
}
let statements = [];
for (let i = 0; i < triggers.length; i++) {
let stmt = 'DROP TRIGGER IF EXISTS ';
stmt += `${triggers[i].name};`;
statements.push(stmt);
}
if (statements.length > 0) {
const pchanges = yield this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropTriggers: Error execute failed');
resolve(false);
}
}
resolve(true);
}));
});
}
findCommonColumns(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
// Get new table list
const tables = yield this.getTablesNames(db);
if (tables.length === 0) {
console.log("findCommonColumns: Error get table's names failed");
resolve(false);
}
for (let i = 0; i < tables.length; i++) {
// get the column's name
const tableNamesTypes = yield this.getTableColumnNamesTypes(db, tables[i].name);
// find the common columns
const keys = Object.keys(this._alterTables);
if (keys.includes(tables[i].name)) {
this._commonColumns[tables[i].name] = this.arraysIntersection(this._alterTables[tables[i].name], tableNamesTypes.names);
}
}
resolve(true);
}));
});
}
getTablesNames(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
// get the table's names
let stmt = "SELECT name FROM sqlite_master WHERE type = 'table' ";
stmt += "AND name NOT LIKE 'sync_table' ";
stmt += "AND name NOT LIKE '_temp_%' ";
stmt += "AND name NOT LIKE 'sqlite_%';";
const tables = yield this.select(db, stmt, []);
resolve(tables);
}));
});
}
updateNewTablesData(db) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
let retB = yield this.beginTransaction(db);
if (!retB) {
console.log('updateNewTablesData: ' + 'Error beginTransaction failed');
resolve(false);
}
let statements = [];
const keys = Object.keys(this._commonColumns);
keys.forEach(key => {
const columns = this._commonColumns[key].join(',');
let stmt = `INSERT INTO ${key} (${columns}) SELECT `;
stmt += `${columns} FROM _temp_${key};`;
statements.push(stmt);
});
const pchanges = yield this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('updateNewTablesData: Error execute failed');
resolve(false);
}
retB = yield this.endTransaction(db);
if (!retB) {
console.log('updateNewTablesData: ' + 'Error endTransaction failed');
resolve(false);
}
resolve(true);
}));
});
}
arraysIntersection(a1, a2) {
return a1.filter((n) => {
return a2.indexOf(n) !== -1;
});
}
backupDB(dbName) {
return new Promise(resolve => {
const dbPath = this._utils.getDBPath(dbName);
const dbBackupPath = this._utils.getDBPath(`backup-${dbName}`);
if (dbPath.length > 0 && dbBackupPath.length > 0) {
this.NodeFs.copyFile(dbPath, dbBackupPath, this.NodeFs.constants.COPYFILE_EXCL, (err) => {
if (err) {
console.log('Error: in backupDB Found:', err);
resolve(false);
}
else {
resolve(true);
}
});
}
else {
console.log('Error: in backupDB path & backuppath not correct');
resolve(false);
}
});
}
restoreDB(dbName) {
return new Promise(resolve => {
const dbPath = this._utils.getDBPath(dbName);
const dbBackupPath = this._utils.getDBPath(`backup-${dbName}`);
if (dbPath.length > 0 && dbBackupPath.length > 0) {
const isBackup = this.isDB(dbBackupPath);
if (!isBackup) {
console.log('Error: in restoreDB no backup database');
resolve(false);
}
const isFile = this.isDB(dbPath);
if (isFile) {
try {
this.NodeFs.unlinkSync(dbPath);
//file removed
}
catch (e) {
console.log('Error: in restoreDB delete database failed');
resolve(false);
}
}
this.NodeFs.copyFile(dbBackupPath, dbPath, this.NodeFs.constants.COPYFILE_EXCL, (err) => {
if (err) {
console.log('Error: in restoreDB copyfile failed:', err);
resolve(false);
}
else {
resolve(true);
}
});
}
else {
console.log('Error: in backupDB path & backuppath not correct');
resolve(false);
}
});
}
isDB(dbPath) {
try {
if (this.NodeFs.existsSync(dbPath)) {
//file exists
return true;
}
}
catch (err) {
console.error(err);
return false;
}
}
}
//# sourceMappingURL=DatabaseSQLiteHelper.js.map

@@ -5,2 +5,3 @@ /* JSON function */

'database',
'version',
'encrypted',

@@ -18,2 +19,4 @@ 'mode',

return false;
if (key === 'version' && typeof obj[key] != 'number')
return false;
if (key === 'encrypted' && typeof obj[key] != 'boolean')

@@ -20,0 +23,0 @@ return false;

import { WebPlugin } from '@capacitor/core';
import { CapacitorSQLitePlugin, capEchoOptions, capSQLiteOptions, capSQLiteExecuteOptions, capSQLiteSetOptions, capSQLiteRunOptions, capSQLiteQueryOptions, capSQLiteImportOptions, capSQLiteExportOptions, capSQLiteSyncDateOptions, capEchoResult, capSQLiteResult, capSQLiteChanges, capSQLiteValues, capSQLiteJson } from './definitions';
import { CapacitorSQLitePlugin, capEchoOptions, capSQLiteOptions, capSQLiteExecuteOptions, capSQLiteSetOptions, capSQLiteRunOptions, capSQLiteQueryOptions, capSQLiteImportOptions, capSQLiteExportOptions, capSQLiteSyncDateOptions, capEchoResult, capSQLiteResult, capSQLiteChanges, capSQLiteValues, capSQLiteJson, capSQLiteUpgradeOptions } from './definitions';
export declare class CapacitorSQLiteElectronWeb extends WebPlugin implements CapacitorSQLitePlugin {

@@ -7,2 +7,3 @@ NodeFs: any;

private mDb;
private versionUpgrades;
constructor();

@@ -23,4 +24,5 @@ echo(options: capEchoOptions): Promise<capEchoResult>;

setSyncDate(options: capSQLiteSyncDateOptions): Promise<capSQLiteResult>;
addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<capSQLiteResult>;
}
declare const CapacitorSQLite: CapacitorSQLiteElectronWeb;
export { CapacitorSQLite };

@@ -15,2 +15,3 @@ import { __awaiter } from "tslib";

this.RemoteRef = null;
this.versionUpgrades = {};
console.log('CapacitorSQLite Electron');

@@ -28,2 +29,3 @@ this.RemoteRef = remote;

open(options) {
var _a;
return __awaiter(this, void 0, void 0, function* () {

@@ -37,2 +39,3 @@ if (typeof options.database === 'undefined') {

const dbName = options.database;
const dbVersion = (_a = options.version) !== null && _a !== void 0 ? _a : 1;
/*

@@ -44,5 +47,7 @@ let encrypted: boolean = options.encrypted ? options.encrypted : false;

*/
this.mDb = new DatabaseSQLiteHelper(`${dbName}SQLite.db` /*,encrypted,inMode,secretKey,newsecretKey*/);
console.log('---> in Open this.versionUpgrades ' + this.versionUpgrades);
this.mDb = new DatabaseSQLiteHelper(`${dbName}SQLite.db`, dbVersion, this.versionUpgrades /*,encrypted,inMode,secretKey,newsecretKey*/);
yield this.mDb.setup();
if (!this.mDb.isOpen) {
return Promise.reject({
return Promise.resolve({
result: false,

@@ -52,3 +57,5 @@ message: `Open command failed: Database ${dbName}SQLite.db not opened`,

}
return Promise.resolve({ result: true });
else {
return Promise.resolve({ result: true });
}
});

@@ -247,2 +254,3 @@ }

importFromJson(options) {
var _a;
return __awaiter(this, void 0, void 0, function* () {

@@ -267,3 +275,5 @@ const retRes = { changes: -1 };

const dbName = `${jsonObj.database}SQLite.db`;
this.mDb = new DatabaseSQLiteHelper(dbName);
const dbVersion = (_a = jsonObj.version) !== null && _a !== void 0 ? _a : 1;
this.mDb = new DatabaseSQLiteHelper(dbName, dbVersion, {});
yield this.mDb.setup();
const ret = yield this.mDb.importJson(jsonObj);

@@ -316,2 +326,42 @@ this.mDb.close(dbName);

}
addUpgradeStatement(options) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof options.database === 'undefined' ||
typeof options.database != 'string') {
return Promise.reject({
result: false,
message: 'Must provide a database name',
});
}
if (typeof options.upgrade[0] === 'undefined') {
return Promise.reject({
result: false,
message: 'Must provide an upgrade Object',
});
}
const upgrade = options.upgrade[0];
const keys = Object.keys(upgrade);
if (!keys.includes('fromVersion') ||
!keys.includes('toVersion') ||
!keys.includes('statement')) {
return Promise.reject({
result: false,
message: 'Must provide an upgrade capSQLiteVersionUpgrade Object',
});
}
const fullDBName = `${options.database}SQLite.db`;
if (!this.versionUpgrades[fullDBName]) {
this.versionUpgrades[fullDBName] = {};
}
this.versionUpgrades[fullDBName][upgrade.fromVersion] = {
fromVersion: upgrade.fromVersion,
toVersion: upgrade.toVersion,
statement: upgrade.statement,
};
if (upgrade.set)
this.versionUpgrades[fullDBName][upgrade.fromVersion]['set'] =
upgrade.set;
return Promise.resolve({ result: true });
});
}
}

@@ -318,0 +368,0 @@ const CapacitorSQLite = new CapacitorSQLiteElectronWeb();

@@ -10,3 +10,3 @@ declare module '@capacitor/core' {

*
* @param options The echo options
* @param options: capEchoOptions
* @return Promise<{ value: string }

@@ -18,4 +18,4 @@ * @since 0.0.1

* Open a SQLite database
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 0.0.1

@@ -26,4 +26,4 @@ */

* Close a SQLite database
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 0.0.1

@@ -34,4 +34,4 @@ */

* Execute a Batch of Raw Statements as String
* @param {capSQLiteExecuteOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteExecuteOptions
* @returns Promise<capSQLiteChanges>
* @since 0.0.1

@@ -42,4 +42,4 @@ */

* Execute a Set of Raw Statements as Array of CapSQLiteSet
* @param {capSQLiteSetOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteSetOptions
* @returns Promise<capSQLiteChanges>
* @since 2.2.0-2

@@ -50,4 +50,4 @@ */

* Execute a Single Statement
* @param {capSQLiteRunOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteRunOptions
* @returns Promise<capSQLiteChanges>
* @since 0.0.1

@@ -58,4 +58,4 @@ */

* Query a Single Statement
* @param {capSQLiteQueryOptions} options
* @returns {Promise<capSQLiteValues>}
* @param options: capSQLiteQueryOptions
* @returns Promise<capSQLiteValues>
* @since 0.0.1

@@ -66,4 +66,4 @@ */

* Check is a SQLite database exists
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 2.0.1-1

@@ -74,4 +74,4 @@ */

* Delete a SQLite database
* @param {capSQLiteOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteOptions
* @returns Promise<capSQLiteResult>
* @since 0.0.1

@@ -82,4 +82,4 @@ */

* Is Json Object Valid
* @param {capSQLiteImportOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteImportOptions
* @returns Promise<capSQLiteResult>
* @since 2.0.1-1

@@ -90,4 +90,4 @@ */

* Import from Json Object
* @param {capSQLiteImportOptions} options
* @returns {Promise<capSQLiteChanges>}
* @param options: capSQLiteImportOptions
* @returns Promise<capSQLiteChanges>
* @since 2.0.0-3

@@ -98,4 +98,4 @@ */

* Export to Json Object
* @param {capSQLiteExportOptions} options
* @returns {Promise<capSQLiteJson>}
* @param options: capSQLiteExportOptions
* @returns Promise<capSQLiteJson>
* @since 2.0.1-1

@@ -106,3 +106,3 @@ */

* Create a synchronization table
* @returns {Promise<capSQLiteChanges>}
* @returns Promise<capSQLiteChanges>
* @since 2.0.1-1

@@ -113,7 +113,14 @@ */

* Set the synchronization date
* @param {capSQLiteSyncDateOptions} options
* @returns {Promise<capSQLiteResult>}
* @param options: capSQLiteSyncDateOptions
* @returns Promise<capSQLiteResult>
* @since 2.0.1-1
*/
setSyncDate(options: capSQLiteSyncDateOptions): Promise<capSQLiteResult>;
/**
* Add the upgrade Statement for database version upgrading
* @param options: capSQLiteUpgradeOptions
* @returns Promise<capSQLiteResult>
* @since 2.4.2-6 iOS & Electron
*/
addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<capSQLiteResult>;
}

@@ -132,2 +139,6 @@ export interface capEchoOptions {

/**
* The database version
*/
version?: number;
/**
* Set to true (database encryption) / false

@@ -208,2 +219,13 @@ * - Open method only

}
export interface capSQLiteUpgradeOptions {
/**
* The database name
*/
database?: string;
/**
* The upgrade options for version upgrade
* Array of length 1 to easiest the iOS plugin
*/
upgrade?: capSQLiteVersionUpgrade[];
}
export interface capEchoResult {

@@ -261,2 +283,6 @@ /**

/**
* The database version
*/
version: number;
/**
* Set to true (database encryption) / false

@@ -317,1 +343,7 @@ */

}
export interface capSQLiteVersionUpgrade {
fromVersion: number;
toVersion: number;
statement: string;
set?: capSQLiteSet[];
}
import { UtilsSQLite } from './UtilsSQLite';
import { JsonSQLite, JsonTable, JsonColumn, JsonIndex } from '../definitions';
import {
JsonSQLite,
JsonTable,
JsonColumn,
JsonIndex,
capSQLiteVersionUpgrade,
} from '../definitions';
import { isJsonSQLite, isTable } from './JsonUtils';

@@ -11,2 +16,9 @@

private _databaseName: string;
private _databaseVersion: number;
private _upgradeStatements: Record<
string,
Record<number, capSQLiteVersionUpgrade>
>;
private _alterTables: Record<string, Array<string>> = {};
private _commonColumns: Record<string, Array<string>> = {};
// private _encrypted: boolean;

@@ -19,4 +31,8 @@ // private _mode: string;

constructor(
dbName: string /*, encrypted:boolean = false, mode:string = "no-encryption",
secret:string = "",newsecret:string=""*/,
dbName: string,
dbVersion = 1,
upgradeStatements: Record<string, Record<number, capSQLiteVersionUpgrade>>,
/*, encrypted:boolean = false, mode:string = "no-encryption",
secret:string = "",newsecret:string=""*/
) {

@@ -26,2 +42,4 @@ this.NodeFs = require('fs');

this._databaseName = dbName;
this._databaseVersion = dbVersion;
this._upgradeStatements = upgradeStatements;
// this._encrypted = encrypted;

@@ -31,5 +49,8 @@ // this._mode = mode;

// this._newsecret = newsecret;
this._openDB();
}
private _openDB() {
public async setup(): Promise<any> {
await this._openDB();
}
private async _openDB() {
const db = this._utils.connection(

@@ -41,2 +62,74 @@ this._databaseName,

this.isOpen = true;
// check if the database got a version
let curVersion: number = await this.getDBVersion(db);
console.log('openDB: curVersion ', curVersion);
if (curVersion === -1 || curVersion === 0) {
await this.updateDatabaseVersion(db, 1);
curVersion = await this.getDBVersion(db);
console.log(
'openDB: After updateDatabaseVersion curVersion ',
curVersion,
);
}
// check if the database version is Ok
console.log(
'openDB: curVersion ' +
curVersion +
' databaseVersion ' +
this._databaseVersion,
);
console.log('this._databaseName ', this._databaseName);
console.log('this._upgradeStatements ', this._upgradeStatements);
if (curVersion !== this._databaseVersion) {
// version not ok
if (this._databaseVersion < curVersion) {
this.isOpen = false;
console.log(
'openDB: Error Database version lower than current version',
);
} else if (
Object.keys(this._upgradeStatements).length === 0 ||
Object.keys(this._upgradeStatements[this._databaseName]).length === 0
) {
this.isOpen = false;
console.log(
'openDB: Error No upgrade statements found for that database',
);
} else {
// backup the current version
const backup: boolean = await this.backupDB(this._databaseName);
if (backup) {
// upgrade version process
let res: boolean = await this.onUpgrade(
this._databaseName,
db,
curVersion,
this._databaseVersion,
);
if (res) {
this.isOpen = true;
} else {
this.isOpen = false;
console.log(
'openDB: Error Failed on database version ' + 'upgrading',
);
// restore the old version
const restore: boolean = await this.restoreDB(this._databaseName);
if (!restore) {
console.log(
'openDB: Error Failed on database version ' + 'restoring',
);
}
}
} else {
this.isOpen = false;
console.log('openDB: Error Failed on database version ' + 'backup');
}
// delete the backup file
const retDel = await this.deleteDB(`backup-${this._databaseName}`);
if (!retDel) {
console.log('openDB: Error Failed on deleting backup ');
}
}
}
db.close();

@@ -92,3 +185,4 @@ } else {

const sDate: number = Math.round(new Date(syncDate).getTime() / 1000);
const stmt: string = `UPDATE sync_table SET sync_date = ${sDate} WHERE id = 1;`;
let stmt: string = `UPDATE sync_table SET sync_date = ${sDate} `;
stmt += `WHERE id = 1;`;
const retRes = await this.execute(db, stmt);

@@ -173,17 +267,7 @@ if (retRes.changes != -1) ret = true;

}
for (let i = 0; i < set.length; i++) {
const statement = 'statement' in set[i] ? set[i].statement : null;
const values =
'values' in set[i] && set[i].values.length > 0 ? set[i].values : null;
if (statement == null || values == null) {
console.log('execSet: Error statement or values are null');
db.close();
resolve(retRes);
}
lastId = await this.prepare(db, statement, values);
if (lastId === -1) {
console.log('execSet: Error return lastId= -1');
db.close();
resolve(retRes);
}
retRes = await this.executeSet(db, set);
if (retRes.changes === -1) {
console.log('executeSet: Error executeSet failed');
db.close();
return retRes;
}

@@ -203,2 +287,31 @@

}
private async executeSet(db: any, set: Array<any>): Promise<any> {
let lastId: number = -1;
let retRes: any = { changes: -1, lastId: lastId };
if (db === null) {
this.isOpen = false;
console.log('executeSet: Error Database connection failed');
return retRes;
}
for (let i = 0; i < set.length; i++) {
const statement = 'statement' in set[i] ? set[i].statement : null;
const values =
'values' in set[i] && set[i].values.length > 0 ? set[i].values : null;
if (statement == null || values == null) {
console.log('executeSet: Error statement or values are null');
return retRes;
}
lastId = await this.prepare(db, statement, values);
if (lastId === -1) {
console.log('executeSet: Error return lastId= -1');
return retRes;
}
}
const changes = await this.dbChanges(db);
retRes.changes = changes;
retRes.lastId = lastId;
return retRes;
}
public run(statement: string, values: Array<any>): Promise<any> {

@@ -372,2 +485,3 @@ return new Promise(async resolve => {

retJson.database = this._databaseName.slice(0, -9);
retJson.version = this._databaseVersion;
retJson.encrypted = false;

@@ -394,10 +508,16 @@ retJson.mode = mode;

let isIndexes: boolean = false;
// set PRAGMA
let pragmas: string = `
PRAGMA user_version = 1;
PRAGMA foreign_keys = ON;
`;
const pchanges: number = await this.exec(pragmas);
const version: number = jsonData.version;
// set Foreign Keys PRAGMA
let pragmas: string = 'PRAGMA foreign_keys = ON;';
let pchanges: number = await this.exec(pragmas);
if (pchanges === -1) resolve(-1);
// DROP ALL when mode="full"
if (jsonData.mode === 'full') {
// set User Version PRAGMA
let pragmas: string = `PRAGMA user_version = ${version};`;
pchanges = await this.exec(pragmas);
if (pchanges === -1) resolve(-1);
await this.dropAll();
}
// create the database schema

@@ -412,4 +532,2 @@ let statements: Array<string> = [];

isSchema = true;
if (jsonData.mode === 'full')
statements.push(`DROP TABLE IF EXISTS ${jsonData.tables[i].name};`);
// create table

@@ -452,5 +570,10 @@ statements.push(

// create trigger last_modified associated with the table
statements.push(
`CREATE TRIGGER IF NOT EXISTS ${jsonData.tables[i].name}_trigger_last_modified AFTER UPDATE ON ${jsonData.tables[i].name} FOR EACH ROW WHEN NEW.last_modified <= OLD.last_modified BEGIN UPDATE ${jsonData.tables[i].name} SET last_modified = (strftime('%s','now')) WHERE id=OLD.id; END;`,
);
let trig: string = 'CREATE TRIGGER IF NOT EXISTS ';
trig += `${jsonData.tables[i].name}_trigger_last_modified `;
trig += `AFTER UPDATE ON ${jsonData.tables[i].name} `;
trig += 'FOR EACH ROW WHEN NEW.last_modified <= ';
trig += 'OLD.last_modified BEGIN UPDATE ';
trig += `${jsonData.tables[i].name} SET last_modified = `;
trig += "(strftime('%s','now')) WHERE id=OLD.id; END;";
statements.push(trig);
}

@@ -532,3 +655,4 @@ if (

console.log(
`Error: Table ${jsonData.tables[i].name} info does not exist`,
`Error: Table ${jsonData.tables[i].name} ` +
'info does not exist',
);

@@ -551,3 +675,4 @@ success = false;

console.log(
`Error: Table ${jsonData.tables[i].name} values row ${j} not correct length`,
`Error: Table ${jsonData.tables[i].name} ` +
`values row ${j} not correct length`,
);

@@ -564,3 +689,4 @@ success = false;

console.log(
`Error: Table ${jsonData.tables[i].name} values row ${j} not correct types`,
`Error: Table ${jsonData.tables[i].name} ` +
`values row ${j} not correct types`,
);

@@ -586,3 +712,5 @@ success = false;

);
stmt = `INSERT INTO ${jsonData.tables[i].name} (${nameString}) VALUES (`;
stmt =
`INSERT INTO ${jsonData.tables[i].name} (` +
`${nameString}) VALUES (`;
stmt += `${questionMarkString});`;

@@ -596,3 +724,4 @@ } else {

console.log(
`Error: Table ${jsonData.tables[i].name} values row ${j} not set to String`,
`Error: Table ${jsonData.tables[i].name} ` +
`values row ${j} not set to String`,
);

@@ -602,6 +731,6 @@ success = false;

}
stmt = `UPDATE ${jsonData.tables[i].name} SET ${setString} WHERE `;
stmt += `${tableColumnNames[0]} = ${
jsonData.tables[i].values![j][0]
};`;
stmt =
`UPDATE ${jsonData.tables[i].name} SET ` +
`${setString} WHERE ${tableColumnNames[0]} = ` +
`${jsonData.tables[i].values![j][0]};`;
}

@@ -642,3 +771,5 @@ const lastId: number = await this.prepare(

let ret: boolean = false;
const query: string = `SELECT name FROM sqlite_master WHERE type='table' AND name='${tableName}';`;
const query: string =
`SELECT name FROM sqlite_master WHERE ` +
`type='table' AND name='${tableName}';`;
const resQuery: Array<any> = await this.select(db, query, []);

@@ -718,3 +849,5 @@ if (resQuery.length > 0) ret = true;

let ret: boolean = false;
const query: string = `SELECT ${firstColumnName} FROM ${dbName} WHERE ${firstColumnName} = ${key};`;
const query: string =
`SELECT ${firstColumnName} FROM ` +
`${dbName} WHERE ${firstColumnName} = ${key};`;
const resQuery: Array<any> = await this.select(db, query, []);

@@ -765,3 +898,5 @@ if (resQuery.length === 1) ret = true;

if (err) {
console.log(`exec: Error Begin Transaction failed : ${err.message}`);
console.log(
`exec: Error Begin Transaction failed : ` + `${err.message}`,
);
resolve(false);

@@ -779,3 +914,5 @@ } else {

if (err) {
console.log(`exec: Error End Transaction failed : ${err.message}`);
console.log(
`exec: Error End Transaction failed : ` + `${err.message}`,
);
resolve(false);

@@ -795,3 +932,3 @@ } else {

this.isOpen = false;
console.log('createJsonTables: Error Database connection failed');
console.log('createJsonTables: ' + 'Error Database connection failed');
resolve(false);

@@ -802,6 +939,7 @@ }

"SELECT name,sql FROM sqlite_master WHERE type = 'table' ";
stmt += "AND name NOT LIKE 'sqlite_%' AND name NOT LIKE 'sync_table';";
stmt += "AND name NOT LIKE 'sqlite_%' ";
stmt += "AND name NOT LIKE 'sync_table';";
let tables: Array<any> = await this.select(db, stmt, []);
if (tables.length === 0) {
console.log("createJsonTables: Error get table's names failed");
console.log('createJsonTables: ' + "Error get table's names failed");
resolve(false);

@@ -814,10 +952,10 @@ }

if (syncDate != -1) {
// take the tables which have been modified or created since last sync
// take the tables which have been modified or
// created since last sync
modTables = await this.getTableModified(db, tables, syncDate);
} else {
console.log('createJsonTables: Error did not find a sync_date');
console.log('createJsonTables: ' + 'Error did not find a sync_date');
resolve(false);
}
}
let jsonTables: Array<JsonTable> = [];

@@ -871,3 +1009,4 @@ for (let i: number = 0; i < tables.length; i++) {

stmt = 'SELECT name,tbl_name,sql FROM sqlite_master WHERE ';
stmt += `type = 'index' AND tbl_name = '${table.name}' AND sql NOTNULL;`;
stmt += `type = 'index' AND tbl_name = '${table.name}' `;
stmt += `AND sql NOTNULL;`;
const retIndexes: Array<any> = await this.select(db, stmt, []);

@@ -889,3 +1028,4 @@ if (retIndexes.length > 0) {

console.log(
"createJsonTables: Error indexes table name doesn't match",
'createJsonTables: ' +
"Error indexes table name doesn't match",
);

@@ -896,3 +1036,3 @@ success = false;

} else {
console.log('createJsonTables: Error in creating indexes');
console.log('createJsonTables: ' + 'Error in creating indexes');
success = false;

@@ -920,3 +1060,5 @@ break;

if (syncDate != 0) {
stmt = `SELECT * FROM ${table.name} WHERE last_modified > ${syncDate};`;
stmt =
`SELECT * FROM ${table.name} ` +
`WHERE last_modified > ${syncDate};`;
} else {

@@ -946,3 +1088,3 @@ stmt = `SELECT * FROM ${table.name};`;

) {
console.log('createJsonTables: Error table is not a jsonTable');
console.log('createJsonTables: ' + 'Error table is not a jsonTable');
success = false;

@@ -977,3 +1119,5 @@ break;

// get total count of modified since last sync
stmt = `SELECT count(*) FROM ${tables[i].name} WHERE last_modified > ${syncDate};`;
stmt =
`SELECT count(*) FROM ${tables[i].name} ` +
`WHERE last_modified > ${syncDate};`;
retQuery = await this.select(db, stmt, []);

@@ -1010,2 +1154,489 @@ if (retQuery.length != 1) break;

}
private getDBVersion(db: any): Promise<number> {
return new Promise(async resolve => {
const query = `PRAGMA user_version;`;
const resQuery: Array<any> = await this.select(db, query, []);
if (resQuery.length > 0) {
return resolve(resQuery[0].user_version);
} else {
return resolve(-1);
}
});
}
private async updateDatabaseVersion(
db: any,
newVersion: number,
): Promise<number> {
let pragmas: string = `
PRAGMA user_version = ${newVersion};
`;
const pchanges: number = await this.execute(db, pragmas);
return pchanges;
}
private async onUpgrade(
dbName: string,
db: any,
currentVersion: number,
targetVersion: number,
): Promise<boolean> {
/**
* When upgrade statements for current database are missing
*/
if (!this._upgradeStatements[dbName]) {
console.log(
`Error PRAGMA user_version failed : Version mismatch! Expec
ted Version ${targetVersion} found Version ${currentVersion}. Mi
ssing Upgrade Statements for Database '${dbName}' Vers
ion ${currentVersion}.`,
);
return false;
} else if (!this._upgradeStatements[dbName][currentVersion]) {
/**
* When upgrade statements for current version are missing
*/
console.log(
`Error PRAGMA user_version failed : Version mismatch! Expected V
ersion ${targetVersion} found Version ${currentVersion}. Miss
ing Upgrade Statements for Database '${dbName}' Versi
on ${currentVersion}.`,
);
return false;
}
const upgrade = this._upgradeStatements[dbName][currentVersion];
/**
* When the version after an upgrade would be greater
* than the targeted version
*/
if (targetVersion < upgrade.toVersion) {
console.log(
`Error PRAGMA user_version failed : Version mismatch! Expect
ed Version ${targetVersion} found Version ${currentVersion}. Up
grade Statement would upgrade to version ${upgrade.toVersion}, b
ut target version is ${targetVersion}.`,
);
return false;
}
// set PRAGMA
let pragmas: string = `
PRAGMA foreign_keys = OFF;
`;
let pchanges: number = await this.execute(db, pragmas);
if (pchanges === -1) {
console.log('onUpgrade: Error in setting ' + 'PRAGMA foreign_keys = OFF');
return false;
}
// Here we assume all the tables schema are given in
// the upgrade statement
if (upgrade.statement) {
// -> backup all existing tables "tableName" in "temp_tableName"
let retB: boolean = await this.backupTables(db);
if (!retB) {
console.log('onUpgrade Error in backuping existing tables');
return false;
}
// -> Drop all Indexes
retB = await this.dropIndexes(db);
if (!retB) {
console.log('onUpgrade Error in dropping indexes');
return false;
}
// -> Drop all Triggers
retB = await this.dropTriggers(db);
if (!retB) {
console.log('onUpgrade Error in dropping triggers');
return false;
}
// -> Create new tables from upgrade.statement
const result = await this.execute(db, upgrade.statement);
if (result.changes < 0) {
console.log(`onUpgrade Error in creating tables `);
return false;
}
// -> Create the list of table's common fields
retB = await this.findCommonColumns(db);
if (!retB) {
console.log('onUpgrade Error in findCommonColumns');
return false;
}
// -> Update the new table's data from old table's data
retB = await this.updateNewTablesData(db);
if (!retB) {
console.log('onUpgrade Error in updateNewTablesData');
return false;
}
// -> Drop _temp_tables
retB = await this.dropTempTables(db);
if (!retB) {
console.log('onUpgrade Error in dropTempTables');
return false;
}
// -> Do some cleanup
this._alterTables = {};
this._commonColumns = {};
// here we assume that the Set contains only
// - the data for new tables as INSERT statements
// - the data for new columns in existing tables
// as UPDATE statements
if (upgrade.set) {
// -> load new data
const result = await this.executeSet(db, upgrade.set);
if (result.changes < 0) {
console.log('onUpgrade Error executeSet Failed');
return false;
}
}
// -> update database version
await this.updateDatabaseVersion(db, upgrade.toVersion);
// -> update syncDate if any
const isExists = await this.isTableExists(db, 'sync_table');
if (isExists) {
const sDate: number = Math.round(new Date().getTime() / 1000);
let stmt: string = `UPDATE sync_table SET sync_date = ${sDate} `;
stmt += `WHERE id = 1;`;
const retRes = await this.execute(db, stmt);
if (retRes.changes === -1) {
let message: string = 'onUpgrade: Update sync_date failed ';
console.log(message);
return false;
}
}
} else {
let message: string = 'onUpgrade: No statement given in ';
message += 'upgradeStatements object';
console.log(message);
return false;
}
// set PRAGMA
pragmas = `
PRAGMA foreign_keys = ON;
`;
pchanges = await this.execute(db, pragmas);
if (pchanges === -1) {
console.log('onUpgrade: Error in setting ' + 'PRAGMA foreign_keys = ON');
return false;
}
return true;
}
private async dropTempTables(db: any): Promise<boolean> {
return new Promise(async resolve => {
const tempTables: Array<string> = Object.keys(this._alterTables);
const statements: Array<string> = [];
for (let i: number = 0; i < tempTables.length; i++) {
const stmt = `DROP TABLE IF EXISTS _temp_${tempTables[i]};`;
statements.push(stmt);
}
const pchanges: any = await this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropTempTables: Error execute failed');
resolve(false);
}
resolve(true);
});
}
private async backupTables(db: any): Promise<boolean> {
return new Promise(async resolve => {
const tables: Array<any> = await this.getTablesNames(db);
if (tables.length === 0) {
console.log("backupTables: Error get table's names failed");
resolve(false);
}
for (let i: number = 0; i < tables.length; i++) {
const retB: boolean = await this.backupTable(db, tables[i].name);
if (!retB) {
console.log('backupTables: Error backupTable failed');
resolve(false);
}
}
resolve(true);
});
}
private async backupTable(db: any, tableName: string): Promise<boolean> {
return new Promise(async resolve => {
let retB: boolean = await this.beginTransaction(db);
if (!retB) {
console.log('backupTable: Error beginTransaction failed');
resolve(false);
}
// get the column's name
const tableNamesTypes: any = await this.getTableColumnNamesTypes(
db,
tableName,
);
this._alterTables[tableName] = tableNamesTypes.names;
// prefix the table with _temp_
let stmt: string = `ALTER TABLE ${tableName} RENAME TO _temp_${tableName};`;
const pchanges: any = await this.execute(db, stmt);
if (pchanges.changes === -1) {
console.log('backupTable: Error execute failed');
resolve(false);
}
retB = await this.endTransaction(db);
if (!retB) {
console.log('backupTable: Error endTransaction failed');
resolve(false);
}
resolve(true);
});
}
private async dropAll(): Promise<boolean> {
return new Promise(async resolve => {
// Drop All Tables
const db = this._utils.connection(
this._databaseName,
false /*,this._secret*/,
);
if (db === null) {
this.isOpen = false;
console.log('dropAll: Error Database connection failed');
resolve(false);
}
let retB: boolean = await this.dropTables(db);
if (!retB) resolve(false);
// Drop All Indexes
retB = await this.dropIndexes(db);
if (!retB) resolve(false);
// Drop All Triggers
retB = await this.dropTriggers(db);
if (!retB) resolve(false);
// VACCUUM
await this.execute(db, 'VACUUM;');
db.close();
return true;
});
}
private async dropTables(db: any): Promise<boolean> {
return new Promise(async resolve => {
// get the table's names
const tables: Array<any> = await this.getTablesNames(db);
let statements: Array<string> = [];
for (let i: number = 0; i < tables.length; i++) {
const stmt: string = `DROP TABLE IF EXISTS ${tables[i].name};`;
statements.push(stmt);
}
if (statements.length > 0) {
const pchanges: any = await this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropTables: Error execute failed');
resolve(false);
}
}
resolve(true);
});
}
private async dropIndexes(db: any): Promise<boolean> {
return new Promise(async resolve => {
// get the index's names
let stmt: string = "SELECT name FROM sqlite_master WHERE type = 'index' ";
stmt += "AND name NOT LIKE 'sqlite_%';";
let indexes: Array<any> = await this.select(db, stmt, []);
if (indexes.length === 0) {
console.log("dropIndexes: Error get index's names failed");
resolve(false);
}
let statements: Array<string> = [];
for (let i: number = 0; i < indexes.length; i++) {
const stmt: string = `DROP INDEX IF EXISTS ${indexes[i].name};`;
statements.push(stmt);
}
if (statements.length > 0) {
const pchanges: any = await this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropIndexes: Error execute failed');
resolve(false);
}
}
resolve(true);
});
}
private async dropTriggers(db: any): Promise<boolean> {
return new Promise(async resolve => {
// get the index's names
let stmt: string =
"SELECT name FROM sqlite_master WHERE type = 'trigger';";
let triggers: Array<any> = await this.select(db, stmt, []);
if (triggers.length === 0) {
console.log("dropTriggers: Error get index's names failed");
resolve(false);
}
let statements: Array<string> = [];
for (let i: number = 0; i < triggers.length; i++) {
let stmt: string = 'DROP TRIGGER IF EXISTS ';
stmt += `${triggers[i].name};`;
statements.push(stmt);
}
if (statements.length > 0) {
const pchanges: any = await this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('dropTriggers: Error execute failed');
resolve(false);
}
}
resolve(true);
});
}
private async findCommonColumns(db: any): Promise<boolean> {
return new Promise(async resolve => {
// Get new table list
const tables: Array<any> = await this.getTablesNames(db);
if (tables.length === 0) {
console.log("findCommonColumns: Error get table's names failed");
resolve(false);
}
for (let i: number = 0; i < tables.length; i++) {
// get the column's name
const tableNamesTypes: any = await this.getTableColumnNamesTypes(
db,
tables[i].name,
);
// find the common columns
const keys: Array<string> = Object.keys(this._alterTables);
if (keys.includes(tables[i].name)) {
this._commonColumns[tables[i].name] = this.arraysIntersection(
this._alterTables[tables[i].name],
tableNamesTypes.names,
);
}
}
resolve(true);
});
}
private async getTablesNames(db: any): Promise<Array<any>> {
return new Promise(async resolve => {
// get the table's names
let stmt: string = "SELECT name FROM sqlite_master WHERE type = 'table' ";
stmt += "AND name NOT LIKE 'sync_table' ";
stmt += "AND name NOT LIKE '_temp_%' ";
stmt += "AND name NOT LIKE 'sqlite_%';";
const tables: Array<any> = await this.select(db, stmt, []);
resolve(tables);
});
}
private async updateNewTablesData(db: any): Promise<boolean> {
return new Promise(async resolve => {
let retB: boolean = await this.beginTransaction(db);
if (!retB) {
console.log('updateNewTablesData: ' + 'Error beginTransaction failed');
resolve(false);
}
let statements: Array<string> = [];
const keys: Array<string> = Object.keys(this._commonColumns);
keys.forEach(key => {
const columns = this._commonColumns[key].join(',');
let stmt: string = `INSERT INTO ${key} (${columns}) SELECT `;
stmt += `${columns} FROM _temp_${key};`;
statements.push(stmt);
});
const pchanges: any = await this.execute(db, statements.join('\n'));
if (pchanges.changes === -1) {
console.log('updateNewTablesData: Error execute failed');
resolve(false);
}
retB = await this.endTransaction(db);
if (!retB) {
console.log('updateNewTablesData: ' + 'Error endTransaction failed');
resolve(false);
}
resolve(true);
});
}
private arraysIntersection(a1: Array<any>, a2: Array<any>): Array<any> {
return a1.filter((n: any) => {
return a2.indexOf(n) !== -1;
});
}
private backupDB(dbName: string): Promise<boolean> {
return new Promise(resolve => {
const dbPath = this._utils.getDBPath(dbName);
const dbBackupPath = this._utils.getDBPath(`backup-${dbName}`);
if (dbPath.length > 0 && dbBackupPath.length > 0) {
this.NodeFs.copyFile(
dbPath,
dbBackupPath,
this.NodeFs.constants.COPYFILE_EXCL,
(err: any) => {
if (err) {
console.log('Error: in backupDB Found:', err);
resolve(false);
} else {
resolve(true);
}
},
);
} else {
console.log('Error: in backupDB path & backuppath not correct');
resolve(false);
}
});
}
private restoreDB(dbName: string): Promise<boolean> {
return new Promise(resolve => {
const dbPath = this._utils.getDBPath(dbName);
const dbBackupPath = this._utils.getDBPath(`backup-${dbName}`);
if (dbPath.length > 0 && dbBackupPath.length > 0) {
const isBackup: boolean = this.isDB(dbBackupPath);
if (!isBackup) {
console.log('Error: in restoreDB no backup database');
resolve(false);
}
const isFile: boolean = this.isDB(dbPath);
if (isFile) {
try {
this.NodeFs.unlinkSync(dbPath);
//file removed
} catch (e) {
console.log('Error: in restoreDB delete database failed');
resolve(false);
}
}
this.NodeFs.copyFile(
dbBackupPath,
dbPath,
this.NodeFs.constants.COPYFILE_EXCL,
(err: any) => {
if (err) {
console.log('Error: in restoreDB copyfile failed:', err);
resolve(false);
} else {
resolve(true);
}
},
);
} else {
console.log('Error: in backupDB path & backuppath not correct');
resolve(false);
}
});
}
private isDB(dbPath: string): boolean {
try {
if (this.NodeFs.existsSync(dbPath)) {
//file exists
return true;
}
} catch (err) {
console.error(err);
return false;
}
}
//1234567890123456789012345678901234567890123456789012345678901234567890
}

@@ -5,2 +5,3 @@ /* JSON function */

'database',
'version',
'encrypted',

@@ -18,2 +19,3 @@ 'mode',

if (key === 'database' && typeof obj[key] != 'string') return false;
if (key === 'version' && typeof obj[key] != 'number') return false;
if (key === 'encrypted' && typeof obj[key] != 'boolean') return false;

@@ -20,0 +22,0 @@ if (key === 'mode' && typeof obj[key] != 'string') return false;

@@ -18,2 +18,4 @@ import { WebPlugin } from '@capacitor/core';

capSQLiteJson,
capSQLiteUpgradeOptions,
capSQLiteVersionUpgrade,
} from './definitions';

@@ -31,2 +33,6 @@ import { DatabaseSQLiteHelper } from './electron-utils/DatabaseSQLiteHelper';

private mDb!: DatabaseSQLiteHelper;
private versionUpgrades: Record<
string,
Record<number, capSQLiteVersionUpgrade>
> = {};

@@ -55,2 +61,3 @@ constructor() {

const dbName: string = options.database;
const dbVersion: number = options.version ?? 1;
/*

@@ -62,12 +69,17 @@ let encrypted: boolean = options.encrypted ? options.encrypted : false;

*/
console.log('---> in Open this.versionUpgrades ' + this.versionUpgrades);
this.mDb = new DatabaseSQLiteHelper(
`${dbName}SQLite.db` /*,encrypted,inMode,secretKey,newsecretKey*/,
`${dbName}SQLite.db`,
dbVersion,
this.versionUpgrades /*,encrypted,inMode,secretKey,newsecretKey*/,
);
await this.mDb.setup();
if (!this.mDb.isOpen) {
return Promise.reject({
return Promise.resolve({
result: false,
message: `Open command failed: Database ${dbName}SQLite.db not opened`,
});
} else {
return Promise.resolve({ result: true });
}
return Promise.resolve({ result: true });
}

@@ -272,3 +284,5 @@ async close(options: capSQLiteOptions): Promise<capSQLiteResult> {

const dbName: string = `${jsonObj.database}SQLite.db`;
this.mDb = new DatabaseSQLiteHelper(dbName);
const dbVersion: number = jsonObj.version ?? 1;
this.mDb = new DatabaseSQLiteHelper(dbName, dbVersion, {});
await this.mDb.setup();
const ret = await this.mDb.importJson(jsonObj);

@@ -320,2 +334,46 @@ this.mDb.close(dbName);

}
async addUpgradeStatement(
options: capSQLiteUpgradeOptions,
): Promise<capSQLiteResult> {
if (
typeof options.database === 'undefined' ||
typeof options.database != 'string'
) {
return Promise.reject({
result: false,
message: 'Must provide a database name',
});
}
if (typeof options.upgrade[0] === 'undefined') {
return Promise.reject({
result: false,
message: 'Must provide an upgrade Object',
});
}
const upgrade = options.upgrade[0];
const keys: Array<string> = Object.keys(upgrade);
if (
!keys.includes('fromVersion') ||
!keys.includes('toVersion') ||
!keys.includes('statement')
) {
return Promise.reject({
result: false,
message: 'Must provide an upgrade capSQLiteVersionUpgrade Object',
});
}
const fullDBName = `${options.database}SQLite.db`;
if (!this.versionUpgrades[fullDBName]) {
this.versionUpgrades[fullDBName] = {};
}
this.versionUpgrades[fullDBName][upgrade.fromVersion] = {
fromVersion: upgrade.fromVersion,
toVersion: upgrade.toVersion,
statement: upgrade.statement,
};
if (upgrade.set)
this.versionUpgrades[fullDBName][upgrade.fromVersion]['set'] =
upgrade.set;
return Promise.resolve({ result: true });
}
}

@@ -322,0 +380,0 @@ const CapacitorSQLite = new CapacitorSQLiteElectronWeb();

{
"name": "@capacitor-community/sqlite",
"version": "2.4.2-5",
"version": "2.4.2-6",
"description": "Capacitor SQLite Plugin",

@@ -5,0 +5,0 @@ "homepage": "https://github.com/capacitor-community/sqlite",

@@ -133,2 +133,3 @@ <p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p>

| isDBExists | ✅ | ✅ | ✅ | ❌ |
| addUpgradeStatement | ❌ | ✅ | ✅ | ❌ |

@@ -141,2 +142,4 @@ ## Documentation

[UpgradeDatabaseVersion_Documentation](https://github.com/capacitor-community/sqlite/blob/master/docs/UpgradeDatabaseVersion.md)
## Applications demonstrating the use of the plugin

@@ -308,2 +311,3 @@

<td align="center"><a href="https://github.com/paulantoine2"><img src="https://avatars0.githubusercontent.com/u/22882943?s=64&v=4" width="100px;" alt=""/><br /><sub><b>Paul Antoine</b></sub></a><br /><a href="https://github.com/capacitor-community/sqlite/commits?author=jepiqueau" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/paulantoine2"><img src="https://avatars2.githubusercontent.com/u/303016?s=60&u=1ce232ae3c22eac7b0b4778e46fe079939c39b40&v=4" width="100px;" alt=""/><br /><sub><b>Karyfars</b></sub></a><br /><a href="https://github.com/capacitor-community/sqlite/commits?author=jepiqueau" title="Code">💻</a></td>
</tr>

@@ -310,0 +314,0 @@ </table>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc