UNPKG

@electric-sql/drivers

Version:

ElectricSQL database drivers.

114 lines 3.07 kB
import { Mutex } from "async-mutex"; class DatabaseAdapter { txMutex; constructor() { this.txMutex = new Mutex(); } async _transaction(f) { await this._run({ sql: "BEGIN" }); return new Promise((resolve, reject) => { const tx = new Transaction(this, reject); f(tx, (res) => { this._run({ sql: "COMMIT" }).then(() => { resolve(res); }).catch(reject); }); }).catch((err) => { return this._run({ sql: "ROLLBACK" }).then(() => { throw err; }); }); } async transaction(f) { return this.txMutex.runExclusive(() => { return this._transaction(f); }); } run(stmt) { return this.txMutex.runExclusive(() => { return this._run(stmt); }); } query(stmt) { return this.txMutex.runExclusive(() => { return this._query(stmt); }); } runInTransaction(...statements) { return this.txMutex.runExclusive(() => { return this._runInTransaction(...statements); }); } async _runExclusively(f) { const adapter = { run: this._run.bind(this), query: this._query.bind(this), transaction: this._transaction.bind(this), runInTransaction: this._runInTransaction.bind(this) }; return await f(adapter); } runExclusively(f) { return this.txMutex.runExclusive(() => { return this._runExclusively(f); }); } get isLocked() { return this.txMutex.isLocked(); } } class BatchDatabaseAdapter extends DatabaseAdapter { async _runInTransaction(...statements) { return this.execBatch(statements); } } class SerialDatabaseAdapter extends DatabaseAdapter { async _runInTransaction(...statements) { let transactionBegan = false; let rowsAffected = 0; try { await this._run({ sql: "BEGIN" }); transactionBegan = true; for (const stmt of statements) { const { rowsAffected: rowsModified } = await this._run(stmt); rowsAffected += rowsModified; } await this._run({ sql: "COMMIT" }); return { rowsAffected }; } catch (error) { if (transactionBegan) { await this._run({ sql: "ROLLBACK" }); } throw error; } } } class Transaction { constructor(adapter, signalFailure) { this.adapter = adapter; this.signalFailure = signalFailure; } invokeCallback(prom, successCallback, errorCallback) { prom.then((res) => { if (typeof successCallback !== "undefined") successCallback(this, res); }).catch((err) => { if (typeof errorCallback !== "undefined") errorCallback(err); this.signalFailure(err); }); } run(statement, successCallback, errorCallback) { const prom = this.adapter._run(statement); this.invokeCallback(prom, successCallback, errorCallback); } query(statement, successCallback, errorCallback) { const prom = this.adapter._query(statement); this.invokeCallback(prom, successCallback, errorCallback); } } export { BatchDatabaseAdapter, SerialDatabaseAdapter }; //# sourceMappingURL=adapter.js.map