jeep-sqlite
Version:
Browser SQLite Stencil Component
1,304 lines • 122 kB
JavaScript
import { Database } from "../../utils/database";
import localForage from "localforage";
import { UtilsJSON } from "../../utils/utils-json";
import { UtilsStore } from "../../utils/utils-store";
import * as JSZip from "jszip";
import { fileOpen, fileSave, supported } from "browser-fs-access";
export class JeepSqlite {
constructor() {
this.isStore = false;
this._dbDict = {};
this.databaseList = {};
this._versionUpgrades = {};
this._overwrite = true;
this.autoSave = false;
this.typeOrm = false;
this.wasmPath = undefined;
this.pickText = undefined;
this.saveText = undefined;
this.buttonOptions = undefined;
this.innerAutoSave = undefined;
this.innerTypeOrm = undefined;
this.innerWasmPath = undefined;
this.innerPickText = undefined;
this.innerSaveText = undefined;
this.innerButtonOptions = undefined;
}
//*****************************
//* Watch on Property Changes *
//*****************************
parseAutoSave(newValue) {
this.innerAutoSave = newValue;
}
parseTypeOrm(newValue) {
this.innerTypeOrm = newValue;
}
parseWasmPath(newValue) {
this.innerWasmPath = newValue;
}
parsePickText(newValue) {
this.innerPickText = newValue;
}
parseSaveText(newValue) {
this.innerSaveText = newValue;
}
parseButtonOptions(newValue) {
this.innerButtonOptions = JSON.parse(newValue);
const keys = Object.keys(this.innerButtonOptions);
for (const key of keys) {
switch (key) {
case "top": {
this.el.style.setProperty('--jeep-sqlite-top', this.innerButtonOptions[key]);
break;
}
case "right": {
this.el.style.setProperty('--jeep-sqlite-right', this.innerButtonOptions[key]);
break;
}
case "fontSize": {
this.el.style.setProperty('--jeep-sqlite-font-size', this.innerButtonOptions[key]);
break;
}
case "padding": {
this.el.style.setProperty('--jeep-sqlite-padding', this.innerButtonOptions[key]);
break;
}
case "backgroundColor": {
this.el.style.setProperty('--jeep-sqlite-background-color', this.innerButtonOptions[key]);
break;
}
case "color": {
this.el.style.setProperty('--jeep-sqlite-color', this.innerButtonOptions[key]);
break;
}
}
}
}
//**********************
//* Method Definitions *
//**********************
async echo(options) {
return options;
}
async createConnection(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const version = options.version ? options.version : 1;
const readonly = options.readonly ? options.readonly : false;
try {
await this._createConnection(dbName, version, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async isConnection(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
const ret = await this._isConnection(dbName, readonly);
return Promise.resolve(ret);
}
async closeConnection(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
await this._closeConnection(dbName, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async open(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
await this._open(dbName, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async close(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
await this._close(dbName, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async getVersion(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
const res = await this._getVersion(dbName, readonly);
return Promise.resolve(res);
}
catch (err) {
return Promise.reject(err);
}
}
async beginTransaction(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
if (readonly) {
return Promise.reject(`BeginTransaction: not allowed in read-only mode`);
}
try {
const changes = await this._beginTransaction(dbName);
return Promise.resolve(changes);
}
catch (err) {
return Promise.reject(err);
}
}
async commitTransaction(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
if (readonly) {
return Promise.reject(`CommitTransaction: not allowed in read-only mode`);
}
try {
const changes = await this._commitTransaction(dbName);
return Promise.resolve(changes);
}
catch (err) {
return Promise.reject(err);
}
}
async rollbackTransaction(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
if (readonly) {
return Promise.reject(`BeginTransaction: not allowed in read-only mode`);
}
try {
const changes = await this._rollbackTransaction(dbName);
return Promise.resolve(changes);
}
catch (err) {
return Promise.reject(err);
}
}
async isTransactionActive(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
if (readonly) {
return Promise.reject(`isTransactionActive: not allowed in read-only mode`);
}
try {
const res = await this._isTransactionActive(dbName);
return Promise.resolve(res);
}
catch (err) {
return Promise.reject(err);
}
}
async execute(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('statements') || options.statements.length === 0) {
return Promise.reject('Must provide raw SQL statements');
}
const dbName = options.database;
const statements = options.statements;
let transaction = true;
const readonly = options.readonly ? options.readonly : false;
if (keys.includes('transaction'))
transaction = options.transaction;
try {
const changes = await this._execute(dbName, statements, transaction, readonly);
return Promise.resolve(changes);
}
catch (err) {
return Promise.reject(err);
}
}
async executeSet(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('set') || options.set.length === 0) {
return Promise.reject('Must provide a non-empty set of SQL statements');
}
const dbName = options.database;
const setOfStatements = options.set;
let transaction = true;
if (keys.includes('transaction'))
transaction = options.transaction;
const readonly = options.readonly ? options.readonly : false;
const returnMode = options.returnMode ? options.returnMode : 'no';
try {
const changes = await this._executeSet(dbName, setOfStatements, transaction, readonly, returnMode);
return Promise.resolve(changes);
}
catch (err) {
return Promise.reject(err);
}
}
async run(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('statement') || options.statement.length === 0) {
return Promise.reject('Must provide a run statement');
}
const dbName = options.database;
const statement = options.statement;
let values = [];
if (keys.includes('values')) {
values = options.values.length > 0 ? options.values : [];
}
let transaction = true;
if (keys.includes('transaction'))
transaction = options.transaction;
const readonly = options.readonly ? options.readonly : false;
const returnMode = options.returnMode ? options.returnMode : 'no';
try {
const retChanges = await this._run(dbName, statement, values, transaction, readonly, returnMode);
return Promise.resolve(retChanges);
}
catch (err) {
return Promise.reject(err);
}
}
async query(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('statement') || options.statement.length === 0) {
return Promise.reject('Must provide a query statement');
}
let values = [];
if (keys.includes('values')) {
values = options.values.length > 0 ? options.values : [];
}
const dbName = options.database;
const statement = options.statement;
const readonly = options.readonly ? options.readonly : false;
try {
const retValues = await this._query(dbName, statement, values, readonly);
return Promise.resolve(retValues);
}
catch (err) {
return Promise.reject(err);
}
}
async getTableList(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
const retValues = await this._getTableList(dbName, readonly);
return Promise.resolve(retValues);
}
catch (err) {
return Promise.reject(err);
}
}
async isDBExists(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
const ret = await this._isDBExists(dbName, readonly);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async isDBOpen(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
const ret = await this._isDBOpen(dbName, readonly);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async deleteDatabase(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
return await this._deleteDatabase(dbName, readonly);
}
catch (err) {
return Promise.reject(err);
}
}
async isStoreOpen() {
return Promise.resolve(this.isStore);
}
async copyFromAssets(options) {
let overwrite;
if (options != null) {
const keys = Object.keys(options);
overwrite = keys.includes('overwrite') ? options.overwrite : true;
}
else {
overwrite = true;
}
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
try {
await this._copyFromAssets(overwrite);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async isTableExists(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
if (!keys.includes('table')) {
return Promise.reject('Must provide a table name');
}
const tableName = options.table;
const readonly = options.readonly ? options.readonly : false;
try {
const ret = await this._isTableExists(dbName, tableName, readonly);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async createSyncTable(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
const ret = await this._createSyncTable(dbName, readonly);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async getSyncDate(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
const ret = await this._getSyncDate(dbName, readonly);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async setSyncDate(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('syncdate')) {
return Promise.reject('Must provide a synchronization date');
}
const dbName = options.database;
const syncDate = options.syncdate;
const readonly = options.readonly ? options.readonly : false;
try {
await this._setSyncDate(dbName, syncDate, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async isJsonValid(options) {
const keys = Object.keys(options);
if (!keys.includes('jsonstring')) {
return Promise.reject('Must provide a json object');
}
const jsonStrObj = options.jsonstring;
try {
const ret = await this._isJsonValid(jsonStrObj);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async importFromJson(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('jsonstring')) {
return Promise.reject('Must provide a json object');
}
const jsonStrObj = options.jsonstring;
try {
const ret = await this._importFromJson(jsonStrObj);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async exportToJson(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('jsonexportmode')) {
return Promise.reject('Must provide a json export mode');
}
const dbName = options.database;
const exportMode = options.jsonexportmode;
const readonly = options.readonly ? options.readonly : false;
try {
const ret = await this._exportToJson(dbName, exportMode, readonly);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async deleteExportedRows(options) {
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
await this._deleteExportedRows(dbName, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async addUpgradeStatement(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
if (!keys.includes('upgrade')) {
return Promise.reject('Must provide an upgrade capSQLiteVersionUpgrade Object');
}
const dbName = options.database;
const upgrades = options.upgrade;
for (const upgrade of upgrades) {
const versionUpgradeKeys = Object.keys(upgrade);
if (!versionUpgradeKeys.includes('toVersion') ||
!versionUpgradeKeys.includes('statements')) {
return Promise.reject('Must provide an upgrade capSQLiteVersionUpgrade Object');
}
if (typeof upgrade.toVersion != 'number') {
return Promise.reject('upgrade.toVersion must be a number');
}
if (this._versionUpgrades[dbName]) {
this._versionUpgrades[dbName][upgrade.toVersion] = upgrade;
}
else {
const upgVDict = {};
upgVDict[upgrade.toVersion] = upgrade;
this._versionUpgrades[dbName] = upgVDict;
}
}
return Promise.resolve();
}
async isDatabase(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
try {
const ret = await this._isDatabase(dbName);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async getDatabaseList() {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
try {
const ret = await this._getDatabaseList();
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async checkConnectionsConsistency(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('dbNames')) {
return Promise.reject(`Must provide a list of connection's name`);
}
const dbNames = options.dbNames;
if (!keys.includes('openModes')) {
return Promise.reject(`Must provide a list of connection's open mode`);
}
const openModes = options.openModes;
try {
const ret = await this._checkConnectionsConsistency(dbNames, openModes);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async saveToStore(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
const readonly = options.readonly ? options.readonly : false;
try {
await this._saveToStore(dbName, readonly);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async saveToLocalDisk(options) {
const keys = Object.keys(options);
if (!keys.includes('database')) {
return Promise.reject('Must provide a database name');
}
const dbName = options.database;
try {
await this._saveToLocalDisk(dbName);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async getFromLocalDiskToStore(options) {
const overwrite = options.overwrite ? options.overwrite : true;
if (supported) {
console.log('Using the File System Access API.');
}
else {
console.log('Using the fallback implementation.');
}
try {
await this._getFromLocalDiskToStore(overwrite);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async getFromHTTPRequest(options) {
if (!this.isStore) {
return Promise.reject(`>>> jeep-sqlite StoreName: ${this.storeName} is not opened`);
}
let keys = Object.keys(options);
if (!keys.includes('url')) {
return Promise.reject('Must provide an url');
}
const url = options.url;
const overwrite = options.overwrite ? options.overwrite : true;
try {
await this._getFromHTTPRequest(url, overwrite);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
//*******************************
//* Component Lifecycle Methods *
//*******************************
connectedCallback() {
this.parseAutoSave(this.autoSave !== undefined ? this.autoSave : false);
this.parseTypeOrm(this.typeOrm !== undefined ? this.typeOrm : false);
this.parseWasmPath(this.wasmPath !== undefined ? this.wasmPath : '/assets');
this.parseSaveText(this.saveText !== undefined ? this.saveText : 'Save');
this.parsePickText(this.pickText !== undefined ? this.pickText : 'Pick a database');
if (this.buttonOptions !== undefined) {
this.parseButtonOptions(this.buttonOptions);
}
this.openStore("jeepSqliteStore", "databases").then((mStore) => {
this.isStore = mStore;
});
}
componentWillLoad() {
}
async componentDidLoad() {
this._element = this.el.shadowRoot;
if (!this.isStore) {
console.log('jeep-sqlite isStore = false');
}
}
//******************************
//* Private Method Definitions *
//******************************
async _createConnection(database, version, readonly) {
let upgDict = {};
const vUpgKeys = Object.keys(this._versionUpgrades);
if (vUpgKeys.length !== 0 && vUpgKeys.includes(database)) {
upgDict = this._versionUpgrades[database];
}
const dbDictKeys = Object.keys(this._dbDict);
let mDB;
try {
if (dbDictKeys.length > 0 && (dbDictKeys.includes("RW_" + database) ||
dbDictKeys.includes("RO_" + database))) {
mDB = dbDictKeys.includes("RW_" + database) ? this._dbDict["RW_" + database]
: this._dbDict["RO_" + database];
}
else {
mDB = new Database(database + 'SQLite.db', version, upgDict, this.store, this.innerAutoSave, this.innerWasmPath);
}
const connName = readonly ? "RO_" + database : "RW_" + database;
this._dbDict[connName] = mDB;
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(msg);
}
}
async _isConnection(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (keys.includes(connName)) {
return { result: true };
}
else {
return { result: false };
}
}
async _closeConnection(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`CloseConnection: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
try {
if (mDB.isDBOpen()) {
await mDB.close();
}
// remove the connection from dictionary
delete this._dbDict[connName];
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`CloseConnection: ${msg}`);
}
}
async _open(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`Open: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
try {
await mDB.open();
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`Open: ${msg}`);
}
}
async _close(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`Close: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`Close: ${database} database not opened`);
}
try {
await mDB.close();
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`Close: ${msg}`);
}
}
async _saveToStore(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`SaveToStore: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`SaveToStore: ${database} database not opened`);
}
try {
await mDB.saveToStore();
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`SaveToStore: ${msg}`);
}
}
async _saveToLocalDisk(database) {
try {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject('SaveToLocalDisk: No available connection for ' + `${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`SaveToLocalDisk: ${database} database not opened`);
}
const uint = await mDB.exportDB();
this._blob = await this.uint2blob(uint);
const dbName = `${database}SQLite.db`;
this._opts = { fileName: dbName, extensions: ['.db'], startIn: 'documents', };
this._buttonSaveEl = document.createElement('button');
// const baseName = this._opts.fileName.split('.db')[0];
this._buttonSaveEl.setAttribute("id", `saveButton`);
this._buttonSaveEl.innerHTML = `${this.innerSaveText} ${dbName}`;
this._element.appendChild(this._buttonSaveEl);
this._buttonSaveEl.addEventListener("click", this.saveFile.bind(this));
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`SaveToLocalDisk: ${msg}`);
}
}
async _getFromLocalDiskToStore(overwrite) {
this._buttonPickEl = document.createElement('button');
this._buttonPickEl.setAttribute("id", "pickButton");
this._buttonPickEl.innerHTML = `${this.innerPickText}`;
this._element.appendChild(this._buttonPickEl);
this._buttonPickEl.addEventListener("click", this.pickDatabase.bind(this));
this._overwrite = overwrite;
return Promise.resolve();
}
async pickDatabase() {
try {
const blob = await fileOpen({ extensions: ['.db'] });
let uInt8Array = await this.blob2uint(blob);
const databaseName = this.removePathSuffix(blob.name);
const dbName = this.setPathSuffix(blob.name);
// check if dbName exists
const isExist = await UtilsStore.isDBInStore(dbName, this.store);
if (!isExist) {
await UtilsStore.saveDBToStore(dbName, uInt8Array, this.store);
}
else {
if (this._overwrite) {
await UtilsStore.removeDBFromStore(dbName, this.store);
await UtilsStore.saveDBToStore(dbName, uInt8Array, this.store);
}
else {
this.PickDatabaseEnded.emit({ message: `Error: cannot overwrite ${dbName}` });
}
}
this._element.removeChild(this._buttonPickEl);
this.PickDatabaseEnded.emit({ db_name: databaseName });
}
catch (err) {
const msg = err.message ? err.message : err;
this.PickDatabaseEnded.emit({ message: msg });
}
}
async saveFile() {
try {
await fileSave(this._blob, [this._opts]);
const databaseName = this._opts.fileName;
this._element.removeChild(this._buttonSaveEl);
this.SaveDatabaseEnded.emit({ db_name: databaseName });
}
catch (err) {
const msg = err.message ? err.message : err;
this.SaveDatabaseEnded.emit({ message: msg });
}
}
async _getVersion(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`Open: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`GetVersion: ${database} database not opened`);
}
try {
const version = await mDB.getVersion();
const ret = {};
ret.version = version;
return Promise.resolve(ret);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`Open: ${msg}`);
}
}
async _beginTransaction(database) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`BeginTransaction: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`BeginTransaction: ${database} database not opened`);
}
let changes = {};
const ret = await mDB.beginTransaction();
changes = { changes: { changes: ret } };
return Promise.resolve(changes);
}
async _commitTransaction(database) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`CommitTransaction: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`CommitTransaction: ${database} database not opened`);
}
let changes = {};
const ret = await mDB.commitTransaction();
changes = { changes: { changes: ret } };
return Promise.resolve(changes);
}
async _rollbackTransaction(database) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`RollbackTransaction: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`RollbackTransaction: ${database} database not opened`);
}
let changes = {};
const ret = await mDB.rollbackTransaction();
changes = { changes: { changes: ret } };
return Promise.resolve(changes);
}
async _isTransactionActive(database) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`IsTransactionActive: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`IsTransactionActive: ${database} database not opened`);
}
let result = {};
const res = mDB.isTransActive();
result = { result: res };
return Promise.resolve(result);
}
async _execute(database, statements, transaction, readonly) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`Execute: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`Execute: ${database} database not opened`);
}
if (readonly) {
return Promise.reject(`Execute: not allowed in read-only mode`);
}
let changes = {};
const command = statements.substring(0, 6);
if (this.innerAutoSave && command === "COMMIT" && this.innerTypeOrm) {
// fix issue for typeORM with autosave
changes = { changes: { changes: 0 } };
return Promise.resolve(changes);
}
try {
const ret = await mDB.executeSQL(statements, transaction);
changes = { changes: { changes: ret } };
return Promise.resolve(changes);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`Execute: ${msg}`);
}
}
async _executeSet(database, setOfStatements, transaction, readonly, returnMode) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`ExecuteSet: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`ExecuteSet: ${database} database not opened`);
}
if (readonly) {
return Promise.reject(`ExecuteSet: not allowed in read-only mode`);
}
for (const sStmt of setOfStatements) {
if (!('statement' in sStmt) || !('values' in sStmt)) {
return Promise.reject('ExecuteSet: Must provide a set as ' + 'Array of {statement,values}');
}
}
try {
const ret = await mDB.execSet(setOfStatements, transaction, returnMode);
const changes = { changes: { changes: ret.changes, lastId: ret.lastId,
values: ret.values } };
return Promise.resolve(changes);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`ExecuteSet: ${msg}`);
}
}
async _run(database, statement, values, transaction, readonly, returnMode) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`Run: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`Run: ${database} database not opened`);
}
if (readonly) {
return Promise.reject(`Run: not allowed in read-only mode`);
}
let changes = {};
const command = statement.substring(0, 6);
if (this.innerAutoSave && command === "COMMIT") {
// fix issue for typeORM with autosave
changes = { changes: { changes: 0 } };
return Promise.resolve(changes);
}
try {
const ret = await mDB.runSQL(statement, values, transaction, returnMode);
changes = { changes: { changes: ret.changes, lastId: ret.lastId, values: ret.values } };
return Promise.resolve(changes);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`Run: ${msg}`);
}
}
async _query(database, statement, values, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`Query: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`Query: ${database} database not opened`);
}
let ret = [];
const command = statement.substring(0, 6);
if (this.innerAutoSave && command === "COMMIT") {
// fix issue for typeORM with autosave
return Promise.resolve({ values: ret });
}
try {
ret = await mDB.selectSQL(statement, values);
return Promise.resolve({ values: ret });
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`Query failed: ${msg}`);
}
}
async _getTableList(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`GetTableList: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`GetTableList: ${database} database not opened`);
}
let ret = [];
try {
ret = await mDB.getTableNames();
return Promise.resolve({ values: ret });
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`GetTableList failed: ${msg}`);
}
}
async _isDBExists(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`IsDBExists: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
/* if (!mDB.isDBOpen()) {
return Promise.reject(
`IsDBExists: ${database} database not opened`);
}
*/
try {
const ret = await mDB.isDBExists(database + 'SQLite.db');
const result = { result: ret };
return Promise.resolve(result);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`IsDBExists: ${msg}`);
}
}
async _isDBOpen(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`IsDBOpen: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
const result = { result: false };
return Promise.resolve(result);
}
try {
const ret = await mDB.isDBOpen(database + 'SQLite.db');
const result = { result: ret };
return Promise.resolve(result);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`IsDBOpen: ${msg}`);
}
}
async _deleteDatabase(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`DeleteDatabase: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (readonly) {
return Promise.reject(`DeleteDatabase: not allowed in read-only mode`);
}
try {
await mDB.deleteDB(database + 'SQLite.db');
return Promise.resolve();
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`DeleteDatabase: ${msg}`);
}
}
async _isTableExists(database, table, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject(`IsTableExists: No available connection for ${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`IsTableExists: ${database} database not opened`);
}
try {
const ret = await mDB.isTable(table);
const result = { result: ret };
return Promise.resolve(result);
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`IsTableExists: ${msg}`);
}
}
async _createSyncTable(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = "RW_" + database;
if (!keys.includes(connName)) {
return Promise.reject('CreateSyncTable: No available connection for ' + `${database}`);
}
const mDB = this._dbDict[connName];
if (!mDB.isDBOpen()) {
return Promise.reject(`CreateSyncTable: ${database} database not opened`);
}
if (readonly) {
return Promise.reject(`CreateSyncTable: not allowed in read-only mode`);
}
try {
const ret = await mDB.createSyncTable();
return Promise.resolve({ changes: { changes: ret } });
}
catch (err) {
const msg = err.message ? err.message : err;
return Promise.reject(`CreateSyncTable: ${msg}`);
}
}
async _getSyncDate(database, readonly) {
const keys = Object.keys(this._dbDict);
const connName = readonly ? "RO_" + database : "RW_" + d