require('dotenv').config(); const mysql = require('mysql2/promise'); const config = require('./index'); // Create a connection pool const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, waitForConnections: true, connectionLimit: 10, queueLimit: 0, enableKeepAlive: true, keepAliveInitialDelay: 0, namedPlaceholders: true, connectTimeout: 10000, idleTimeout: 60000, maxIdle: 10 }); // Test the connection pool.getConnection() .then(connection => { console.log('Database connected successfully'); connection.release(); }) .catch(err => { console.error('Error connecting to the database:', err); process.exit(1); }); // Handle pool errors pool.on('error', (err) => { console.error('Unexpected error on idle connection', err); process.exit(-1); }); // Query with retry logic const queryWithRetry = async (sql, params, maxRetries = 3) => { let lastError; for (let i = 0; i < maxRetries; i++) { try { const [results] = await pool.query(sql, params); return results; } catch (error) { lastError = error; console.error(`Database query error (attempt ${i + 1}/${maxRetries}):`, error); if (error.code === 'PROTOCOL_CONNECTION_LOST' || error.code === 'ECONNRESET' || error.code === 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR') { console.log(`Database connection lost. Retry attempt ${i + 1} of ${maxRetries}`); await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); continue; } throw error; } } throw lastError; }; // Health check function const checkDatabaseConnection = async () => { try { await pool.query('SELECT 1'); return true; } catch (error) { console.error('Database health check failed:', error); return false; } }; // Graceful shutdown const closePool = async () => { try { await pool.end(); console.log('Database pool closed successfully'); } catch (error) { console.error('Error closing database pool:', error); throw error; } }; module.exports = { query: queryWithRetry, checkConnection: checkDatabaseConnection, closePool };