@synerty/vortexjs
Version:
Custom observable data serialisation and routing based on Angular 2+
123 lines • 16.6 kB
JavaScript
import { __decorate, __param } from "tslib";
import { Inject } from "@angular/core";
import { random, SqlApiABC } from "./sql-api-abc";
import { dateStr } from "../UtilMisc";
const RETRY_NO_SPACE = "there was not enough remaining storage space";
const RETRY_DISK_ERROR = "unable to begin transaction (3850 disk I/O error)";
export let WebSqlApi = class WebSqlApi extends SqlApiABC {
constructor(dbName, dbSchema) {
super(dbName, dbSchema);
}
async isOpen() {
return this.db != null;
}
async close() {
this.db = null;
}
async _openDb() {
let retries = 5;
while (true) {
try {
return await this._openWrapped();
}
catch (err) {
err = err.message ? err.message : err;
if (retries >= 0 && WebSqlApi.checkRetryMessage(err)) {
retries--;
await new Promise((r) => setTimeout(() => r(), 100 + random()));
continue;
}
throw new Error(err);
}
}
}
async _openWrapped() {
if (await this.isOpen()) {
return;
}
this.db = openDatabase(this.dbName, "1", this.dbName, 4 * 1024 * 1024);
await this.installSchema();
}
async transaction(executeData, isQuery) {
if (!(await this.isOpen()))
await this.open();
let retries = 5;
while (true) {
try {
return await this._transactionInner(executeData, isQuery);
}
catch (e) {
if (retries >= 0 &&
(WebSqlApi.checkRetryMessage(e) || WebSqlApi.isLockedMsg(e))) {
retries--;
await new Promise((r) => setTimeout(() => r(), 100 + random()));
continue;
}
throw new Error(e);
}
}
}
async _transactionInner(executeData, isQuery) {
executeData = [...executeData];
const data = [];
await new Promise((resolve, reject) => {
this.db.transaction((t) => {
const execSql = () => {
const ed = executeData.pop();
if (ed == null) {
resolve();
return;
}
t.executeSql(ed.sql, ed.bindParams, (transaction, results) => {
/*
* results:(SQLResultSet) {
* insertId:0,
* rows:(SQLResultSetRowList){
* length:0
* },
* rowsAffected:0
* }
*/
if (isQuery) {
// ALL GOOD, Return the rows
for (let i = 0; i < results.rows.length; ++i) {
data.push(results.rows.item(i));
}
}
if (executeData.length === 0) {
resolve();
}
else {
execSql();
}
}, (tx, err) => {
err = err == null ? tx : err; // Sometimes tx is the err
reject(err.message ? err.message : err);
});
};
execSql();
});
});
return isQuery ? data : null;
}
static checkRetryMessage(message) {
if (message.indexOf(RETRY_NO_SPACE) !== -1)
return true;
return message.indexOf(RETRY_DISK_ERROR) !== -1;
}
static isLockedMsg(err) {
const msg = err.toString();
const hasNsSqlError = msg.indexOf("SQLITE.ALL - Database Error5") !== -1;
// unable to begin transaction (5 database is locked)
const hasWebSqlError = msg.indexOf("5 database is locked") !== -1;
if (hasNsSqlError || hasWebSqlError)
return true;
console.log(`${dateStr()} WebSQL: Found error message that isn't a lock : ${msg}`);
return false;
}
};
WebSqlApi = __decorate([
__param(0, Inject("")),
__param(1, Inject([]))
], WebSqlApi);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLXNxbC1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvdm9ydGV4L3N0b3JhZ2UtYXBpL3dlYi1zcWwtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFrQixNQUFNLGVBQWUsQ0FBQztBQUNsRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBSXRDLE1BQU0sY0FBYyxHQUFHLDhDQUE4QyxDQUFDO0FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsbURBQW1ELENBQUM7QUFFdEUsV0FBTSxTQUFTLEdBQWYsTUFBTSxTQUFVLFNBQVEsU0FBUztJQUNwQyxZQUF3QixNQUFjLEVBQWMsUUFBa0I7UUFDbEUsS0FBSyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU07UUFDUixPQUFPLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsS0FBSztRQUNQLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFFUyxLQUFLLENBQUMsT0FBTztRQUNuQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDaEIsT0FBTyxJQUFJLEVBQUU7WUFDVCxJQUFJO2dCQUNBLE9BQU8sTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7YUFDcEM7WUFBQyxPQUFPLEdBQUcsRUFBRTtnQkFDVixHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO2dCQUN0QyxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FB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QUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFbEUsSUFBSSxhQUFhLElBQUksY0FBYztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRWpELE9BQU8sQ0FBQyxHQUFHLENBQ1AsR0FBRyxPQUFPLEVBQUUsb0RBQW9ELEdBQUcsRUFBRSxDQUN4RSxDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKLENBQUE7QUFqSlksU0FBUztJQUNMLFdBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQWtCLFdBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0dBRDFDLFNBQVMsQ0FpSnJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IHJhbmRvbSwgU3FsQXBpQUJDLCBTcWxFeGVjdXRlRGF0YSB9IGZyb20gXCIuL3NxbC1hcGktYWJjXCI7XG5pbXBvcnQgeyBkYXRlU3RyIH0gZnJvbSBcIi4uL1V0aWxNaXNjXCI7XG5cbmRlY2xhcmUgbGV0IG9wZW5EYXRhYmFzZTogYW55O1xuXG5jb25zdCBSRVRSWV9OT19TUEFDRSA9IFwidGhlcmUgd2FzIG5vdCBlbm91Z2ggcmVtYWluaW5nIHN0b3JhZ2Ugc3BhY2VcIjtcbmNvbnN0IFJFVFJZX0RJU0tfRVJST1IgPSBcInVuYWJsZSB0byBiZWdpbiB0cmFuc2FjdGlvbiAoMzg1MCBkaXNrIEkvTyBlcnJvcilcIjtcblxuZXhwb3J0IGNsYXNzIFdlYlNxbEFwaSBleHRlbmRzIFNxbEFwaUFCQyB7XG4gICAgY29uc3RydWN0b3IoQEluamVjdChcIlwiKSBkYk5hbWU6IHN0cmluZywgQEluamVjdChbXSkgZGJTY2hlbWE6IHN0cmluZ1tdKSB7XG4gICAgICAgIHN1cGVyKGRiTmFtZSwgZGJTY2hlbWEpO1xuICAgIH1cblxuICAgIGFzeW5jIGlzT3BlbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGIgIT0gbnVsbDtcbiAgICB9XG5cbiAgICBhc3luYyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5kYiA9IG51bGw7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGFzeW5jIF9vcGVuRGIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCByZXRyaWVzID0gNTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX29wZW5XcmFwcGVkKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSBlcnIubWVzc2FnZSA/IGVyci5tZXNzYWdlIDogZXJyO1xuICAgICAgICAgICAgICAgIGlmIChyZXRyaWVzID49IDAgJiYgV2ViU3FsQXBpLmNoZWNrUmV0cnlNZXNzYWdlKGVycikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0cmllcy0tO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcigpLCAxMDAgKyByYW5kb20oKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9vcGVuV3JhcHBlZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKGF3YWl0IHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGIgPSBvcGVuRGF0YWJhc2UodGhpcy5kYk5hbWUsIFwiMVwiLCB0aGlzLmRiTmFtZSwgNCAqIDEwMjQgKiAxMDI0KTtcblxuICAgICAgICBhd2FpdCB0aGlzLmluc3RhbGxTY2hlbWEoKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgdHJhbnNhY3Rpb24oXG4gICAgICAgIGV4ZWN1dGVEYXRhOiBTcWxFeGVjdXRlRGF0YVtdLFxuICAgICAgICBpc1F1ZXJ5OiBib29sZWFuXG4gICAgKTogUHJvbWlzZTxhbnlbXSB8IG51bGw+IHtcbiAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5pc09wZW4oKSkpIGF3YWl0IHRoaXMub3BlbigpO1xuXG4gICAgICAgIGxldCByZXRyaWVzID0gNTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3RyYW5zYWN0aW9uSW5uZXIoZXhlY3V0ZURhdGEsIGlzUXVlcnkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcmV0cmllcyA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIChXZWJTcWxBcGkuY2hlY2tSZXRyeU1lc3NhZ2UoZSkgfHwgV2ViU3FsQXBpLmlzTG9ja2VkTXNnKGUpKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXRyaWVzLS07XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiByKCksIDEwMCArIHJhbmRvbSgpKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF90cmFuc2FjdGlvbklubmVyKFxuICAgICAgICBleGVjdXRlRGF0YTogU3FsRXhlY3V0ZURhdGFbXSxcbiAgICAgICAgaXNRdWVyeTogYm9vbGVhblxuICAgICk6IFByb21pc2U8YW55W10gfCBudWxsPiB7XG4gICAgICAgIGV4ZWN1dGVEYXRhID0gWy4uLmV4ZWN1dGVEYXRhXTtcbiAgICAgICAgY29uc3QgZGF0YTogYW55W10gPSBbXTtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kYi50cmFuc2FjdGlvbigodCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4ZWNTcWwgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVkID0gZXhlY3V0ZURhdGEucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlZCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdC5leGVjdXRlU3FsKFxuICAgICAgICAgICAgICAgICAgICAgICAgZWQuc3FsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWQuYmluZFBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICh0cmFuc2FjdGlvbiwgcmVzdWx0cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcmVzdWx0czooU1FMUmVzdWx0U2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgICBpbnNlcnRJZDowLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgICAgcm93czooU1FMUmVzdWx0U2V0Um93TGlzdCl7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgbGVuZ3RoOjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgICByb3dzQWZmZWN0ZWQ6MFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzUXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQUxMIEdPT0QsIFJldHVybiB0aGUgcm93c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdHMucm93cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKHJlc3VsdHMucm93cy5pdGVtKGkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGVjdXRlRGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWNTcWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgKHR4LCBlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIgPSBlcnIgPT0gbnVsbCA/IHR4IDogZXJyOyAvLyBTb21ldGltZXMgdHggaXMgdGhlIGVyclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIubWVzc2FnZSA/IGVyci5tZXNzYWdlIDogZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGV4ZWNTcWwoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gaXNRdWVyeSA/IGRhdGEgOiBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGNoZWNrUmV0cnlNZXNzYWdlKG1lc3NhZ2U6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAobWVzc2FnZS5pbmRleE9mKFJFVFJZX05PX1NQQUNFKSAhPT0gLTEpIHJldHVybiB0cnVlO1xuXG4gICAgICAgIHJldHVybiBtZXNzYWdlLmluZGV4T2YoUkVUUllfRElTS19FUlJPUikgIT09IC0xO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzTG9ja2VkTXNnKGVycjogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG1zZyA9IGVyci50b1N0cmluZygpO1xuXG4gICAgICAgIGNvbnN0IGhhc05zU3FsRXJyb3IgPVxuICAgICAgICAgICAgbXNnLmluZGV4T2YoXCJTUUxJVEUuQUxMIC0gRGF0YWJhc2UgRXJyb3I1XCIpICE9PSAtMTtcblxuICAgICAgICAvLyB1bmFibGUgdG8gYmVnaW4gdHJhbnNhY3Rpb24gKDUgZGF0YWJhc2UgaXMgbG9ja2VkKVxuICAgICAgICBjb25zdCBoYXNXZWJTcWxFcnJvciA9IG1zZy5pbmRleE9mKFwiNSBkYXRhYmFzZSBpcyBsb2NrZWRcIikgIT09IC0xO1xuXG4gICAgICAgIGlmIChoYXNOc1NxbEVycm9yIHx8IGhhc1dlYlNxbEVycm9yKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gV2ViU1FMOiBGb3VuZCBlcnJvciBtZXNzYWdlIHRoYXQgaXNuJ3QgYSBsb2NrIDogJHttc2d9YFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuIl19