Files
2026-10-21 14:50:31 +02:00

58 lines
1.6 KiB
JavaScript

import Database from 'better-sqlite3';
import { mkdirSync, readdirSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { getPaths } from './config.mjs';
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
export function migrate(databasePath = getPaths().database) {
mkdirSync(path.dirname(databasePath), { recursive: true });
mkdirSync(getPaths().uploads, { recursive: true });
const database = new Database(databasePath);
database.pragma('foreign_keys = ON');
database.exec(`
CREATE TABLE IF NOT EXISTS schema_migrations (
name TEXT PRIMARY KEY,
applied_at_utc TEXT NOT NULL
)
`);
const applied = new Set(
database
.prepare('SELECT name FROM schema_migrations')
.all()
.map((row) => row.name)
);
const migrations = readdirSync(path.join(projectRoot, 'migrations'))
.filter((name) => /^\d+.+\.sql$/.test(name))
.sort();
for (const name of migrations) {
if (applied.has(name)) continue;
const sql = readFileSync(path.join(projectRoot, 'migrations', name), 'utf8');
database.exec('BEGIN IMMEDIATE');
try {
database.exec(sql);
database
.prepare('INSERT INTO schema_migrations (name, applied_at_utc) VALUES (?, ?)')
.run(name, new Date().toISOString());
database.exec('COMMIT');
console.log(`Migration applied: ${name}`);
} catch (error) {
database.exec('ROLLBACK');
database.close();
throw error;
}
}
database.close();
console.log(`Database ready: ${databasePath}`);
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
migrate();
}