import { Pool } from "pg"; import prisma from "../prisma"; import db from "../db"; type PoolEntry = { pool: Pool; lastUsed: number; }; const poolCache = new Map(); const POOL_TTL_MS = 1000 * 60 * 30; // 30 minutes TTL for idle pools function buildConnString(db: { host: string; port: number; username: string; password: string; name: string; ssl?: boolean; }) { // Use pg connection string const { host, port, username, password, name, ssl } = db; return `postgresql://${encodeURIComponent(username)}:${encodeURIComponent( password )}@${host}:${port}/${encodeURIComponent(name)}${ ssl ? "?sslmode=require" : "" }`; } export async function getPoolForDbId(db_id: string) { // const now = Date.now(); // const cached = poolCache.get(db_id); // if (cached) { // cached.lastUsed = now; // return cached.pool; // } // load credentials from central metadata table (prisma database model) const dbRec = await prisma.database.findUnique({ where: { db_id } }); if (!dbRec) throw new Error("database not found"); const connString = buildConnString({ host: dbRec.host, port: Number(dbRec.port), username: dbRec.username, password: dbRec.password, name: dbRec.db_name, }); await db.activity_logs.create({ data: { action: "GET", status: "SUCCESS", message: "connString: " + connString, }, }); const pool = new Pool({ connectionString: connString, max: 10, idleTimeoutMillis: 3600000, }); return pool; } // optional: background cleanup setInterval(() => { const now = Date.now(); for (const [key, entry] of poolCache.entries()) { if (now - entry.lastUsed > POOL_TTL_MS) { try { entry.pool.end().catch(() => {}); } catch {} poolCache.delete(key); } } }, 1000 * 60 * 5);