import { Database } from 'bun:sqlite'; import { mkdirSync, readdirSync, readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; const MIGRATIONS_DIR = join(import.meta.dir, 'migrations'); export function openDb(path: string): Database { if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }); const db = new Database(path, { create: true, strict: true }); db.exec('PRAGMA journal_mode = WAL;'); db.exec('PRAGMA synchronous = NORMAL;'); db.exec('PRAGMA foreign_keys = ON;'); db.exec('PRAGMA busy_timeout = 5000;'); migrate(db); return db; } export function migrate(db: Database): void { db.exec('CREATE TABLE IF NOT EXISTS schema_migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)'); const applied = new Set( db.query<{ name: string }, []>('SELECT name FROM schema_migrations').all().map((r) => r.name), ); const files = readdirSync(MIGRATIONS_DIR).filter((f) => f.endsWith('.sql')).sort(); for (const file of files) { if (applied.has(file)) continue; const sql = readFileSync(join(MIGRATIONS_DIR, file), 'utf8'); db.transaction(() => { db.exec(sql); db.query('INSERT INTO schema_migrations (name, applied_at) VALUES (?, ?)').run(file, Date.now()); })(); } }