···165165 (Option.get (Sqlite.find db key))
166166 value2
167167168168+(* INSERT operations *)
169169+170170+(** Insert roundtrip — insert then read_table returns same values. *)
171171+let test_insert_roundtrip text_val =
172172+ let text_val = truncate text_val in
173173+ let db = Sqlite.in_memory () in
174174+ Sqlite.create_table db ~sql:"CREATE TABLE t (a TEXT, b INTEGER)";
175175+ let rowid =
176176+ Sqlite.insert db ~table:"t" [ Sqlite.Vtext text_val; Sqlite.Vint 42L ]
177177+ in
178178+ let rows = Sqlite.read_table db "t" in
179179+ check (List.length rows = 1);
180180+ let rid, values = List.hd rows in
181181+ check (rid = rowid);
182182+ match values with
183183+ | [ Sqlite.Vtext s; Sqlite.Vint 42L ] ->
184184+ check_eq ~pp:Format.pp_print_string ~eq:( = ) s text_val
185185+ | _ -> check false
186186+187187+(** Multiple inserts produce distinct rowids. *)
188188+let test_insert_distinct_rowids n =
189189+ let n = (abs n mod 50) + 1 in
190190+ let db = Sqlite.in_memory () in
191191+ Sqlite.create_table db ~sql:"CREATE TABLE t (x TEXT)";
192192+ let rowids =
193193+ List.init n (fun i ->
194194+ Sqlite.insert db ~table:"t" [ Sqlite.Vtext (string_of_int i) ])
195195+ in
196196+ let unique = List.sort_uniq Int64.compare rowids in
197197+ check (List.length unique = n)
198198+199199+(** Insert with INTEGER PRIMARY KEY uses explicit rowid. *)
200200+let test_insert_explicit_pk n =
201201+ let n = Int64.of_int ((abs n mod 100_000) + 1) in
202202+ let db = Sqlite.in_memory () in
203203+ Sqlite.create_table db ~sql:"CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT)";
204204+ let rowid =
205205+ Sqlite.insert db ~table:"t" [ Sqlite.Vint n; Sqlite.Vtext "val" ]
206206+ in
207207+ check (rowid = n);
208208+ let rows = Sqlite.read_table db "t" in
209209+ let rid, _ = List.hd rows in
210210+ check (rid = n)
211211+212212+(** Insert must not crash on arbitrary text data. *)
213213+let test_insert_crash text_val =
214214+ let text_val = truncate text_val in
215215+ let db = Sqlite.in_memory () in
216216+ Sqlite.create_table db ~sql:"CREATE TABLE t (a TEXT)";
217217+ try ignore (Sqlite.insert db ~table:"t" [ Sqlite.Vtext text_val ])
218218+ with _exn -> ()
219219+220220+(** Insert with blob data roundtrips correctly. *)
221221+let test_insert_blob_roundtrip blob =
222222+ let blob = truncate blob in
223223+ let db = Sqlite.in_memory () in
224224+ Sqlite.create_table db ~sql:"CREATE TABLE t (data BLOB)";
225225+ let _ = Sqlite.insert db ~table:"t" [ Sqlite.Vblob blob ] in
226226+ let rows = Sqlite.read_table db "t" in
227227+ let _, values = List.hd rows in
228228+ match values with
229229+ | [ Sqlite.Vblob b ] -> check_eq ~pp:Format.pp_print_string ~eq:( = ) b blob
230230+ | _ -> check false
231231+168232(* Register all tests *)
169233170234let suite =
···185249 test_case "both empty" [ const () ] test_both_empty;
186250 test_case "multiple puts" [ bytes; list bytes ] test_multiple_puts;
187251 test_case "put delete put" [ bytes; bytes; bytes ] test_put_delete_put;
252252+ test_case "insert roundtrip" [ bytes ] test_insert_roundtrip;
253253+ test_case "insert distinct rowids" [ int ] test_insert_distinct_rowids;
254254+ test_case "insert explicit pk" [ int ] test_insert_explicit_pk;
255255+ test_case "insert crash safety" [ bytes ] test_insert_crash;
256256+ test_case "insert blob roundtrip" [ bytes ] test_insert_blob_roundtrip;
188257 ] )