sig
  module Types :
    sig type st = Sqlite3.Data.t list * int * string * string option end
  type st = Sqlexpr_sqlite.Types.st
  exception Error of string * exn
  exception Sqlite_error of string * Sqlite3.Rc.t
  module type S =
    sig
      type 'a result
      type ('a, 'b) statement = {
        sql_statement : string;
        stmt_id : string option;
        directive : (Sqlexpr_sqlite.st -> 'b) -> Sqlexpr_sqlite.st -> 'a;
      }
      type ('a, 'b, 'c) expression = {
        statement : ('a, 'c) Sqlexpr_sqlite.S.statement;
        get_data : int * (Sqlite3.Data.t array -> 'b);
      }
      type db
      exception Error of string * exn
      exception Sqlite_error of string * Sqlite3.Rc.t
      val open_db :
        ?init:(Sqlite3.db -> unit) -> string -> Sqlexpr_sqlite.S.db
      val close_db : Sqlexpr_sqlite.S.db -> unit
      val borrow_worker :
        Sqlexpr_sqlite.S.db ->
        (Sqlexpr_sqlite.S.db -> 'Sqlexpr_sqlite.S.result) ->
        'Sqlexpr_sqlite.S.result
      val steal_worker :
        Sqlexpr_sqlite.S.db ->
        (Sqlexpr_sqlite.S.db -> 'Sqlexpr_sqlite.S.result) ->
        'Sqlexpr_sqlite.S.result
      val execute :
        Sqlexpr_sqlite.S.db ->
        ('a, unit Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.statement -> 'a
      val insert :
        Sqlexpr_sqlite.S.db ->
        ('a, int64 Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.statement -> 'a
      val select :
        Sqlexpr_sqlite.S.db ->
        ('c, 'a, 'a list Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.expression ->
        'c
      val select_f :
        Sqlexpr_sqlite.S.db ->
        ('-> 'Sqlexpr_sqlite.S.result) ->
        ('c, 'a, 'b list Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.expression ->
        'c
      val select_one :
        Sqlexpr_sqlite.S.db ->
        ('c, 'a, 'Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.expression ->
        'c
      val select_one_maybe :
        Sqlexpr_sqlite.S.db ->
        ('c, 'a, 'a option Sqlexpr_sqlite.S.result)
        Sqlexpr_sqlite.S.expression -> 'c
      val select_one_f :
        Sqlexpr_sqlite.S.db ->
        ('-> 'Sqlexpr_sqlite.S.result) ->
        ('c, 'a, 'Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.expression ->
        'c
      val select_one_f_maybe :
        Sqlexpr_sqlite.S.db ->
        ('-> 'Sqlexpr_sqlite.S.result) ->
        ('c, 'a, 'b option Sqlexpr_sqlite.S.result)
        Sqlexpr_sqlite.S.expression -> 'c
      val transaction :
        Sqlexpr_sqlite.S.db ->
        ?kind:[ `DEFERRED | `EXCLUSIVE | `IMMEDIATE ] ->
        (Sqlexpr_sqlite.S.db -> 'Sqlexpr_sqlite.S.result) ->
        'Sqlexpr_sqlite.S.result
      val fold :
        Sqlexpr_sqlite.S.db ->
        ('-> '-> 'Sqlexpr_sqlite.S.result) ->
        '->
        ('c, 'b, 'Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.expression ->
        'c
      val iter :
        Sqlexpr_sqlite.S.db ->
        ('-> unit Sqlexpr_sqlite.S.result) ->
        ('b, 'a, unit Sqlexpr_sqlite.S.result) Sqlexpr_sqlite.S.expression ->
        'b
      module Directives :
        sig
          type ('a, 'b) directive =
              (Sqlexpr_sqlite.st -> 'b) -> Sqlexpr_sqlite.st -> 'a
          val literal :
            string -> ('a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val int : (int -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val text : (string -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val blob : (string -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val float : (float -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val int32 : (int32 -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val int64 : (int64 -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val bool : (bool -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val any :
            (('-> string) -> '-> 'a, 'a)
            Sqlexpr_sqlite.S.Directives.directive
          val maybe_int :
            (int option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_text :
            (string option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_blob :
            (string option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_float :
            (float option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_int32 :
            (int32 option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_int64 :
            (int64 option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_bool :
            (bool option -> 'a, 'a) Sqlexpr_sqlite.S.Directives.directive
          val maybe_any :
            (('-> string) -> 'b option -> 'a, 'a)
            Sqlexpr_sqlite.S.Directives.directive
        end
      module Conversion :
        sig
          val text : Sqlite3.Data.t -> string
          val blob : Sqlite3.Data.t -> string
          val int : Sqlite3.Data.t -> int
          val int32 : Sqlite3.Data.t -> int32
          val int64 : Sqlite3.Data.t -> int64
          val float : Sqlite3.Data.t -> float
          val bool : Sqlite3.Data.t -> bool
          val maybe : (Sqlite3.Data.t -> 'a) -> Sqlite3.Data.t -> 'a option
          val maybe_text : Sqlite3.Data.t -> string option
          val maybe_blob : Sqlite3.Data.t -> string option
          val maybe_int : Sqlite3.Data.t -> int option
          val maybe_int32 : Sqlite3.Data.t -> int32 option
          val maybe_int64 : Sqlite3.Data.t -> int64 option
          val maybe_float : Sqlite3.Data.t -> float option
          val maybe_bool : Sqlite3.Data.t -> bool option
        end
    end
  type single_worker_db
  module Make :
    functor
      (M : sig
             type 'a t
             val return : '-> 'a t
             val bind : 'a t -> ('-> 'b t) -> 'b t
             val fail : exn -> 'a t
             val catch : (unit -> 'a t) -> (exn -> 'a t) -> 'a t
             val finalize : (unit -> 'a t) -> (unit -> unit t) -> 'a t
             val sleep : float -> unit t
             val auto_yield : float -> unit -> unit t
             type mutex
             val create_recursive_mutex : unit -> mutex
             val with_lock : mutex -> (unit -> 'a t) -> 'a t
             val register_finaliser : ('-> unit t) -> '-> unit
             type 'a key = 'Lwt.key
             val new_key : unit -> 'a key
             val get : 'a key -> 'a option
             val with_value : 'a key -> 'a option -> (unit -> 'b t) -> 'b t
           end->
      sig
        type 'a result = 'M.t
        type ('a, 'b) statement = {
          sql_statement : string;
          stmt_id : string option;
          directive : (st -> 'b) -> st -> 'a;
        }
        type ('a, 'b, 'c) expression = {
          statement : ('a, 'c) statement;
          get_data : int * (Sqlite3.Data.t array -> 'b);
        }
        type db = single_worker_db
        exception Error of string * exn
        exception Sqlite_error of string * Sqlite3.Rc.t
        val open_db : ?init:(Sqlite3.db -> unit) -> string -> db
        val close_db : db -> unit
        val borrow_worker : db -> (db -> 'a result) -> 'a result
        val steal_worker : db -> (db -> 'a result) -> 'a result
        val execute : db -> ('a, unit result) statement -> 'a
        val insert : db -> ('a, int64 result) statement -> 'a
        val select : db -> ('c, 'a, 'a list result) expression -> 'c
        val select_f :
          db ->
          ('-> 'b result) -> ('c, 'a, 'b list result) expression -> 'c
        val select_one : db -> ('c, 'a, 'a result) expression -> 'c
        val select_one_maybe :
          db -> ('c, 'a, 'a option result) expression -> 'c
        val select_one_f :
          db -> ('-> 'b result) -> ('c, 'a, 'b result) expression -> 'c
        val select_one_f_maybe :
          db ->
          ('-> 'b result) -> ('c, 'a, 'b option result) expression -> 'c
        val transaction :
          db ->
          ?kind:[ `DEFERRED | `EXCLUSIVE | `IMMEDIATE ] ->
          (db -> 'a result) -> 'a result
        val fold :
          db ->
          ('-> '-> 'a result) ->
          '-> ('c, 'b, 'a result) expression -> 'c
        val iter :
          db -> ('-> unit result) -> ('b, 'a, unit result) expression -> 'b
        module Directives :
          sig
            type ('a, 'b) directive = (st -> 'b) -> st -> 'a
            val literal : string -> ('a, 'a) directive
            val int : (int -> 'a, 'a) directive
            val text : (string -> 'a, 'a) directive
            val blob : (string -> 'a, 'a) directive
            val float : (float -> 'a, 'a) directive
            val int32 : (int32 -> 'a, 'a) directive
            val int64 : (int64 -> 'a, 'a) directive
            val bool : (bool -> 'a, 'a) directive
            val any : (('-> string) -> '-> 'a, 'a) directive
            val maybe_int : (int option -> 'a, 'a) directive
            val maybe_text : (string option -> 'a, 'a) directive
            val maybe_blob : (string option -> 'a, 'a) directive
            val maybe_float : (float option -> 'a, 'a) directive
            val maybe_int32 : (int32 option -> 'a, 'a) directive
            val maybe_int64 : (int64 option -> 'a, 'a) directive
            val maybe_bool : (bool option -> 'a, 'a) directive
            val maybe_any : (('-> string) -> 'b option -> 'a, 'a) directive
          end
        module Conversion :
          sig
            val text : Sqlite3.Data.t -> string
            val blob : Sqlite3.Data.t -> string
            val int : Sqlite3.Data.t -> int
            val int32 : Sqlite3.Data.t -> int32
            val int64 : Sqlite3.Data.t -> int64
            val float : Sqlite3.Data.t -> float
            val bool : Sqlite3.Data.t -> bool
            val maybe : (Sqlite3.Data.t -> 'a) -> Sqlite3.Data.t -> 'a option
            val maybe_text : Sqlite3.Data.t -> string option
            val maybe_blob : Sqlite3.Data.t -> string option
            val maybe_int : Sqlite3.Data.t -> int option
            val maybe_int32 : Sqlite3.Data.t -> int32 option
            val maybe_int64 : Sqlite3.Data.t -> int64 option
            val maybe_float : Sqlite3.Data.t -> float option
            val maybe_bool : Sqlite3.Data.t -> bool option
          end
        val make : Sqlite3.db -> db
        val sqlite_db : db -> Sqlite3.db
      end
  module type POOL =
    sig
      type 'a result
      module TLS :
        sig
          type 'a key
          val new_key : unit -> 'a key
          val get : 'a key -> 'a option
          val with_value :
            'a key -> 'a option -> (unit -> 'b result) -> 'b result
        end
      type db
      type stmt
      val open_db :
        ?init:(Sqlite3.db -> unit) -> string -> Sqlexpr_sqlite.POOL.db
      val close_db : Sqlexpr_sqlite.POOL.db -> unit
      val prepare :
        Sqlexpr_sqlite.POOL.db ->
        (Sqlexpr_sqlite.POOL.stmt ->
         string -> Sqlite3.Data.t list -> 'Sqlexpr_sqlite.POOL.result) ->
        Sqlexpr_sqlite.st -> 'Sqlexpr_sqlite.POOL.result
      val step :
        ?sql:string ->
        ?params:Sqlite3.Data.t list ->
        Sqlexpr_sqlite.POOL.stmt -> Sqlite3.Rc.t Sqlexpr_sqlite.POOL.result
      val step_with_last_insert_rowid :
        ?sql:string ->
        ?params:Sqlite3.Data.t list ->
        Sqlexpr_sqlite.POOL.stmt -> Int64.t Sqlexpr_sqlite.POOL.result
      val reset : Sqlexpr_sqlite.POOL.stmt -> unit Sqlexpr_sqlite.POOL.result
      val row_data :
        Sqlexpr_sqlite.POOL.stmt ->
        Sqlite3.Data.t array Sqlexpr_sqlite.POOL.result
      val raise_error :
        Sqlexpr_sqlite.POOL.stmt ->
        ?sql:string ->
        ?params:Sqlite3.Data.t list ->
        ?errmsg:string -> Sqlite3.Rc.t -> 'Sqlexpr_sqlite.POOL.result
      val unsafe_execute :
        Sqlexpr_sqlite.POOL.db ->
        ?retry_on_busy:bool -> string -> unit Sqlexpr_sqlite.POOL.result
      val borrow_worker :
        Sqlexpr_sqlite.POOL.db ->
        (Sqlexpr_sqlite.POOL.db -> 'Sqlexpr_sqlite.POOL.result) ->
        'Sqlexpr_sqlite.POOL.result
      val steal_worker :
        Sqlexpr_sqlite.POOL.db ->
        (Sqlexpr_sqlite.POOL.db -> 'Sqlexpr_sqlite.POOL.result) ->
        'Sqlexpr_sqlite.POOL.result
      val transaction_key :
        Sqlexpr_sqlite.POOL.db -> unit Sqlexpr_sqlite.POOL.TLS.key
    end
  module Make_gen :
    functor
      (M : Sqlexpr_concurrency.THREAD) (P : sig
                                              type 'a result = 'M.t
                                              module TLS :
                                                sig
                                                  type 'a key
                                                  val new_key :
                                                    unit -> 'a key
                                                  val get :
                                                    'a key -> 'a option
                                                  val with_value :
                                                    'a key ->
                                                    'a option ->
                                                    (unit -> 'b result) ->
                                                    'b result
                                                end
                                              type db
                                              type stmt
                                              val open_db :
                                                ?init:(Sqlite3.db -> unit) ->
                                                string -> db
                                              val close_db : db -> unit
                                              val prepare :
                                                db ->
                                                (stmt ->
                                                 string ->
                                                 Sqlite3.Data.t list ->
                                                 'a result) ->
                                                st -> 'a result
                                              val step :
                                                ?sql:string ->
                                                ?params:Sqlite3.Data.t list ->
                                                stmt -> Sqlite3.Rc.t result
                                              val step_with_last_insert_rowid :
                                                ?sql:string ->
                                                ?params:Sqlite3.Data.t list ->
                                                stmt -> Int64.t result
                                              val reset : stmt -> unit result
                                              val row_data :
                                                stmt ->
                                                Sqlite3.Data.t array result
                                              val raise_error :
                                                stmt ->
                                                ?sql:string ->
                                                ?params:Sqlite3.Data.t list ->
                                                ?errmsg:string ->
                                                Sqlite3.Rc.t -> 'a result
                                              val unsafe_execute :
                                                db ->
                                                ?retry_on_busy:bool ->
                                                string -> unit result
                                              val borrow_worker :
                                                db ->
                                                (db -> 'a result) ->
                                                'a result
                                              val steal_worker :
                                                db ->
                                                (db -> 'a result) ->
                                                'a result
                                              val transaction_key :
                                                db -> unit TLS.key
                                            end->
      sig
        type 'a result = 'M.t
        type ('a, 'b) statement = {
          sql_statement : string;
          stmt_id : string option;
          directive : (st -> 'b) -> st -> 'a;
        }
        type ('a, 'b, 'c) expression = {
          statement : ('a, 'c) statement;
          get_data : int * (Sqlite3.Data.t array -> 'b);
        }
        type db
        exception Error of string * exn
        exception Sqlite_error of string * Sqlite3.Rc.t
        val open_db : ?init:(Sqlite3.db -> unit) -> string -> db
        val close_db : db -> unit
        val borrow_worker : db -> (db -> 'a result) -> 'a result
        val steal_worker : db -> (db -> 'a result) -> 'a result
        val execute : db -> ('a, unit result) statement -> 'a
        val insert : db -> ('a, int64 result) statement -> 'a
        val select : db -> ('c, 'a, 'a list result) expression -> 'c
        val select_f :
          db ->
          ('-> 'b result) -> ('c, 'a, 'b list result) expression -> 'c
        val select_one : db -> ('c, 'a, 'a result) expression -> 'c
        val select_one_maybe :
          db -> ('c, 'a, 'a option result) expression -> 'c
        val select_one_f :
          db -> ('-> 'b result) -> ('c, 'a, 'b result) expression -> 'c
        val select_one_f_maybe :
          db ->
          ('-> 'b result) -> ('c, 'a, 'b option result) expression -> 'c
        val transaction :
          db ->
          ?kind:[ `DEFERRED | `EXCLUSIVE | `IMMEDIATE ] ->
          (db -> 'a result) -> 'a result
        val fold :
          db ->
          ('-> '-> 'a result) ->
          '-> ('c, 'b, 'a result) expression -> 'c
        val iter :
          db -> ('-> unit result) -> ('b, 'a, unit result) expression -> 'b
        module Directives :
          sig
            type ('a, 'b) directive = (st -> 'b) -> st -> 'a
            val literal : string -> ('a, 'a) directive
            val int : (int -> 'a, 'a) directive
            val text : (string -> 'a, 'a) directive
            val blob : (string -> 'a, 'a) directive
            val float : (float -> 'a, 'a) directive
            val int32 : (int32 -> 'a, 'a) directive
            val int64 : (int64 -> 'a, 'a) directive
            val bool : (bool -> 'a, 'a) directive
            val any : (('-> string) -> '-> 'a, 'a) directive
            val maybe_int : (int option -> 'a, 'a) directive
            val maybe_text : (string option -> 'a, 'a) directive
            val maybe_blob : (string option -> 'a, 'a) directive
            val maybe_float : (float option -> 'a, 'a) directive
            val maybe_int32 : (int32 option -> 'a, 'a) directive
            val maybe_int64 : (int64 option -> 'a, 'a) directive
            val maybe_bool : (bool option -> 'a, 'a) directive
            val maybe_any : (('-> string) -> 'b option -> 'a, 'a) directive
          end
        module Conversion :
          sig
            val text : Sqlite3.Data.t -> string
            val blob : Sqlite3.Data.t -> string
            val int : Sqlite3.Data.t -> int
            val int32 : Sqlite3.Data.t -> int32
            val int64 : Sqlite3.Data.t -> int64
            val float : Sqlite3.Data.t -> float
            val bool : Sqlite3.Data.t -> bool
            val maybe : (Sqlite3.Data.t -> 'a) -> Sqlite3.Data.t -> 'a option
            val maybe_text : Sqlite3.Data.t -> string option
            val maybe_blob : Sqlite3.Data.t -> string option
            val maybe_int : Sqlite3.Data.t -> int option
            val maybe_int32 : Sqlite3.Data.t -> int32 option
            val maybe_int64 : Sqlite3.Data.t -> int64 option
            val maybe_float : Sqlite3.Data.t -> float option
            val maybe_bool : Sqlite3.Data.t -> bool option
          end
      end
  val prettify_sql_stmt : string -> string
  val string_of_param : Sqlite3.Data.t -> string
  val string_of_params : Sqlite3.Data.t list -> string
  module Stmt :
    sig
      type t
      val prepare : Sqlite3.db -> string -> Sqlexpr_sqlite.Stmt.t
      val db_handle : Sqlexpr_sqlite.Stmt.t -> Sqlite3.db
      val finalize : Sqlexpr_sqlite.Stmt.t -> unit
      val reset : Sqlexpr_sqlite.Stmt.t -> Sqlite3.Rc.t
      val step : Sqlexpr_sqlite.Stmt.t -> Sqlite3.Rc.t
      val bind :
        Sqlexpr_sqlite.Stmt.t -> int -> Sqlite3.Data.t -> Sqlite3.Rc.t
      val row_data : Sqlexpr_sqlite.Stmt.t -> Sqlite3.Data.t array
    end
  module Stmt_cache :
    sig
      type t
      val create : unit -> Sqlexpr_sqlite.Stmt_cache.t
      val flush_stmts : Sqlexpr_sqlite.Stmt_cache.t -> unit
      val find_remove_stmt :
        Sqlexpr_sqlite.Stmt_cache.t -> string -> Sqlexpr_sqlite.Stmt.t option
      val add_stmt :
        Sqlexpr_sqlite.Stmt_cache.t ->
        string -> Sqlexpr_sqlite.Stmt.t -> unit
    end
  module Profile :
    functor (M : Sqlexpr_concurrency.THREAD->
      sig
        val profile_execute_sql :
          string ->
          ?full_sql:string ->
          ?params:Sqlite3.Data.t list -> (unit -> 'M.t) -> 'M.t
        val profile_prepare_stmt : string -> (unit -> 'M.t) -> 'M.t
      end
end