package sqlite3_utils

  1. Overview
  2. Docs

Sqlite3_utils: higher-level helpers around Sqlite3

Base Types and Aliases

module Data = Sqlite3.Data
module Rc = Sqlite3.Rc
type db = Sqlite3.db
exception RcError of Rc.t

Exception raised by most of the functions below when a Sqlite failure occurs, with the corresponding error code.

exception Type_error of Data.t

Exception raised when the declared Ty.t does not match the actual result returned by Sqlite.

type t = db

Alias for the DB connection

val check_ret : 'a -> Rc.t -> ('a, Rc.t) Stdlib.result

Check return code.

val check_ret_exn : Rc.t -> unit

Check return code.

val err_string : ('a, Rc.t) Stdlib.result -> ('a, string) Stdlib.result

Turn the error into a string using Rc.to_string

val setup_timeout : ?ms:int -> t -> unit

on "busy", wait ms milliseconds before failing.

val with_db : ?wal:bool -> ?mode:[ `NO_CREATE | `READONLY ] -> ?mutex:[ `FULL | `NO ] -> ?cache:[ `PRIVATE | `SHARED ] -> ?vfs:string -> ?timeout:int -> string -> (t -> 'a) -> 'a

Temporarily open a DB connection. Parameters follow Sqlite3.db_open.

  • parameter timeout

    if provided, timeout in milliseconds before a query fails with "BUSY".

  • parameter wal

    if true, use "pragma journal_mode=WAL" to use a write ahead log (since 0.5)

Type Combinators

module Ty : sig ... end

Values representing types to pass to a statement, or to extract from a row

Cursor API

A Cursor is a special iterator over Sqlite rows of results. It should be consumed quickly as it will not survive the call to exec, exec_raw, etc.

module Cursor : sig ... end
val with_stmt : t -> string -> f:(Sqlite3.stmt -> 'a) -> 'a

Locally make a statement out of the given string, then cleanup when f returns.

val exec0 : t -> string -> (unit, Rc.t) Stdlib.result

Run the query purely for its side effects, without any parameter. If you need to parametrize this with user inputs, use exec_raw or exec_raw_args or exec_no_cursor to use a safe parametrized statement instead of builtin a string that is vulnerable to SQL injections.

val exec0_exn : t -> string -> unit

Run the query purely for its side effects, like exec0.

  • raises RcError

    if the query failed.

val exec_raw : t -> string -> f:(Data.t array Cursor.t -> 'b) -> ('b, Rc.t) Stdlib.result

Wrapper around Sqlite3's prepare statement, returning Data.t.

  • parameter f

    is given the cursor over results, and can use Cursor to turn it into a list, only keep a few values, or aggregate results.

val exec_raw_exn : t -> string -> f:(Data.t array Cursor.t -> 'b) -> 'b

Same as exec_raw but uses check_ret_exn to unwrap errors.

  • raises RcError

    in case of error.

val exec_raw_args : t -> string -> Sqlite3.Data.t array -> f:(Data.t array Cursor.t -> 'b) -> ('b, Rc.t) Stdlib.result

Similar to exec_raw but also takes an array of parameters that will fill the ? placeholders of the prepare statement.

val exec_raw_args_exn : t -> string -> Sqlite3.Data.t array -> f:(Data.t array Cursor.t -> 'b) -> 'b

Same as exec_raw_args but uses check_ret_exn to unwrap errors.

  • raises RcError

    in case of error.

val exec : t -> string -> ty:(('a, ('res, Rc.t) Stdlib.result) Ty.t * ('b, 'c) Ty.t * 'b) -> f:('c Cursor.t -> 'res) -> 'a

Typesafe alternative to exec_raw_args.

  • parameter ty

    describes the type of paramaters and of the returned values.

  • parameter f

    is given the cursor over decoded values

    Example:

     # with_db ":memory:" (fun db ->
         exec0_exn db "create table person (name text, age int);";
         exec0_exn db "insert into person values ('alice', 20), ('bob', 25) ;";
         exec db "select age from person where name=? ;"
          ~ty:Ty.(p1 text, p1 int, (fun (x:int) -> x))
          "alice"
           ~f:Cursor.to_list);;
    - : (int list, Rc.t) result = Ok [20]
val exec_exn : t -> string -> ty:(('a, 'res) Ty.t * ('b, 'c) Ty.t * 'b) -> f:('c Cursor.t -> 'res) -> 'a

Same as exec but uses check_ret_exn to unwrap the result.

  • raises RcError

    in case of error.

val exec_no_params : t -> string -> ty:(('b, 'c) Ty.t * 'b) -> f:('c Cursor.t -> 'res) -> ('res, Rc.t) Stdlib.result

Same as exec but without parameters. ty only takes two arguments: the type description for result rows, and a function to map rows to 'c

val exec_no_params_exn : t -> string -> ty:(('b, 'c) Ty.t * 'b) -> f:('c Cursor.t -> 'res) -> 'res

Same as exec_no_params_exn but uses check_ret_exn to unwrap the result.

  • raises RcError

    in case of error.

val exec_no_cursor : t -> string -> ty:('a, (unit, Rc.t) Stdlib.result) Ty.t -> 'a

Perform a query that doesn't return any result.

  • parameter ty

    the description of the type parameters.

val exec_no_cursor_exn : t -> string -> ty:('a, unit) Ty.t -> 'a

Same as exec_no_cursor_exn but uses check_ret_exn to unwrap the result.

  • raises RcError

    in case of error.

val exec_get_column_names : t -> string -> string list

exec_get_column_names db query is the list of names of columns that would be returned by exec db query.

  • since 0.5
val transact : t -> (t -> 'a) -> 'a

transact db f runs f db within a transaction (begin/commit/rollback). Useful to perform a batch of insertions or updates, as Sqlite doesn't write very fast.

val atomically : t -> (t -> 'a) -> 'a

Same as transact but uses Sqlite's savepoint/release/rollback mechanism. instead of begin/commit/rolllback