| |
| |
| import { PRAGMA_SQL } from "../schema.js"; |
|
|
| const CHECKPOINT_INTERVAL_MS = 60 * 1000; |
|
|
| export async function createBunSqliteAdapter(filePath) { |
| |
| const { Database } = await import("bun:sqlite"); |
| const db = new Database(filePath, { create: true }); |
| db.exec(PRAGMA_SQL); |
|
|
| const stmtCache = new Map(); |
| function prepare(sql) { |
| let stmt = stmtCache.get(sql); |
| if (!stmt) { |
| stmt = db.prepare(sql); |
| stmtCache.set(sql, stmt); |
| } |
| return stmt; |
| } |
|
|
| const checkpointTimer = setInterval(() => { |
| try { db.exec("PRAGMA wal_checkpoint(TRUNCATE)"); } catch {} |
| }, CHECKPOINT_INTERVAL_MS); |
| if (typeof checkpointTimer.unref === "function") checkpointTimer.unref(); |
|
|
| function gracefulClose() { |
| try { db.exec("PRAGMA wal_checkpoint(TRUNCATE)"); } catch {} |
| try { stmtCache.clear(); } catch {} |
| try { db.close(); } catch {} |
| } |
| const onShutdown = () => gracefulClose(); |
| process.once("beforeExit", onShutdown); |
| process.once("SIGINT", () => { onShutdown(); process.exit(0); }); |
| process.once("SIGTERM", () => { onShutdown(); process.exit(0); }); |
|
|
| return { |
| driver: "bun:sqlite", |
| run(sql, params = []) { |
| const r = prepare(sql).run(...params); |
| return { changes: Number(r.changes ?? 0), lastInsertRowid: Number(r.lastInsertRowid ?? 0) }; |
| }, |
| get(sql, params = []) { |
| return prepare(sql).get(...params); |
| }, |
| all(sql, params = []) { |
| return prepare(sql).all(...params); |
| }, |
| exec(sql) { return db.exec(sql); }, |
| transaction(fn) { |
| |
| const tx = db.transaction(fn); |
| return tx(); |
| }, |
| checkpoint() { try { db.exec("PRAGMA wal_checkpoint(TRUNCATE)"); } catch {} }, |
| close() { |
| clearInterval(checkpointTimer); |
| gracefulClose(); |
| }, |
| raw: db, |
| }; |
| } |
|
|