UNPKG

@t1mmen/srtd

Version:

Supabase Repeatable Template Definitions (srtd): 🪄 Live-reloading SQL templates for Supabase DX. Make your database changes reviewable and migrations maintainable! 🚀

93 lines • 2.6 kB
// utils/databaseConnection.ts import pg from 'pg'; import { getConfig } from './config.js'; import { logger } from './logger.js'; let pool; let connectionAttempts = 0; const MAX_RETRIES = 3; export const RETRY_DELAY = 1000; async function createPool() { // Only create a new pool if one doesn't exist or has been ended if (!pool || pool.ended) { const config = await getConfig(process.cwd()); pool = new pg.Pool({ connectionString: config.pgConnection, connectionTimeoutMillis: 2000, max: MAX_RETRIES, idleTimeoutMillis: 1000, maxUses: 500, }); // Handle pool errors pool.on('error', err => { logger.error(`Unexpected pool error: ${err}`); }); } return pool; } async function retryConnection(params) { const { silent = true } = params || {}; connectionAttempts++; logger.debug(`Connection attempt ${connectionAttempts}`); try { const currentPool = await createPool(); return await currentPool.connect(); } catch (err) { if (connectionAttempts < MAX_RETRIES) { if (!silent) { logger.warn(`Connection failed, retrying in ${RETRY_DELAY}ms...`); } await new Promise(resolve => setTimeout(resolve, RETRY_DELAY)); return retryConnection(params); } throw new Error(`Database connection failed after ${MAX_RETRIES} attempts: ${err}`); } } export async function connect(params) { connectionAttempts = 0; return await retryConnection(params); } export async function disconnect() { if (!pool || pool.ended) return; try { await pool.end(); } catch (e) { logger.error(`Pool end error: ${e}`); } finally { pool = undefined; // Important: clear the pool reference } } export async function testConnection() { try { const client = await connect(); try { await client.query('SELECT 1'); return true; } finally { client.release(); } } catch { return false; } } export function getConnectionStats() { if (!pool) return null; return { total: pool.totalCount, idle: pool.idleCount, active: pool.totalCount - pool.idleCount, }; } // Handle process termination function cleanup() { void disconnect().then(() => process.exit(0)); } process.on('SIGTERM', cleanup); process.on('SIGINT', cleanup); //# sourceMappingURL=databaseConnection.js.map