const { Pool } = require('pg'); const { neon } = require('@neondatabase/serverless'); // Database configuration const DB_CONFIG = { // Use Neon serverless for edge deployments connectionString: process.env.DATABASE_URL || process.env.NEON_DATABASE_URL, ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false, }; // Create connection pool for traditional deployment const pool = new Pool(DB_CONFIG); // Create Neon serverless client for edge/serverless deployment let neonClient = null; if (DB_CONFIG.connectionString) { neonClient = neon(DB_CONFIG.connectionString); } /** * Get database client - either pool connection or Neon serverless * @returns {Promise} Database client */ async function getDbClient() { if (process.env.USE_NEON_SERVERLESS === 'true' && neonClient) { return neonClient; } return pool.connect(); } /** * Execute a query using the appropriate client * @param {string} query - SQL query * @param {any[]} params - Query parameters * @returns {Promise} Query result */ async function executeQuery(query, params = []) { if (process.env.USE_NEON_SERVERLESS === 'true' && neonClient) { // Neon serverless client return await neonClient(query, params); } else { // Traditional pool connection const client = await pool.connect(); try { const result = await client.query(query, params); return result.rows; } finally { client.release(); } } } /** * Execute a transaction * @param {Function} callback - Function to execute within transaction * @returns {Promise} Transaction result */ async function executeTransaction(callback) { if (process.env.USE_NEON_SERVERLESS === 'true' && neonClient) { // For Neon serverless, we'll need to handle this differently // Note: Neon serverless doesn't support traditional transactions // Each query is automatically committed return await callback(neonClient); } else { const client = await pool.connect(); try { await client.query('BEGIN'); const result = await callback(client); await client.query('COMMIT'); return result; } catch (error) { await client.query('ROLLBACK'); throw error; } finally { client.release(); } } } /** * Close all database connections */ async function closeConnections() { if (pool) { await pool.end(); } } module.exports = { pool, neonClient, getDbClient, executeQuery, executeTransaction, closeConnections, DB_CONFIG };