2026-02-14 02:20:19 +00:00

87 lines
2.4 KiB
TypeScript
Executable File

// 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<typeof drizzle>;
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<boolean> {
try {
// Add timeout to connection check
const client = await Promise.race([
getPool().connect(),
new Promise<never>((_, 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;
}
}