UNPKG

@opra/sqb

Version:

Opra SQB adapter package

89 lines (88 loc) 2.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SqbServiceBase = void 0; const core_1 = require("@opra/core"); const connect_1 = require("@sqb/connect"); const transactionKey = Symbol.for('transaction'); /** * @class SqbServiceBase * @template T - The data type class type of the resource */ class SqbServiceBase extends core_1.ServiceBase { /** * Constructs a new instance * * @param [options] - The options for the service. * @constructor */ constructor(options) { super(); this.db = options?.db; } /** * Executes the provided function within a transaction. * * @param callback - The function to be executed within the transaction. */ async withTransaction(callback) { const ctx = this.context; let closeSessionOnFinish = false; let connection = ctx[transactionKey]; if (!connection) { /** Determine the SqbClient or SqbConnection instance */ const db = await this.getConnection(); if (db instanceof connect_1.SqbConnection) { connection = db; } else { /** Acquire a connection. New connection should be at the end */ connection = await db.acquire({ autoCommit: false }); closeSessionOnFinish = true; } /** Store transaction connection in current context */ ctx[transactionKey] = connection; } const oldInTransaction = connection.inTransaction; connection.retain(); try { if (!oldInTransaction) await connection.startTransaction(); const out = await callback(connection, this); if (!oldInTransaction && connection.inTransaction) await connection.commit(); return out; } catch (e) { if (!oldInTransaction && connection.inTransaction) await connection.rollback(); throw e; } finally { delete ctx[transactionKey]; /** Release connection */ if (closeSessionOnFinish) { await connection.close(); } else connection.release(); } } /** * Retrieves the database connection. * * @protected * * @throws {Error} If the context or database is not set. */ getConnection() { const ctx = this.context; let db = ctx[transactionKey]; if (db) return db; db = typeof this.db === 'function' ? this.db(this) : this.db; if (db) return db; throw new Error(`Database not set!`); } } exports.SqbServiceBase = SqbServiceBase;