62 lines
1.4 KiB
TypeScript
62 lines
1.4 KiB
TypeScript
// lib/db.ts
|
|
// Database connection pool - reuses connections efficiently
|
|
|
|
import { Pool } from 'pg';
|
|
|
|
// Singleton pattern - only create one pool for the entire app
|
|
let pool: Pool | null = null;
|
|
|
|
export function getPool(): Pool {
|
|
if (!pool) {
|
|
pool = new Pool({
|
|
host: process.env.DB_HOST || 'localhost',
|
|
port: parseInt(process.env.DB_PORT || '5432'),
|
|
database: process.env.DB_NAME || 'openwheels',
|
|
user: process.env.DB_USER || 'postgres',
|
|
password: process.env.DB_PASSWORD,
|
|
max: 20, // Maximum number of connections
|
|
idleTimeoutMillis: 30000,
|
|
connectionTimeoutMillis: 2000,
|
|
});
|
|
|
|
// Log pool errors
|
|
pool.on('error', (err) => {
|
|
console.error('Unexpected database error:', err);
|
|
});
|
|
}
|
|
|
|
return pool;
|
|
}
|
|
|
|
// Helper function for queries - handles errors nicely
|
|
export async function query<T = any>(
|
|
text: string,
|
|
params?: any[]
|
|
): Promise<T[]> {
|
|
const pool = getPool();
|
|
try {
|
|
const result = await pool.query(text, params);
|
|
return result.rows;
|
|
} catch (error) {
|
|
console.error('Database query error:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Helper for single row queries
|
|
export async function queryOne<T = any>(
|
|
text: string,
|
|
params?: any[]
|
|
): Promise<T | null> {
|
|
const rows = await query<T>(text, params);
|
|
return rows.length > 0 ? rows[0] : null;
|
|
}
|
|
|
|
// Graceful shutdown
|
|
export async function closePool(): Promise<void> {
|
|
if (pool) {
|
|
await pool.end();
|
|
pool = null;
|
|
}
|
|
}
|