import * as pg from 'pg' import { PostgresDatabase } from './PostgresDatabase.js' import { Database } from '../../Database.js' import { DatabaseTransaction } from '../../DatabaseTransaction.js' /** * A type alias representing a Postgres transaction. It extends the `PostgresTransactionImpl` * interface and includes the `PoolClient` interface. */ export type PostgresTransaction = PostgresTransactionImpl & pg.PoolClient /** * Represents a transaction in a Postgres database. */ export class PostgresTransactionImpl extends DatabaseTransaction { /** * A Pool object used for writing operations. * @readonly */ public readonly writer!: pg.Pool /** * A readonly property representing a pool reader. */ public readonly reader!: pg.Pool /** * Represents a database transaction using a PoolClient. * @type {PoolClient} */ protected transaction!: pg.PoolClient /** * A protected property representing a database of type Database. * This property is used to interact with a Postgres database using transactions. */ protected database!: Database /** * Constructs a new instance of the class with the provided writer, database, and optional reader. * @param {Pool} writer - The writer pool for database operations. * @param {PostgresDatabase} database - The Postgres database instance. * @param {Pool} [reader] - The reader pool for database operations (optional). */ private constructor(writer: pg.Pool, database: PostgresDatabase, reader?: pg.Pool) { super(writer, database, reader) } /** * Creates a new database transaction using the provided writer and database instances. * @param {Pool} writer - The writer instance for the transaction. * @param {PostgresDatabase} database - The database instance for the transaction. * @param {Pool} [reader] - Optional reader instance for the transaction. * @returns {Promise} A promise that resolves to a new PostgresTransaction instance. */ public static async newTransaction( writer: pg.Pool, database: PostgresDatabase, reader?: pg.Pool ): Promise { const tx = new PostgresTransactionImpl(writer, database, reader) await tx.begin() // defaults to opened return DatabaseTransaction.proxyInstance(tx) as any } /** * Initiates a transaction by connecting to the writer and executing a 'BEGIN' query. * @returns {Promise} A promise that resolves when the transaction is successfully initiated. */ protected doBegin = async () => { this.transaction = await this.writer.connect() return this.transaction.query('BEGIN') } /** * Executes a COMMIT query to commit the current transaction. * @returns A Promise that resolves when the COMMIT query is successfully executed. */ protected doCommit = () => { return this.transaction.query('COMMIT') } /** * Rolls back the current transaction by executing a 'ROLLBACK' query. * @returns A Promise that resolves when the rollback is successful. */ protected doRollback = () => { return this.transaction.query('ROLLBACK') } }