From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 2CB597EEF8 for ; Wed, 15 Jul 2015 15:24:14 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of oleg@okmij.org) identity=pra; client-ip=66.39.3.114; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="oleg@okmij.org"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of oleg@okmij.org designates 66.39.3.114 as permitted sender) identity=mailfrom; client-ip=66.39.3.114; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="oleg@okmij.org"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail1.g3.pair.com) identity=helo; client-ip=66.39.3.114; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="postmaster@mail1.g3.pair.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0AkAQAQXqZVnHIDJ0JbFoNRab1NhXcCgTZMAQEBAQEBEgEBAQEBBg0JCSEuhCQBAQMBJxM/BRYhNAWJAggN0EcBAQgCAR+LTIUGBxaDAYEUBY0fhx6BOYM0hyABggVslgWCMxyBYmGCSgEBAQ X-IPAS-Result: A0AkAQAQXqZVnHIDJ0JbFoNRab1NhXcCgTZMAQEBAQEBEgEBAQEBBg0JCSEuhCQBAQMBJxM/BRYhNAWJAggN0EcBAQgCAR+LTIUGBxaDAYEUBY0fhx6BOYM0hyABggVslgWCMxyBYmGCSgEBAQ X-IronPort-AV: E=Sophos;i="5.15,480,1432591200"; d="scan'208";a="140070904" Received: from mail1.g3.pair.com ([66.39.3.114]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 15 Jul 2015 15:24:12 +0200 Received: from Magus.sf-private (fortigate.sf.ecei.tohoku.ac.jp [130.34.188.206]) by mail1.g3.pair.com (Postfix) with ESMTPSA id 04F9834C1F; Wed, 15 Jul 2015 09:24:09 -0400 (EDT) Date: Wed, 15 Jul 2015 22:32:09 +0900 From: Oleg To: martindemello@gmail.com Cc: caml-list@inria.fr Message-ID: <20150715133209.GA2016@Magus.sf-private> Mail-Followup-To: Oleg , martindemello@gmail.com, caml-list@inria.fr MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.22 (2013-10-16) Subject: Re: [Caml-list] looking for "real world" sqlite3 examples > 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 : repr -> int repr val opid : repr -> int repr val qty : repr -> int repr val orders : unit -> 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" *)