package obuilder

  1. Overview
  2. Docs

Source file db.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
type t = Sqlite3.db

let or_fail ~cmd x =
  match x with
  | Sqlite3.Rc.OK -> ()
  | err -> Fmt.failwith "Sqlite3: %s (executing %S)" (Sqlite3.Rc.to_string err) cmd

let no_callback _ = failwith "[exec] used with a query!"

let exec_stmt ?(cb=no_callback) stmt =
  let rec loop () =
    match Sqlite3.step stmt with
    | Sqlite3.Rc.DONE -> ()
    | Sqlite3.Rc.ROW ->
      let cols = Sqlite3.data_count stmt in
      cb @@ List.init cols (fun i -> Sqlite3.column stmt i);
      loop ()
    | x -> Fmt.failwith "Sqlite3 exec error: %s" (Sqlite3.Rc.to_string x)
  in
  loop ()

let exec_literal db sql =
  Sqlite3.exec db sql |> or_fail ~cmd:sql

let bind stmt values =
  Sqlite3.reset stmt |> or_fail ~cmd:"reset";
  List.iteri (fun i v -> Sqlite3.bind stmt (i + 1) v |> or_fail ~cmd:"bind") values

let exec stmt values =
  bind stmt values;
  exec_stmt stmt

let query stmt values =
  bind stmt values;
  let results = ref [] in
  let cb row =
    results := row :: !results
  in
  exec_stmt ~cb stmt;
  List.rev !results

let query_one stmt values =
  match query stmt values with
  | [row] -> row
  | [] -> failwith "No results from SQL query!"
  | _ -> failwith "Multiple results from SQL query!"

let query_some stmt values =
  match query stmt values with
  | [] -> None
  | [row] -> Some row
  | _ -> failwith "Multiple results from SQL query!"

let of_dir path =
  let db = Sqlite3.db_open path in
  Sqlite3.busy_timeout db 1000;
  exec_literal db "PRAGMA journal_mode=WAL";
  exec_literal db "PRAGMA synchronous=NORMAL";
  db

let dump_item = Fmt.of_to_string Sqlite3.Data.to_string_debug
let dump_row = Fmt.(Dump.list dump_item)
OCaml

Innovation. Community. Security.