Hello
Here is the latest OCaml Weekly News, for the week of July 14 to 21, 2015.
Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-07/msg00010.html
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 http://logic.cs.tsukuba.ac.jp/~ken/quel/ 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 end module type SYM_SCHEMA = sig include SymanticsL include SCHEMA with type 'a repr := 'a repr end (* 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 end 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 database. 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. [1] https://github.com/paurkedal/ocaml-caqti [2] https://github.com/paurkedal/subsocia/blob/master/lib/data/subsocia_direct.ml [3] https://github.com/paurkedal/episql [4] https://github.com/paurkedal/subsocia/blob/master/bin/subsocia_main.ml
Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-07/msg00055.html
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: http://caml.inria.fr/mantis/view.php?id=6908 http://caml.inria.fr/mantis/view.php?id=6393 http://caml.inria.fr/mantis/view.php?id=6691 https://github.com/ocaml/ocaml/pull/43 Thanks for using OCaml. -- Damien Doligez for the OCaml team [1] http://caml.inria.fr/mantis/view.php?id=6919
Thanks to Alp Mestan, we now include in the OCaml Weekly News the links to the recent posts from the ocamlcore planet blog at http://planet.ocaml.org/. Introducing Incremental: https://blogs.janestreet.com/introducing-incremental/ Formally verifying the complexity of OCaml programs with CFML -- part 1: http://gallium.inria.fr/blog/formally-verified-complexity-with-cfml-part-1
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.