// db/db.ts // PostgreSQL connection import * as schema from "./schema.ts"; import { drizzle } from "drizzle-orm/node-postgres"; import { Pool } from "pg"; // Lazy initialization to ensure environment variables are loaded first let pool: Pool | null = null; type DbInstance = ReturnType; let dbInstance: DbInstance | null = null; function getPool(): Pool { if (!pool) { const connectionString = Deno.env.get("POSTGRES_OPTIONS"); if (!connectionString) { throw new Error("POSTGRES_OPTIONS environment variable is not set"); } pool = new Pool({ connectionString, connectionTimeoutMillis: 10000, // 10 second connection timeout idleTimeoutMillis: 30000, // 30 second idle timeout query_timeout: 30000, // 30 second query timeout // Resolve unqualified table names to the migrated schema first. // Keeping public first avoids FK mismatches when legacy memory schema tables exist. }); // Set search_path on first connection to ensure it's applied to all connections pool.on("connect", (client) => { client.query("SET search_path TO public, memory, checkpoints"); }); // Handle pool errors pool.on("error", (err) => { console.error("Unexpected error on idle client", err); }); } return pool; } function getDb() { if (!dbInstance) { dbInstance = drizzle({ client: getPool(), schema }); } return dbInstance; } // Export a proxy that lazily initializes the database connection export const db = new Proxy({} as DbInstance, { get(_target, prop) { const dbInstance = getDb(); return Reflect.get(dbInstance, prop); }, has(_target, prop) { return prop in getDb(); }, }); /** Check if database connection is available with timeout */ export async function checkDatabaseConnection(): Promise { try { // Add timeout to connection check const client = await Promise.race([ getPool().connect(), new Promise((_, reject) => setTimeout( () => reject(new Error("Database connection timeout")), 10000, ) ), ]); // Query with timeout await Promise.race([ client.query("SELECT 1"), new Promise((_, reject) => setTimeout(() => reject(new Error("Database query timeout")), 5000) ), ]); client.release(); return true; } catch (error) { console.error("Database connection check failed:", error); return false; } }