/** * PostgreSQL database client with connection pooling */ import { Pool, PoolConfig, QueryResult, QueryResultRow } from 'pg'; // Re-export types for use in other modules export type { QueryResult, QueryResultRow }; export interface DatabaseConfig { connectionString?: string; host?: string; port?: number; database?: string; user?: string; password?: string; max?: number; idleTimeoutMillis?: number; connectionTimeoutMillis?: number; } /** * Create a PostgreSQL connection pool */ export function createPool(config: DatabaseConfig): Pool { const poolConfig: PoolConfig = { connectionString: config.connectionString, host: config.host, port: config.port, database: config.database, user: config.user, password: config.password, max: config.max || 20, idleTimeoutMillis: config.idleTimeoutMillis || 30000, connectionTimeoutMillis: config.connectionTimeoutMillis || 2000, }; return new Pool(poolConfig); } /** * Default database pool instance */ let defaultPool: Pool | null = null; /** * Get or create the default database pool */ export function getPool(config?: DatabaseConfig): Pool { if (!defaultPool) { if (!config) { throw new Error('Database configuration required for first pool creation'); } defaultPool = createPool(config); } return defaultPool; } /** * Execute a query */ export async function query( text: string, params?: unknown[] ): Promise> { if (!defaultPool) { throw new Error('Database pool not initialized. Call getPool() with configuration first.'); } return defaultPool.query(text, params); } /** * Close the database pool */ export async function closePool(): Promise { if (defaultPool) { await defaultPool.end(); defaultPool = null; } } /** * Health check for database connection */ export async function healthCheck(): Promise { try { const pool = getPool(); await pool.query('SELECT 1'); return true; } catch { return false; } }