package caqti

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Module Caqti_template.CreateSource

This is a convenience API which collects everything needed to create request templates. A request template describes a database query and how to encode parameters and decode the result.

Basic Usage

Consider the example:

  let bounds_upto_req =
    let open Caqti_template.Create in
    static T.(t2 int32 float -->! option (t2 float float))
    "SELECT min(y), max(y) FROM samples WHERE series_id = ? AND x < ?"

First we opening the current module. We then pick the function static to create a template for prepared queries where the query template has static lifetime. The first argument describes the parameter type and the result row type combined with an arrow which describes the multiplicity of the result rows. The exclamation mark in the arrow indicates that precisely one result row is expected. The second argument is the query template, here in the form of a string.

In the query template, ? refer to parameters, but you can also use the PostgreSQL-style $1, $2, etc. if you prefer, as long as you stick to the same convention for a given query template. Caqti drivers translate parameter references to fit the database system, rearranging parameters if necessary.

Caqti provides a way to handle dialectical differences between database systems apart from the parameter syntax. The example above uses a shortcut, since it does not need this functionality. In the full form it looks like:

  let bounds_upto_req =
    let open Caqti_template.Create in
    static_gen
      T.(t2 int32 float -->! option (t2 float float)) @@ Fun.const @@
      Q.parse
        "SELECT min(y), max(y) FROM samples WHERE series_id = ? AND x < ?"

The callback receives a Dialect.t and returns a Query.t. We can now see that the still same query string is explicitly parsed. Query and Query_fmt provides alternative ways of constructing query template which is more suitable for dynamically generated queries.

The following example makes use of the dialect argument to handle dialectical differences regarding string concatenation:

  let concat_req =
    let open Caqti_template.Create in
    static_gen T.(t2 string string -->! string) @@ function
     | D.Mysql _ -> Q.parse "SELECT concat(?, ?)"
     | _ -> Q.parse "SELECT ? || ?"

In summary

  • Pick the main function according to the lifetime of prepared queries and whether to use the simplified or generic callback.
  • In the request type argument, the arrow decoration selects the expected multiplicity of result rows: -->. for zero, -->! for one, -->? for zero or one, -->* for zero or more.

Supplementing

If needed, you can supplement the current module with custom types:

  module Ct : sig
    open Caqti_template

    include Caqti_template.CREATE

    module T : sig
      include module type of T

      val password : string Row_type.t
      val uri : Uri.t Row_type.t
    end
  end = struct
    open Caqti_template

    include Caqti_template.Create

    module T = struct
      include T

      let password = redacted string (* a string redacted from logs *)

      let uri =
        let encode x = Ok (Uri.to_string x) in
        let decode s = Ok (Uri.of_string s) in
        Row_type.custom ~encode ~decode string
    end
  end

Reference

Type Descriptors

Sourcemodule T = Type

Dialect Descriptors

Sourcemodule D = Dialect
include module type of Version.Infix
Sourceval (=*) : Version.t -> string -> bool
Sourceval (<>*) : Version.t -> string -> bool
Sourceval (<*) : Version.t -> string -> bool
Sourceval (<=*) : Version.t -> string -> bool
Sourceval (>*) : Version.t -> string -> bool
Sourceval (>=*) : Version.t -> string -> bool

Query Templates

Sourcemodule Q = Query
Sourcemodule Qf = Query_fmt
include module type of Query.Infix
Sourceval (@++) : Query.t -> Query.t -> Query.t

An alias for cat.

Sourceval (^++) : string -> Query.t -> Query.t

pfx ^++ q is q prefixed with the literal fragment pfx, i.e. cat (lit pfx) q.

Sourceval (++^) : Query.t -> string -> Query.t

q ++^ sfx is q suffixed with the literal fragment sfx, i.e. cat q (lit sfx).

Request Templates

The following are shortcuts for Request.create and Query.parse In particular static, dynamic, and direct covers the most common case of sending a pre-composed query string to the database while the static_gen, dynamic_gen, and direct_gen are the correspending fully generic variants.

Sourceval static : ('a Row_type.t * 'b Row_type.t * 'm Row_mult.t) -> string -> ('a, 'b, 'm) Request.t

Creates a template of static lifetime for prepared requests where the query template is provided as a string to be parsed by Query.parse.

Sourceval static_gen : ('a Row_type.t * 'b Row_type.t * 'm Row_mult.t) -> (Dialect.t -> Query.t) -> ('a, 'b, 'm) Request.t

Creates a template of static lifetime for prepared requests where the query template is dialect-dependent and explicitly constructed by the caller.

Sourceval dynamic : ('a Row_type.t * 'b Row_type.t * 'm Row_mult.t) -> string -> ('a, 'b, 'm) Request.t

Creates a template of static lifetime for prepared requests where the query template is provided as a string to be parsed by Query.parse.

Sourceval dynamic_gen : ('a Row_type.t * 'b Row_type.t * 'm Row_mult.t) -> (Dialect.t -> Query.t) -> ('a, 'b, 'm) Request.t

Creates a template of static lifetime for prepared requests where the query template is dialect-dependent and explicitly constructed by the caller.

Sourceval direct : ('a Row_type.t * 'b Row_type.t * 'm Row_mult.t) -> string -> ('a, 'b, 'm) Request.t

Creates a template for non-prepared requests where the query template is provided as a string to be parsed by Query.parse. If non-prepared requests are not unsupported by the driver, a temporarily prepared request is used instead.

Sourceval direct_gen : ('a Row_type.t * 'b Row_type.t * 'm Row_mult.t) -> (Dialect.t -> Query.t) -> ('a, 'b, 'm) Request.t

Creates a template for non-prepared requests where the query template is dialect-dependent and explicitly constructed by the caller. If non-prepared requests are not unsupported by the driver, a temporarily prepared request is used instead.

OCaml

Innovation. Community. Security.