enterprisecargo / src /db /migrator.js
vish85521's picture
Upload 64 files
eeb3436 verified
Raw
History Blame Contribute Delete
2.22 kB
const fs = require("fs");
const path = require("path");
function listSqlFiles(directory) {
if (!fs.existsSync(directory)) {
return [];
}
return fs
.readdirSync(directory)
.filter((name) => name.toLowerCase().endsWith(".sql"))
.sort((a, b) => a.localeCompare(b, "en"));
}
async function ensureTrackingTable(pool, tableName) {
if (!["schema_migrations", "seed_runs"].includes(tableName)) {
throw new Error(`Unsupported migration tracking table: ${tableName}`);
}
await pool.query(`
CREATE TABLE IF NOT EXISTS ${tableName} (
id BIGSERIAL PRIMARY KEY,
filename TEXT NOT NULL UNIQUE,
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
)
`);
}
async function readApplied(pool, tableName) {
const result = await pool.query(`SELECT filename FROM ${tableName}`);
return new Set(result.rows.map((row) => row.filename));
}
async function executeSqlFile(pool, filePath) {
const sql = fs.readFileSync(filePath, "utf8");
await pool.query(sql);
}
async function runSqlDirectory(pool, options) {
const { directory, trackingTable, logger, label } = options;
await ensureTrackingTable(pool, trackingTable);
const applied = await readApplied(pool, trackingTable);
const files = listSqlFiles(directory);
let appliedCount = 0;
for (const filename of files) {
if (applied.has(filename)) {
logger.debug(`${label} already applied`, { filename });
continue;
}
const absolutePath = path.join(directory, filename);
logger.info(`Applying ${label}`, { filename });
await executeSqlFile(pool, absolutePath);
await pool.query(`INSERT INTO ${trackingTable}(filename) VALUES ($1)`, [filename]);
appliedCount += 1;
}
return {
totalFiles: files.length,
appliedCount,
};
}
async function runMigrations(pool, migrationsDir, logger) {
return runSqlDirectory(pool, {
directory: migrationsDir,
trackingTable: "schema_migrations",
logger,
label: "migration",
});
}
async function runSeeds(pool, seedsDir, logger) {
return runSqlDirectory(pool, {
directory: seedsDir,
trackingTable: "seed_runs",
logger,
label: "seed",
});
}
module.exports = {
runMigrations,
runSeeds,
};