import type { Database } from "bun:sqlite"; import type { Rig } from "@local-studio/contracts/rigs"; import type { Effect } from "effect"; import { makeDatabaseCloser, openInitializedDatabase, repositoryEffect, type RepositoryError, } from "./sqlite"; type RigRow = { data: string; }; export class RigStore { private readonly db: Database; private readonly closeDatabase: () => Effect.Effect; public constructor(dbPath: string) { this.db = openInitializedDatabase(dbPath, (db) => db.run(` CREATE TABLE IF NOT EXISTS rigs ( id TEXT PRIMARY KEY, data TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ) `), ); this.closeDatabase = makeDatabaseCloser(this.db, "rigs.close"); } public list(): Rig[] { const rows = this.db.query("SELECT data FROM rigs ORDER BY created_at").all() as RigRow[]; const rigs: Rig[] = []; for (const row of rows) { try { rigs.push(JSON.parse(row.data) as Rig); } catch { continue; } } return rigs; } public listEffect(): Effect.Effect { return repositoryEffect("rigs.list", () => this.list()); } public get(rigId: string): Rig | null { const row = this.db.query("SELECT data FROM rigs WHERE id = ?").get(rigId) as RigRow | null; if (!row) return null; try { return JSON.parse(row.data) as Rig; } catch { return null; } } public getEffect(rigId: string): Effect.Effect { return repositoryEffect("rigs.get", () => this.get(rigId)); } public save(rig: Rig): void { this.db .query( `INSERT INTO rigs (id, data, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP) ON CONFLICT(id) DO UPDATE SET data = excluded.data, updated_at = CURRENT_TIMESTAMP`, ) .run(rig.id, JSON.stringify(rig)); } public saveEffect(rig: Rig): Effect.Effect { return repositoryEffect("rigs.save", () => this.save(rig)); } public delete(rigId: string): boolean { const result = this.db.query("DELETE FROM rigs WHERE id = ?").run(rigId); return result.changes > 0; } public deleteEffect(rigId: string): Effect.Effect { return repositoryEffect("rigs.delete", () => this.delete(rigId)); } public close(): Effect.Effect { return this.closeDatabase(); } }