47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import { Database } from '@db/sqlite';
|
|
|
|
export function migrate(db: Database) {
|
|
const migrationDirEntries = Deno.readDirSync(import.meta.dirname + '/migrations');
|
|
const migrations = [];
|
|
for (const migration of migrationDirEntries) {
|
|
const content = Deno.readTextFileSync(
|
|
import.meta.dirname + `/migrations/${migration.name}`,
|
|
);
|
|
migrations.push([migration.name, content]);
|
|
}
|
|
|
|
migrations.sort((a, b) => a[0].localeCompare(b[0]));
|
|
|
|
const schemaVersionDesired = migrations.length;
|
|
const { user_version: schemaVersionDb } = db.prepare('pragma user_version').get<
|
|
{ user_version: number }
|
|
>()!;
|
|
|
|
let applyMigrations = false;
|
|
if (schemaVersionDb != schemaVersionDesired) {
|
|
console.error(
|
|
`The database schema is on ${schemaVersionDb}, but the desired version is ${schemaVersionDesired}`,
|
|
);
|
|
applyMigrations = confirm('Apply migrations?');
|
|
}
|
|
|
|
if (!applyMigrations) {
|
|
return;
|
|
}
|
|
|
|
const migrationsToApply = migrations.slice(schemaVersionDb);
|
|
const txn = db.transaction(() => {
|
|
for (const [name, migration] of migrationsToApply) {
|
|
try {
|
|
db.exec(migration);
|
|
} catch (e) {
|
|
throw new Error(`While running migration ${name}`, { cause: e });
|
|
}
|
|
}
|
|
|
|
db.exec(`pragma user_version = ${schemaVersionDesired}`);
|
|
});
|
|
|
|
txn.immediate();
|
|
}
|