UNPKG

@dossierhq/sqlite-core

Version:

A library used by concrete SQLite adapters for Dossier.

91 lines 3.48 kB
/// <reference types="./SqliteTransaction.d.ts" /> import { notOk } from '@dossierhq/core'; import { queryRun } from './QueryFunctions.js'; import { withQueryPerformance } from './utils/withQueryPerformance.js'; export function getTransactionTimestamp(transaction) { if (transaction && 'transactionTimestamp' in transaction) { return transaction.transactionTimestamp; } return new Date(); } export async function withRootTransaction(database, context, childContextFactory, callback) { if (context.transaction) { return notOk.Generic('Trying to create a root transaction with current transaction'); } const now = new Date(); const adapterTransaction = database.adapter.createTransaction(); const transaction = { _type: 'Transaction', savePointCount: 0, transactionTimestamp: now, adapterTransaction, }; const childContext = childContextFactory(transaction); return await database.mutex.withLock(childContext, async () => { // BEGIN if (adapterTransaction) { try { await withQueryPerformance(childContext, 'BEGIN', () => adapterTransaction.begin()); } catch (error) { return notOk.GenericUnexpectedException(childContext, error); } } else { const beginResult = await queryRun(database, childContext, 'BEGIN'); if (beginResult.isError()) return beginResult; } // transaction body let result; try { result = await callback(childContext); } catch (error) { result = notOk.GenericUnexpectedException(childContext, error); } // COMMIT or ROLLBACK if (adapterTransaction) { try { if (result.isOk()) { await withQueryPerformance(childContext, 'COMMIT', () => adapterTransaction.commit()); } else { await withQueryPerformance(childContext, 'ROLLBACK', () => adapterTransaction.rollback()); } } catch (error) { result = notOk.GenericUnexpectedException(childContext, error); } finally { adapterTransaction.close(); } } else { const commitOrRollbackResult = await queryRun(database, childContext, result.isOk() ? 'COMMIT' : 'ROLLBACK'); if (commitOrRollbackResult.isError()) { result = commitOrRollbackResult; } } return result; }); } export async function withNestedTransaction(database, context, transaction, callback) { const sqliteTransaction = transaction; const savePointName = `nested${sqliteTransaction.savePointCount++}`; const savePointResult = await queryRun(database, context, `SAVEPOINT ${savePointName}`); if (savePointResult.isError()) return savePointResult; let result; try { result = await callback(); } catch (error) { result = notOk.GenericUnexpectedException(context, error); } const releaseOrRollbackResult = await queryRun(database, context, result.isOk() ? `RELEASE ${savePointName}` : `ROLLBACK TO ${savePointName}`); if (releaseOrRollbackResult.isError()) return releaseOrRollbackResult; return result; } //# sourceMappingURL=SqliteTransaction.js.map