import type { AnySchemas, AnyRelations } from "../orm/index.ts" import type { PgQueryResultHKT } from "./pgcore.ts" import { PgAsyncDatabase, PgAsyncTransaction } from "./pgcore.ts" export type PgNormalDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > = PgAsyncDatabase export type PgTransactionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, // oxlint-disable-next-line typescript/no-explicit-any > = PgAsyncTransaction export type PgUnionDatabase = | PgNormalDatabase | PgTransactionDatabase export interface WithPgUnionDatabase { database: PgUnionDatabase } export interface WithOptionalPgUnionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > { database?: PgUnionDatabase | undefined } export type WithoutPgUnionDatabase = Omit export const isPgNormalDatabase = ( database: unknown, ): database is PgNormalDatabase => { return database instanceof PgAsyncDatabase } export type GetIsPgNormalDatabase = ( database: unknown, ) => database is PgNormalDatabase export const getIsPgNormalDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >(): GetIsPgNormalDatabase => { return isPgNormalDatabase } export const isPgTransactionDatabase = ( database: unknown, ): database is PgTransactionDatabase => { return database instanceof PgAsyncTransaction } export type GetIsPgTransactionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > = (database: unknown) => database is PgTransactionDatabase export const getIsPgTransactionDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >(): GetIsPgTransactionDatabase => { return isPgTransactionDatabase } export const isPgUnionDatabase = ( database: unknown, ): database is PgUnionDatabase => { if (isPgTransactionDatabase(database) === true) { return true } if (isPgNormalDatabase(database) === true) { return true } return false } export type GetIsPgUnionDatabase = ( database: unknown, ) => database is PgUnionDatabase export const getIsPgUnionDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >(): GetIsPgUnionDatabase => { return isPgUnionDatabase } export type AutoPgDatabaseTransaction = < Result, Schemas extends AnySchemas, Relations extends AnyRelations, >( database: PgUnionDatabase, run: (database: PgTransactionDatabase) => Promise, ) => Promise export const autoPgDatabaseTransaction: AutoPgDatabaseTransaction = async < Result, Schemas extends AnySchemas, Relations extends AnyRelations, >( database: PgUnionDatabase, run: (database: PgTransactionDatabase) => Promise, ): Promise => { // detect transaction database first, then normal database // because transaction database is a subclass of normal database if (isPgTransactionDatabase(database) === true) { return await run(database) } if (isPgNormalDatabase(database) === true) { return await database.transaction(async (database) => { return await run(database) }) } throw new Error("Invalid database instance") } export type GetAutoPgDatabaseTransaction< Schemas extends AnySchemas, Relations extends AnyRelations, > = ( database: PgUnionDatabase, run: (database: PgTransactionDatabase) => Promise, ) => Promise export const getAutoPgDatabaseTransaction = < Schemas extends AnySchemas, Relations extends AnyRelations, >() => { return async ( database: PgUnionDatabase, run: (database: PgTransactionDatabase) => Promise, ): Promise => { return await autoPgDatabaseTransaction(database, run) } }