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
, meaning the the query string arguments accepts The Syntax of Query Templates.
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 convenient 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 < ?"
Constructors for Driver-Independent Requests also provides alternative arrow operators for this common case, which allows using short-from local open,
let bounds_upto_req =
Caqtireq.(tup2 int32 float ->! option (tup2 float float))
"SELECT min(y), max(y) FROM $.samples WHERE series_id = ? AND x < ?"
Constructors for Driver-Independent Requests
(pt ->. Caqti_type.unit) ?oneshot s
is the request which sends the query string s
, encodes parameters according to pt
, and expects no result rows. See create
for the meaning of oneshot
.
(pt ->! rt) ?oneshot s
is the request which sends the query string s
, encodes parameters according to pt
, and decodes a single result row according to rt
. See create
for the meaning of oneshot
.
(pt ->? rt) ?oneshot s
is the request which sends the query string s
, encodes parameters according to pt
, and decodes zero or one result row according to rt
. See create
for the meaning of oneshot
.
(pt ->* rt) ?oneshot s
is the request which sends the query string s
, encodes parameters according to pt
, and decodes any number of result rows according to rt
. See create
for the meaning of oneshot
.
Constructors for Driver-Dependent Requests
The below arrow operators takes a function instead of a string as their third argument. The function receives information about the current driver and returns a Caqti_query.t
. This is the most general way of providing the query string.
As an alternative to using plain application (or @@
) for the third positional argument, additional application operators are provided for convenience.
(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
.
(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
.
(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
.
(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
.