import Database from 'better-sqlite3'; import { mkdirSync } from 'node:fs'; import { dirname } from 'node:path'; import { migrations } from './migrations.js'; export type DB = Database.Database; export function openDatabase(path: string): DB { if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }); const db = new Database(path); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); migrate(db); return db; } function migrate(db: DB): void { db.exec('CREATE TABLE IF NOT EXISTS schema_migrations (id INTEGER PRIMARY KEY, applied_at INTEGER NOT NULL)'); const applied = new Set( db.prepare('SELECT id FROM schema_migrations').all().map((r) => (r as { id: number }).id), ); const record = db.prepare('INSERT INTO schema_migrations (id, applied_at) VALUES (?, ?)'); for (const m of migrations) { if (applied.has(m.id)) continue; db.transaction(() => { db.exec(m.sql); record.run(m.id, Math.floor(Date.now() / 1000)); })(); } }