Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
46 lines
1.1 KiB
TypeScript
46 lines
1.1 KiB
TypeScript
import { mkdirSync } from "node:fs";
|
|
import { dirname } from "node:path";
|
|
import { DatabaseSync } from "node:sqlite";
|
|
import { installSchema } from "./schema";
|
|
|
|
export class DatabaseConnection {
|
|
readonly db: DatabaseSync;
|
|
|
|
constructor(dbPath: string) {
|
|
mkdirSync(dirname(dbPath), { recursive: true });
|
|
this.db = new DatabaseSync(dbPath);
|
|
this.db.exec("pragma journal_mode = WAL");
|
|
this.db.exec("pragma foreign_keys = ON");
|
|
installSchema(this.db);
|
|
}
|
|
|
|
transaction<T>(operation: () => T): T {
|
|
this.db.exec("begin immediate");
|
|
try {
|
|
const result = operation();
|
|
this.db.exec("commit");
|
|
return result;
|
|
} catch (error) {
|
|
this.db.exec("rollback");
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
close(): void {
|
|
this.db.close();
|
|
}
|
|
}
|
|
|
|
export function withSavepoint<T>(db: DatabaseSync, name: string, operation: () => T): T {
|
|
db.exec(`savepoint ${name}`);
|
|
try {
|
|
const result = operation();
|
|
db.exec(`release savepoint ${name}`);
|
|
return result;
|
|
} catch (error) {
|
|
db.exec(`rollback to savepoint ${name}`);
|
|
db.exec(`release savepoint ${name}`);
|
|
throw error;
|
|
}
|
|
}
|