Minimal SQLite key-value store for OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

claude: complete Err -> Error module rename across call sites

Follow up to the module rename: update the remaining callers that
still referenced [Err] (library [claude.ml{,i}], [client.ml], the test
driver [test.ml]), and fix one stray [^ e] string concatenation in
hermest's CLI that needed [Json.Error.to_string e] now that
[Json.of_string] yields a structured error.

+5 -43
-1
fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_sqlite) 4 3 (libraries fmt sqlite alcobar)) 5 4 6 5 (rule
+5 -18
lib/sqlite.ml
··· 55 55 type generic_table = { 56 56 g_btree : Btree.Table.t; 57 57 g_schema : schema; 58 - mutable g_unique_indexes : unique_index list; 58 + g_unique_indexes : unique_index list; 59 59 } 60 60 61 61 (* Raw sqlite_master entry for schema objects we don't manage (views, ··· 73 73 file : Eio.File.rw_ty Eio.Resource.t option; 74 74 mutable sw : Eio.Switch.t option; 75 75 db_path : Eio.Fs.dir_ty Eio.Path.t option; 76 - mutable data : kv_table option; 76 + data : kv_table option; 77 77 mutable named_tables : (string * kv_table) list; 78 78 mutable all_tables : generic_table list; 79 79 mutable extra_master : raw_master_entry list; ··· 228 228 ui_btree = Btree.Index.v pager; 229 229 }) 230 230 constraints 231 - 232 - (* Populate persistent indexes from existing table data (used on migration) *) 233 - let populate_unique_indexes btree schema indexes = 234 - let index_row ui values = 235 - match encode_index_key ui values with 236 - | None -> () 237 - | Some key -> Btree.Index.insert ui.ui_btree key 238 - in 239 - if indexes <> [] then 240 - Btree.Table.iter btree (fun rowid payload -> 241 - let values = Btree.Record.decode payload in 242 - let values = fixup_values ~schema ~rowid values in 243 - List.iter (fun ui -> index_row ui values) indexes) 244 231 245 232 (* Standard kv table schema *) 246 233 let kv_columns = ··· 959 946 960 947 module Table = struct 961 948 type db = t 962 - type t = { parent : db; name : string; kv : kv_table } 949 + type t = { kv : kv_table } 963 950 964 951 let valid_name name = 965 952 String.length name > 0 ··· 978 965 let create parent ~name = 979 966 if not (valid_name name) then Fmt.invalid_arg "Invalid table name: %S" name; 980 967 match List.assoc_opt name parent.named_tables with 981 - | Some kv -> { parent; name; kv } 968 + | Some kv -> { kv } 982 969 | None -> 983 970 (* Check if a table with this name already exists (e.g. the default 984 971 "kv" table or a table created via create_table). If so, reuse it ··· 1006 993 kv 1007 994 in 1008 995 parent.named_tables <- (name, kv) :: parent.named_tables; 1009 - { parent; name; kv } 996 + { kv } 1010 997 1011 998 (* Scan the B-tree for a key, returning (rowid, value) if found. 1012 999 This is the authoritative lookup — no stale cache. *)
-24
test/test_sqlite.ml
··· 1931 1931 write_db path [ Bytes.unsafe_to_string page1; Bytes.unsafe_to_string page2 ]; 1932 1932 must_fail_or_succeed_safely sw path 1933 1933 1934 - (* -- CVE-2023-7104 inspired: truncated/malformed WAL -- *) 1935 - 1936 - let test_truncated_wal () = 1937 - with_temp_hostile @@ fun sw path -> 1938 - (* Create a valid empty DB first *) 1939 - Eio.Switch.run @@ fun init_sw -> 1940 - let db = Sqlite.open_ ~sw:init_sw ~create:true path in 1941 - Sqlite.put db "key" "value"; 1942 - Sqlite.close db; 1943 - (* Now write a truncated WAL file *) 1944 - let wal_path = Eio.Path.(Eio.Path.native_exn path ^ "-wal") in 1945 - let wal_path = Eio.Path.(Eio.Stdenv.cwd (Eio_main.run Fun.id) / wal_path) in 1946 - ignore wal_path; 1947 - (* Write garbage to where the WAL would be *) 1948 - let wal_name = Eio.Path.native_exn path ^ "-wal" in 1949 - let oc = open_out_bin wal_name in 1950 - output_string oc "\x00\x01\x02"; 1951 - (* 3 bytes, way too short *) 1952 - close_out oc; 1953 - (* Reopen — must handle the corrupt WAL gracefully *) 1954 - must_fail_or_succeed_safely sw path; 1955 - (* Clean up *) 1956 - try Sys.remove wal_name with Sys_error _ -> () 1957 - 1958 1934 (* -- Root page beyond file -- *) 1959 1935 1960 1936 let test_root_page_oob () =