import { Client, Pool } from 'pg';
import { ZQLDatabase } from "../zql-database.js";
export class NodePgConnection {
    #pool;
    constructor(pool) {
        this.#pool = pool;
    }
    async transaction(fn) {
        const client = this.#pool instanceof Pool ? await this.#pool.connect() : this.#pool;
        try {
            await client.query('BEGIN');
            const result = await fn(new NodePgTransactionInternal(client));
            await client.query('COMMIT');
            return result;
        }
        catch (error) {
            try {
                await client.query('ROLLBACK');
            }
            catch {
                // ignore rollback error; original error will be thrown
            }
            throw error;
        }
        finally {
            if (this.#pool instanceof Pool && 'release' in client) {
                client.release();
            }
        }
    }
}
export class NodePgTransactionInternal {
    wrappedTransaction;
    constructor(client) {
        this.wrappedTransaction = client;
    }
    async query(sql, params) {
        const res = await this.wrappedTransaction.query(sql, params);
        return res.rows;
    }
}
/**
 * Wrap a `pg` Pool for Zero ZQL.
 *
 * Provides ZQL querying plus access to the underlying node-postgres client.
 * Use {@link NodePgTransaction} to type your server mutator transaction.
 *
 * @param schema - Zero schema.
 * @param pg - `pg` Pool or connection string.
 *
 * @example
 * ```ts
 * import {Pool} from 'pg';
 *
 * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});
 * const zql = zeroNodePg(schema, pool);
 *
 * // Define the server mutator transaction type using the helper
 * type ServerTx = ServerTransaction<
 *   Schema,
 *   NodePgTransaction
 * >;
 *
 * async function createUser(
 *   tx: ServerTx,
 *   {id, name}: {id: string; name: string},
 * ) {
 *   await tx.dbTransaction.wrappedTransaction
 *     .query('SELECT * FROM "user" WHERE id = $1', [id]);
 * }
 * ```
 */
export function zeroNodePg(schema, pg) {
    if (typeof pg === 'string') {
        pg = new Pool({ connectionString: pg });
    }
    return new ZQLDatabase(new NodePgConnection(pg), schema);
}
//# sourceMappingURL=pg.js.map