Files
formulation/scripts/lib/migrations.mjs
T

25 lines
1.2 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
export function applyMigrations(database, options = {}) {
const migrationsDirectory = options.migrationsDirectory ?? path.resolve(process.cwd(), "migrations");
const names = fs.readdirSync(migrationsDirectory).filter((name) => /^\d+.*\.sql$/.test(name)).sort((left, right) => Number(left.match(/^\d+/)[0]) - Number(right.match(/^\d+/)[0]));
database.exec("CREATE TABLE IF NOT EXISTS schema_migrations (version INTEGER PRIMARY KEY, name TEXT NOT NULL, applied_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP)");
const applied = [];
for (const name of names) {
const version = Number(name.match(/^\d+/)[0]);
if (database.prepare("SELECT 1 FROM schema_migrations WHERE version = ?").get(version)) continue;
database.exec("BEGIN IMMEDIATE");
try {
database.exec(fs.readFileSync(path.join(migrationsDirectory, name), "utf8"));
database.prepare("INSERT INTO schema_migrations(version, name) VALUES (?, ?)").run(version, name);
database.exec("COMMIT");
applied.push(name);
} catch (error) {
database.exec("ROLLBACK");
throw new Error(`Failed database migration ${name}`, { cause: error });
}
}
return applied;
}