Previous week Up Next week


Here is the latest OCaml Weekly News, for the week of July 14 to 21, 2015.

  1. looking for "real world" sqlite3 examples
  2. OCaml 4.02.2 and 4.02.3
  3. Other OCaml News

looking for "real world" sqlite3 examples


Continuing this thread from two weeks ago, Oleg said:
> 3. is there a maintained library for generating sql queries in a typed manner?

> But mostly, I want to look at someone else's code and get an idea of
> how this is done in ocaml; pretty much all my database code to date
> has been written in dynamically typed languages and relied on code
> generation.

I'd like to point out

which is a library for writing query in a typed, functional style and
generate efficient SQL (without nested SELECTs). The library makes SQL
composable, however odd it may seem. One may consider the library
similar to T-LINQ, described by Cheney et al at ICFP 2013 -- only we
use pure OCaml rather than F# and generate a SQL statement that can be
submitted to any database. (We actually used PostgreSQL for testing).
The main theoretical difference is that our normalization rules are
typed and type-preserving by construction -- and extensible, to
compensate for difference among databases.

Here is a simple example

(* Should be automatically generated, but currently isn't *)
module type SCHEMA = sig   
  type 'a repr

  val oid      : <oid:int; pid:int; qty:int> repr -> int repr
  val opid     : <oid:int; pid:int; qty:int> repr -> int repr
  val qty      : <oid:int; pid:int; qty:int> repr -> int repr

  val orders   : unit -> <oid:int; pid:int; qty:int> list
module type SYM_SCHEMA = sig
  include SymanticsL
  include SCHEMA  with type 'a repr := 'a repr

(* simple query *)

module Q1'(S:SYM_SCHEMA) = struct
  open S
  let table_orders = table ("orders", orders ())

  let res =
      foreach (fun () -> table_orders) @@ fun o ->
      where (oid o =% int 2) @@ fun () ->
      yield o

  let observe = observe

let module M = Q1'(GenSQL) in M.observe (fun () -> M.res)
(* "SELECT x.* FROM orders AS x WHERE true AND x.oid = 2" *)
Petter Urkedal also said:
I have two projects which may also be of interest.  I haven't announced
them earlier, but I'm using them in almost production ready code:

Caqti [1] is a common interface to database client libraries, currently
supporting the postgresql and sqlite3 bindings.  It supports monad-based
cooperative threading, including lwt and async.  MySQL/MariaDB and ODBC
would be nice additions, but it would be preferable to have async
bindings for these, to avoid resorting to preemptive threading.

Caqti can be used directly (see e.g. [2]) though it does not provide a
high-level type-safe interface.  The high-level interface is omitted
since I think there are different approaches depending on the problem
and the programmer's taste, and it would be nice if the high-level
interfaces used a common library to connect and communicate with the

epiSQL [3] is a tool which parses SQL definitions and re-emits it as XML
or generates code for Macaque or Caqti.

On 2015-07-04, Martin DeMello wrote:
> 1. database schema, versioning and migrations - will i need to do
> those independently via sql/shell scripts, or is there some good way
> to integrate them into my ocaml code?

The Caqti_sql_utils module provides a function to read SQL statements
from a file and sending them to the database.  It's used in load_sql in
[4].  Then one needs a schema version, and a function which iterates
over DB updates from that version.  I have though about adding something
like that, but I'd like more experience in the end-application before
moving code to Caqti.

It would be nice to also have a developer tool to verify that the
updates correspond to the changes in the schema.  This would fit into
epiSQL, but takes a bit though and work to implement.

> 2. type conversions - in the absence of an orm, do i have to write my
> own by hand per resultset. or is there some intermediate-level library
> that i haven't found that would automate some of it?

In Caqti you have to pass a function to extract fields from the returned
tuple, as in `C.Tuple.(fun tup -> int 0 tup, text 1 tup)`, or when
folding, `C.Tuple.(fun tup acc -> (int 0 tup, text 1 tup) :: acc)`. So,
it does part of the job, but requires care due to the lack of
type- and bounds-checks.


OCaml 4.02.2 and 4.02.3


Damien Doligez announced:
There is a nasty bug [1] in 4.02.2. It doesn't impact everyone, but we think
it's important enough to warrant making a new version. We will thus release
4.02.3 before the end of this month. If you have important bugs to report on
4.02.2, you should do it right now.

Note that we will take the opportunity to the following:

Thanks for using OCaml.

-- Damien Doligez for the OCaml team


Other OCaml News

From the ocamlcore planet blog:
Thanks to Alp Mestan, we now include in the OCaml Weekly News the links to the
recent posts from the ocamlcore planet blog at

Introducing Incremental:

Formally verifying the complexity of OCaml programs with CFML -- part 1:

Old cwn

If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.

If you also wish to receive it every week by mail, you may subscribe online.

Alan Schmitt