← back to Patty

lib/db.ts

46 lines

import { Pool, PoolClient, QueryResult, QueryResultRow } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 10,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 5000,
});

// Log pool errors so they don't crash the process
pool.on('error', (err: Error) => {
  console.error('[db] Unexpected pool error:', err.message);
});

/**
 * Execute a parameterized query against the pool.
 * Returns the full QueryResult so callers can read .rows, .rowCount, etc.
 */
export async function query<T extends QueryResultRow = QueryResultRow>(
  text: string,
  params?: unknown[],
): Promise<QueryResult<T>> {
  const start = Date.now();
  try {
    const result = await pool.query<T>(text, params);
    const duration = Date.now() - start;
    if (duration > 2000) {
      console.warn(`[db] Slow query (${duration}ms):`, text.slice(0, 120));
    }
    return result;
  } catch (err) {
    console.error('[db] Query error:', (err as Error).message, '\n  SQL:', text.slice(0, 200));
    throw err;
  }
}

/**
 * Acquire a dedicated client from the pool — use for transactions.
 * IMPORTANT: Always call client.release() in a finally block.
 */
export async function getClient(): Promise<PoolClient> {
  return pool.connect();
}

export default pool;