@dossierhq/sqlite-core
Version:
A library used by concrete SQLite adapters for Dossier.
91 lines • 3.48 kB
JavaScript
/// <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