69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
import fs from "node:fs";
|
|
import { readdir } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import dbClient from "./index.js";
|
|
|
|
const __dirname = import.meta.dirname;
|
|
|
|
const createMigrationTable = () => {
|
|
return dbClient.query(`
|
|
CREATE TABLE IF NOT EXISTS migrations (
|
|
id VARCHAR(255) PRIMARY KEY,
|
|
name VARCHAR(255),
|
|
executed_at TIMESTAMP
|
|
)
|
|
`);
|
|
}
|
|
|
|
const getMigrationsFiles = () => {
|
|
try {
|
|
return readdir(path.resolve(__dirname, "./migrations"));
|
|
} catch(err) {
|
|
return new Error("[Migration] getMigrations err: ", err);
|
|
}
|
|
};
|
|
|
|
const runMigrations = async () => {
|
|
try {
|
|
// Create migration table if needed
|
|
await createMigrationTable();
|
|
|
|
const migrationFiles = await getMigrationsFiles();
|
|
const migrationsDb = await dbClient.query("SELECT name FROM migrations WHERE executed_at IS NOT NULL");
|
|
const migrationsToRun = migrationFiles.filter(m => !migrationsDb.rows.map(m => m.name).includes(m));
|
|
|
|
console.log("[Migration] migrations to run: ", migrationsToRun);
|
|
|
|
for (const migration of migrationsToRun) {
|
|
await dbClient.query("BEGIN");
|
|
const sqlQuery = fs.readFileSync(path.resolve(__dirname, `./migrations/${migration}`), "utf-8");
|
|
try {
|
|
await dbClient.query(sqlQuery);
|
|
|
|
await dbClient.query({
|
|
text: "INSERT INTO migrations(id, name, executed_at) VALUES($1, $2, $3)",
|
|
values: [migration.slice(0, -4), migration, new Date().toISOString().slice(0, 19).replace('T', ' ')]
|
|
});
|
|
|
|
await dbClient.query("COMMIT");
|
|
} catch(err) {
|
|
console.log(err);
|
|
await dbClient.query("ROLLBACK");
|
|
}
|
|
}
|
|
|
|
console.log("[Migration]: SUCCESS");
|
|
} catch (err) {
|
|
console.error("Error", err);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
// Run this from CLI
|
|
if (import.meta.main) {
|
|
console.log("Run migrations");
|
|
runMigrations()
|
|
.then(() => process.exit(0))
|
|
.catch(() => process.exit(1));
|
|
}
|