1import { DataTypes, QueryTypes } from 'sequelize';
2import db from '../config/database.js';
3import migrations from '../migrations/index.js';
4
5const META_TABLE = 'SequelizeMeta';
6
7const ensureMetaTable = async (queryInterface) => {
8 const tables = await queryInterface.showAllTables();
9 if (tables.includes(META_TABLE)) return;
10
11 await queryInterface.createTable(META_TABLE, {
12 name: { type: DataTypes.STRING, allowNull: false, primaryKey: true }
13 });
14 console.log(`Created ${META_TABLE} table for tracking migrations`);
15};
16
17const getExecutedMigrations = async () => {
18 const rows = await db.query(`SELECT name FROM ${META_TABLE} ORDER BY name ASC`,
19 { type: QueryTypes.SELECT });
20 return new Set(rows.map(row => row.name));
21};
22
23export const runMigrations = async () => {
24 const queryInterface = db.getQueryInterface();
25 await ensureMetaTable(queryInterface);
26
27 const executed = await getExecutedMigrations();
28 const pending = migrations.filter(m => !executed.has(m.name));
29
30 if (pending.length === 0) {
31 console.log('No pending migrations found');
32 return;
33 }
34
35 console.log(`Found ${pending.length} pending migration(s)`);
36
37 for (const { name, up } of pending) {
38 console.log(`Running migration: ${name}`);
39 try {
40 await up(queryInterface, DataTypes);
41 await db.query(`INSERT INTO ${META_TABLE} (name) VALUES (?)`, { replacements: [name] });
42 console.log(`Migration ${name} completed successfully`);
43 } catch (error) {
44 console.error(`Migration ${name} failed:`, error.message);
45 throw error;
46 }
47 }
48
49 console.log('All migrations completed successfully');
50};
51
52export default runMigrations;
53