import type { AnySchemas, AnyRelations } from "../orm/index.ts" import { PglightDatabase as RawDatabase, PglightTransaction as RawTransaction } from "./pglight.ts" export type PglightNormalDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > = RawDatabase export type PglightTransactionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, // oxlint-disable-next-line typescript/no-explicit-any > = RawTransaction export type PglightUnionDatabase = | PglightNormalDatabase | PglightTransactionDatabase export interface WithPglightUnionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > { database: PglightUnionDatabase } export interface WithOptionalPglightUnionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > { database?: PglightUnionDatabase | undefined } export type WithoutPglightUnionDatabase = Omit export const isPglightNormalDatabase = ( database: unknown, ): database is PglightNormalDatabase => { return database instanceof RawDatabase } export type GetIsPglightNormalDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > = (database: unknown) => database is PglightNormalDatabase export const getIsPglightNormalDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >(): GetIsPglightNormalDatabase => { return isPglightNormalDatabase } export const isPglightTransactionDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >( database: unknown, ): database is PglightTransactionDatabase => { return database instanceof RawTransaction } export type GetIsPglightTransactionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > = (database: unknown) => database is PglightTransactionDatabase export const getIsPglightTransactionDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >(): GetIsPglightTransactionDatabase => { return isPglightTransactionDatabase } export const isPglightUnionDatabase = ( database: unknown, ): database is PglightUnionDatabase => { if (isPglightTransactionDatabase(database) === true) { return true } if (isPglightNormalDatabase(database) === true) { return true } return false } export type GetIsPglightUnionDatabase< Schemas extends AnySchemas, Relations extends AnyRelations, > = (database: unknown) => database is PglightUnionDatabase export const getIsPglightUnionDatabase = < Schemas extends AnySchemas, Relations extends AnyRelations, >(): GetIsPglightUnionDatabase => { return isPglightUnionDatabase } export type AutoPglightDatabaseTransaction = < Result, Schemas extends AnySchemas, Relations extends AnyRelations, >( database: PglightUnionDatabase, run: (database: PglightTransactionDatabase) => Promise, ) => Promise export const autoPglightDatabaseTransaction: AutoPglightDatabaseTransaction = async < Result, Schemas extends AnySchemas, Relations extends AnyRelations, >( database: PglightUnionDatabase, run: (database: PglightTransactionDatabase) => Promise, ): Promise => { // detect transaction database first, then normal database // because transaction database is a subclass of normal database if (isPglightTransactionDatabase(database)) { return await run(database) } if (isPglightNormalDatabase(database)) { return await database.transaction(async (database) => { return await run(database) }) } throw new Error("Invalid database instance") } export type GetAutoPglightDatabaseTransaction< Schemas extends AnySchemas, Relations extends AnyRelations, > = ( database: PglightUnionDatabase, run: (database: PglightTransactionDatabase) => Promise, ) => Promise export const getAutoPglightDatabaseTransaction = < Schemas extends AnySchemas, Relations extends AnyRelations, >() => { return async ( database: PglightUnionDatabase, run: (database: PglightTransactionDatabase) => Promise, ): Promise => { return await autoPglightDatabaseTransaction(database, run) } }