// Applies drizzle migrations using drizzle-orm's bun-sqlite migrator. // // We deliberately do NOT use `drizzle-kit migrate` here: drizzle-kit loads // better-sqlite3 (native binding), which Bun's runtime can't dlopen on Linux // (oven-sh/bun#4290). The bun-sqlite migrator reads the same `./drizzle/*.sql` // that `drizzle-kit generate` produces, so there's no format drift. import { Database } from 'bun:sqlite'; import { drizzle } from 'drizzle-orm/bun-sqlite'; import { migrate } from 'drizzle-orm/bun-sqlite/migrator'; import { mkdirSync } from 'node:fs'; import { dirname } from 'node:path'; import { env } from '../env'; mkdirSync(dirname(env.DATABASE_PATH), { recursive: true }); const sqlite = new Database(env.DATABASE_PATH, { create: true }); // Keep foreign keys OFF during migration. SQLite's table-rebuild pattern // (CREATE __new_x / INSERT SELECT / DROP x / RENAME __new_x → x) trips FK // checks mid-migration, and `PRAGMA foreign_keys` inside a drizzle-wrapped // transaction is a no-op, so we have to set it on the connection up-front. sqlite.exec('PRAGMA foreign_keys = OFF;'); const db = drizzle(sqlite); migrate(db, { migrationsFolder: './drizzle' }); // Catch any orphaned rows the migration might have introduced before we // hand the DB off to the service. const fkCheck = sqlite .query('PRAGMA foreign_key_check') .all() as unknown[]; if (fkCheck.length > 0) { console.error('foreign_key_check failures after migration:', fkCheck); process.exit(1); } console.log('migrations applied'); sqlite.close();