Finish setting up basic db migrations
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import * as path from 'path'
|
||||
import { promises as fs } from 'fs'
|
||||
import { FileMigrationProvider, Migrator, type MigrationResultSet } from 'kysely/migration'
|
||||
import { db } from './db'
|
||||
import { argv } from 'bun'
|
||||
import { env, log } from '../util'
|
||||
|
||||
type HandlerResult = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
function processResults(label: string, { error, results }: MigrationResultSet): string {
|
||||
let message = "";
|
||||
|
||||
results?.forEach((it) => {
|
||||
if (it.status === 'Success') {
|
||||
message = `migration ${label} succeeded: "${it.migrationName}"`;
|
||||
} else if (it.status === 'Error') {
|
||||
throw new Error(`migration ${label} failed: "${it.migrationName}"`);
|
||||
}
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
const handlers: Record<string, (migrator: Migrator) => Promise<HandlerResult>> = {
|
||||
"up": async function (migrator: Migrator) {
|
||||
const resultSet = await migrator.migrateUp();
|
||||
const message = processResults("up", resultSet);
|
||||
|
||||
return { message };
|
||||
},
|
||||
"down": async function (migrator: Migrator) {
|
||||
const resultSet = await migrator.migrateDown();
|
||||
const message = processResults("down", resultSet);
|
||||
|
||||
return { message };
|
||||
},
|
||||
"latest": async function (migrator: Migrator) {
|
||||
const resultSet = await migrator.migrateToLatest();
|
||||
const message = processResults("to latest", resultSet);
|
||||
|
||||
return { message };
|
||||
},
|
||||
"rollback": async function (migrator: Migrator) {
|
||||
let count = 0;
|
||||
|
||||
while (true) {
|
||||
const resultSet = await migrator.migrateDown();
|
||||
if (!resultSet.results?.length) break;
|
||||
|
||||
processResults("rollback", resultSet);
|
||||
++count;
|
||||
}
|
||||
|
||||
return { message: `rolled back ${count} migration(s)` };
|
||||
}
|
||||
};
|
||||
|
||||
// Main
|
||||
(async () => {
|
||||
const command = argv[2] ?? "";
|
||||
if (!handlers[command]) throw new Error("Unrecognized command");
|
||||
|
||||
const answer = prompt(`Run "${command}" migration against ${env.DATABASE_URL}? (y/N)`);
|
||||
if (answer?.trim().toLowerCase() !== "y") {
|
||||
log.info("Aborted");
|
||||
await db.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
const migrator = new Migrator({
|
||||
db,
|
||||
provider: new FileMigrationProvider({
|
||||
fs,
|
||||
path,
|
||||
// This needs to be an absolute path.
|
||||
migrationFolder: path.join(__dirname, "migrations"),
|
||||
}),
|
||||
});
|
||||
|
||||
try {
|
||||
const result = await handlers[command](migrator);
|
||||
log.info({ name: command, result }, "finished");
|
||||
}
|
||||
catch (err) {
|
||||
log.error({ name: command, err }, "failed");
|
||||
process.exit(1)
|
||||
}
|
||||
finally {
|
||||
await db.destroy()
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user