import mysql from 'mysql2'; import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; import config from './config.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Create database connection const connection = mysql.createConnection(config.connection); // Ensure migrations table exists function ensureMigrationsTable() { const createTableQuery = ` CREATE TABLE IF NOT EXISTS ${config.tableName} ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `; return new Promise((resolve, reject) => { connection.execute(createTableQuery, (err) => { if (err) reject(err); else resolve(); }); }); } // Get list of already executed migrations function getExecutedMigrations() { const query = `SELECT name FROM ${config.tableName} ORDER BY executed_at`; return new Promise((resolve, reject) => { connection.execute(query, (err, results) => { if (err) reject(err); else resolve(results.map(row => row.name)); }); }); } // Execute a migration file function executeMigration(migrationName, sqlContent) { return new Promise((resolve, reject) => { connection.execute(sqlContent, (err) => { if (err) reject(err); else { // Log the execution in migrations table const logQuery = `INSERT INTO ${config.tableName} (name) VALUES (?)`; connection.execute(logQuery, [migrationName], (logErr) => { if (logErr) reject(logErr); else resolve(); }); } }); }); } // Get all migration files async function getMigrationFiles() { try { const files = await fs.readdir(config.migrationsDir); return files .filter(file => file.endsWith('.sql')) .sort((a, b) => a.localeCompare(b)); } catch (err) { if (err.code === 'ENOENT') { // Directory doesn't exist, create it await fs.mkdir(config.migrationsDir, { recursive: true }); return []; } throw err; } } // Run migrations async function runMigrations() { try { await ensureMigrationsTable(); const executed = await getExecutedMigrations(); const allMigrations = await getMigrationFiles(); const pending = allMigrations.filter(name => !executed.includes(name)); if (pending.length === 0) { console.log('No pending migrations'); return; } console.log(`Running ${pending.length} migrations...`); for (const migrationName of pending) { console.log(`Executing ${migrationName}`); const filePath = path.join(config.migrationsDir, migrationName); const sqlContent = await fs.readFile(filePath, 'utf8'); await executeMigration(migrationName, sqlContent); } console.log('All migrations executed successfully'); } catch (err) { console.error('Error running migrations:', err); throw err; } finally { connection.end(); } } // Run the migrations if (process.argv.includes('--run')) { runMigrations().catch(console.error); } export { runMigrations };