import hash from 'object-hash' import { DynamoDatabase } from './integrations/dynamo/DynamoDatabase.js' import { KnexDatabase } from './integrations/knex/KnexDatabase.js' import { KyselyDatabase } from './integrations/kysely/KyselyDatabase.js' import { PostgresDatabase } from './integrations/pgsql/PostgresDatabase.js' import type { DatabaseImplType, DatabaseType, DbConfig } from './types.js' /** * Object containing different database implementations. * @type {Object} * @property {KnexDatabase} knex - Knex database implementation * @property {PostgresDatabase} pg - Postgres database implementation * @property {KyselyDatabase} kysely - Kysely database implementation */ export const DATABASES = { knex: KnexDatabase, pg: PostgresDatabase, kysely: KyselyDatabase, dynamo: DynamoDatabase, } /** * Manages the creation and storage of database instances. */ export class DatabaseManager { /** * Singleton instance of the DatabaseManager class. * This instance is used to interact with the database. */ public static readonly INSTANCE = new DatabaseManager() /** * A private property that holds a reference to the DATABASES constant. * @type {typeof DATABASES} */ private databases: typeof DATABASES = DATABASES /** * An object that stores instances of DatabaseImplType objects with keys of type string. * @type {Object.>} */ private instances: { [k: string]: DatabaseImplType } = {} /** * Creates a database instance based on the provided configuration. * @param {DbConfig} config - The configuration object for the database. * @returns {DatabaseImplType} An instance of the database based on the configuration. */ public create( config: DbConfig ): DatabaseImplType { const configHash = hash(config) if (this.instances[configHash]) { return this.instances[configHash] as any } const instance = this.instantiateDb(config as any) this.instances[configHash] = instance return instance } /** * Instantiates a database connection based on the provided configuration. * @param {DbConfig<'knex'> | DbConfig<'pg'> | DbConfig<'kysely'>} config - The configuration object specifying the type of database. * @returns {DatabaseImplType} An instance of the specified database connection. */ private instantiateDb( config: DbConfig<'knex'> | DbConfig<'pg'> | DbConfig<'kysely'> | DbConfig<'dynamo'> ): DatabaseImplType { return new this.databases[config.type](config as any) as any } }