Darkwing's design note and SQLite prototype as records. Sage accepts seven of eight open questions; the PM launching sessions goes to Jason. Co-Authored-By: Claude Opus 5.5 <[email protected]>
17 lines
1.3 KiB
JavaScript
17 lines
1.3 KiB
JavaScript
import { DatabaseSync } from "node:sqlite";
|
|
const opts = `'[{"key":"A"},{"key":"B"}]'`;
|
|
const base = `CREATE TABLE decisions (seq INTEGER PRIMARY KEY AUTOINCREMENT, id TEXT NOT NULL UNIQUE, rec TEXT NOT NULL) STRICT;
|
|
CREATE TRIGGER d_no_update BEFORE UPDATE ON decisions BEGIN SELECT RAISE(ABORT,'append-only'); END;
|
|
CREATE TRIGGER d_no_delete BEFORE DELETE ON decisions BEGIN SELECT RAISE(ABORT,'append-only'); END;
|
|
INSERT INTO decisions (id,rec) VALUES ('d-1','B');`;
|
|
const guard = `CREATE TRIGGER d_no_replace BEFORE INSERT ON decisions WHEN EXISTS (SELECT 1 FROM decisions WHERE seq = NEW.seq OR id = NEW.id) BEGIN SELECT RAISE(ABORT,'append-only: key exists'); END;`;
|
|
for (const [label, extra, pragma] of [["triggers only", "", false], ["recursive_triggers on", "", true], ["insert guard", guard, false]]) {
|
|
const db = new DatabaseSync(":memory:");
|
|
if (pragma) db.exec("PRAGMA recursive_triggers = ON");
|
|
db.exec(base + extra);
|
|
for (const sql of ["INSERT OR REPLACE INTO decisions (id,rec) VALUES ('d-1','A')", "REPLACE INTO decisions (seq,id,rec) VALUES (1,'d-x','A')"]) {
|
|
try { db.exec(sql); console.log(label, "| ALLOWED:", sql.slice(0, 30), "->", JSON.stringify(db.prepare("SELECT seq,id,rec FROM decisions").all())); }
|
|
catch (e) { console.log(label, "| refused:", sql.slice(0, 30), "->", e.message); }
|
|
}
|
|
}
|