76 lines
1.8 KiB
TypeScript
76 lines
1.8 KiB
TypeScript
import { Pool } from "pg";
|
|
import prisma from "../prisma";
|
|
import db from "../db";
|
|
|
|
type PoolEntry = {
|
|
pool: Pool;
|
|
lastUsed: number;
|
|
};
|
|
|
|
const poolCache = new Map<string, PoolEntry>();
|
|
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);
|