| import Database from 'better-sqlite3'; |
| import { drizzle } from 'drizzle-orm/better-sqlite3'; |
| import * as schema from './db/schema'; |
| import fs from 'node:fs'; |
| import path from 'node:path'; |
|
|
| const DB_FILE = process.env.DB_FILE || './data.sqlite'; |
|
|
| export const sqlite = new Database(DB_FILE); |
| sqlite.pragma('journal_mode = WAL'); |
| sqlite.pragma('foreign_keys = ON'); |
|
|
| export const db = drizzle(sqlite, { schema }); |
|
|
| |
| export function applyMigrations(): void { |
| const migrationsDir = path.join(process.cwd(), 'drizzle'); |
| if (!fs.existsSync(migrationsDir)) return; |
| sqlite.exec(`CREATE TABLE IF NOT EXISTS _migrations ( |
| name TEXT PRIMARY KEY, |
| applied_at INTEGER NOT NULL |
| )`); |
| const rows = sqlite.prepare('SELECT name FROM _migrations').all() as { name: string }[]; |
| const applied = new Set(rows.map((r) => r.name)); |
| const files = fs.readdirSync(migrationsDir).filter((f) => f.endsWith('.sql')).sort(); |
| for (const f of files) { |
| if (applied.has(f)) continue; |
| const sql = fs.readFileSync(path.join(migrationsDir, f), 'utf8'); |
| try { |
| sqlite.exec(sql); |
| sqlite.prepare('INSERT INTO _migrations (name, applied_at) VALUES (?, ?)').run(f, Date.now()); |
| console.log('[migrate] applied', f); |
| } catch (err) { |
| console.error('[migrate] FAILED', f, err); |
| throw err; |
| } |
| } |
| } |
|
|