Add bun:sqlite persistence layer
This commit is contained in:
parent
a1864e5880
commit
415e49327e
3 changed files with 90 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -32,3 +32,5 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
# Finder (MacOS) folder config
|
# Finder (MacOS) folder config
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
*.db
|
||||||
|
|
|
||||||
52
src/db.test.ts
Normal file
52
src/db.test.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
|
||||||
|
import { initDb, saveUpdate, getUpdates, close } from "./db";
|
||||||
|
import { unlinkSync } from "fs";
|
||||||
|
|
||||||
|
const TEST_DB = ":memory:";
|
||||||
|
|
||||||
|
describe("db persistence", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
initDb(TEST_DB);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("saves and retrieves updates for a room", () => {
|
||||||
|
const room = "test-room";
|
||||||
|
const update1 = new Uint8Array([1, 2, 3]);
|
||||||
|
const update2 = new Uint8Array([4, 5, 6]);
|
||||||
|
|
||||||
|
saveUpdate(room, update1);
|
||||||
|
saveUpdate(room, update2);
|
||||||
|
|
||||||
|
const updates = getUpdates(room);
|
||||||
|
expect(updates).toHaveLength(2);
|
||||||
|
expect(updates[0]).toEqual(update1);
|
||||||
|
expect(updates[1]).toEqual(update2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns empty array for unknown room", () => {
|
||||||
|
const updates = getUpdates("nonexistent");
|
||||||
|
expect(updates).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rooms are isolated", () => {
|
||||||
|
const room1 = "room-one";
|
||||||
|
const room2 = "room-two";
|
||||||
|
const update1 = new Uint8Array([1, 1, 1]);
|
||||||
|
const update2 = new Uint8Array([2, 2, 2]);
|
||||||
|
|
||||||
|
saveUpdate(room1, update1);
|
||||||
|
saveUpdate(room2, update2);
|
||||||
|
|
||||||
|
const room1Updates = getUpdates(room1);
|
||||||
|
const room2Updates = getUpdates(room2);
|
||||||
|
|
||||||
|
expect(room1Updates).toHaveLength(1);
|
||||||
|
expect(room2Updates).toHaveLength(1);
|
||||||
|
expect(room1Updates[0]).toEqual(update1);
|
||||||
|
expect(room2Updates[0]).toEqual(update2);
|
||||||
|
});
|
||||||
|
});
|
||||||
36
src/db.ts
Normal file
36
src/db.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Database } from "bun:sqlite";
|
||||||
|
|
||||||
|
let db: Database | null = null;
|
||||||
|
|
||||||
|
export function initDb(path: string): void {
|
||||||
|
db = new Database(path);
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS updates (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
room TEXT NOT NULL,
|
||||||
|
data BLOB NOT NULL,
|
||||||
|
created_at INTEGER DEFAULT (unixepoch())
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_room ON updates(room);
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveUpdate(room: string, data: Uint8Array): void {
|
||||||
|
if (!db) throw new Error("Database not initialized");
|
||||||
|
const stmt = db.prepare("INSERT INTO updates (room, data) VALUES (?, ?)");
|
||||||
|
stmt.run(room, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUpdates(room: string): Uint8Array[] {
|
||||||
|
if (!db) throw new Error("Database not initialized");
|
||||||
|
const stmt = db.prepare("SELECT data FROM updates WHERE room = ? ORDER BY id ASC");
|
||||||
|
const rows = stmt.all(room) as Array<{ data: Uint8Array }>;
|
||||||
|
return rows.map(row => row.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function close(): void {
|
||||||
|
if (db) {
|
||||||
|
db.close();
|
||||||
|
db = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue