package caqti

  1. Overview
  2. Docs

The following operators provides a more visually appealing way of expressing requests. They are implemented in terms of create and Caqti_query.of_string_exn.

The ?oneshot argument defaults to false, so when not constructing one-shot queries, the full application (pt --> rt) f can be written pt --> rt @@ f, which motivates the (@:-) and (@@:-) shortcuts.

In the simplest case you can use this module directly together with Caqti_type:

let bounds_upto_req =
  let open Caqti_type.Std in
  let open Caqti_request.Infix in
  tup2 int32 float --> option (tup2 float float) @:-
  "SELECT min(y), max(y) FROM samples WHERE series_id = ? AND x < ?"

For more complex applications it may be to provide a custom module, to avoid the double open and to customize the operators, e.g.

module Caqtireq = struct
  include Caqti_type.Std
  include Caqti_type_calendar (* if needed, link caqti-type-calendar *)
  include Caqti_request.Infix

  (* Any additional types. *)
  let password = redacted string
  let uri =
    custom ~encode:(fun x -> Ok (Uri.to_string x))
           ~decode:(fun s -> Ok (Uri.of_string s)) string

  (* Optionally define a custom environment providing two schema names.
   * The references should only be assigned at startup. *)
  let myapp_schema = ref "myapp"
  let mylib_schema = ref "mylib"
  let env = function
   | "" -> Caqti_query.L !myapp_schema
   | "mylib" -> Caqti_query.L !mylib_schema
   | _ -> raise Not_found

  (* Since we have a custom environment, override the definitions of the
   * following operators to perform the substitution. *)
  let (@:-) t qs =
    let q = Caqti_query.expand env (Caqti_query.of_string_exn qs) in
    t (fun _ -> q)
  let (@@:-) t qsf =
    t (fun driver_info ->
      let qs = qsf (Caqti_driver_info.dialect_tag driver_info) in
      Caqti_query.expand env (Caqti_query.of_string_exn qs))
end

If you don't like using global references, or you need to work with different enviroments for different connections, you should instead pass the environment function when connecting to the database. We can now simplify and schema-qualify the previous request:

let bounds_upto_req =
  let open Caqtireq in
  tup2 int32 float --> option (tup2 float float) @:-
  "SELECT min(y), max(y) FROM $.samples WHERE series_id = ? AND x < ?"
val (-->.) : 'a Caqti_type.t -> unit Caqti_type.t -> ?oneshot:bool -> (Caqti_driver_info.t -> Caqti_query.t) -> ('a, unit, [ `Zero ]) t

(pt -->. Caqti_type.unit) ?oneshot f is the request which sends the query string returned by f, encodes parameters according to pt, and expects no result rows. See create for the meaning of oneshot.

val (-->) : 'a Caqti_type.t -> 'b Caqti_type.t -> ?oneshot:bool -> (Caqti_driver_info.t -> Caqti_query.t) -> ('a, 'b, [ `One ]) t

(pt --> rt) ?oneshot f is the request which sends the query string returned by f, encodes parameters according to pt, and decodes a single result row according to rt. See create for the meaning of oneshot.

val (-->?) : 'a Caqti_type.t -> 'b Caqti_type.t -> ?oneshot:bool -> (Caqti_driver_info.t -> Caqti_query.t) -> ('a, 'b, [ `Zero | `One ]) t

(pt -->? rt) ?oneshot f is the request which sends the query string returned by f, encodes parameters according to pt, and decodes zero or one result row according to rt. See create for the meaning of oneshot.

val (-->*) : 'a Caqti_type.t -> 'b Caqti_type.t -> ?oneshot:bool -> (Caqti_driver_info.t -> Caqti_query.t) -> ('a, 'b, [ `Zero | `One | `Many ]) t

(pt -->* rt) ?oneshot f is the request which sends the query string returned by f, encodes parameters according to pt, and decodes any number of result rows according to rt. See create for the meaning of oneshot.

Specialized Application Operators

As an alternative to using plain application (or @@) for the third positional argument of the above arrow operators, the following application operators transform the argument from a form which is often more convenient. In particular, they accept queries expressed as strings instead of the Caqti_query.t constructors which are more suitable for dynamically generated queries.

val (@:-) : ((Caqti_driver_info.t -> Caqti_query.t) -> ('a, 'b, 'm) t) -> string -> ('a, 'b, 'm) t

Applies a dialect-independent query string which is parsed with Caqti_query.of_string_exn.

val (@@:-) : ((Caqti_driver_info.t -> Caqti_query.t) -> ('a, 'b, 'm) t) -> (Caqti_driver_info.dialect_tag -> string) -> ('a, 'b, 'm) t

Applies a dialect-dependent query string which is parsed with Caqti_query.of_string_exn.

OCaml

Innovation. Community. Security.