Тут будет про sqlgg (до тех пор пока на сайте не будет вменяемого туториала/документации). Что это такое и с чем его едят?
Парсер sql запросов и генератор кода для связывания параметров и результатов выполнения запроса с переменными целевого языка (включая OCaml), с проверкой корректности типов во время компиляции. sqlgg это не ORM (код генерируется на основе sql запросов, а не наоборот) и не валидатор sql (хотя было бы неплохо). Типовыводилка пока что очень примитивная.
Собираем все запросы SQL, которые могут нам понадобиться в коде, в отдельный файл, скажем, test.sql:
CREATE TABLE IF NOT EXISTS test (word varchar, categ varchar, counter int);
CREATE INDEX IF NOT EXISTS testidx ON test (word, categ);
CREATE INDEX IF NOT EXISTS words_idx ON test (word);
-- @test_word
SELECT COUNT(*) FROM test WHERE word=@word AND categ=@categ;
-- @update_by_word
UPDATE test SET counter=counter+@counter WHERE word=@word AND categ=@categ;
-- @insert_new
INSERT INTO test (word, categ, counter) VALUES;
-- @select_words
SELECT word, counter FROM test WHERE categ=@categ LIMIT @limit;
Получаем камлевый код из test.sql (с помощью -name указываем имя функтора) :
$ sqlgg -gen ocaml -name Make test.sql > test_sql.ml
Код на OCaml, который будет использовать это:
open Sqlite3
module Sql = Test_sql.Make(Sqlgg_sqlite3)
(* Sqlgg_sqlite3 это один из модулей реализующий собственно код доступа к БД *)
let () =
let file = Sys.argv.(1) in
let db = db_open file in
(* имена этих функций выбраны автоматически *)
Sql.create_test db;
Sql.create_index_testidx db;
Sql.create_index_words_idx db;
(* NB именованные параметры *)
Sql.insert_new db ~word:"make" ~categ:"verb" ~counter:3L;
Sql.insert_new db ~word:"do" ~categ:"verb" ~counter:1L;
Sql.insert_new db ~word:"man" ~categ:"noun" ~counter:1L;
(* результат выборки COUNT - одна строка, поэтому тип функции int option, так же сработает и LIMIT 1 *)
begin match Sql.test_word db ~word:"man" ~categ:"noun" with
| Some _ -> print_endline "the man exists"
| None -> print_endline "no man there"
end;
(* выборка из двух столбцов *)
Sql.select_words db ~categ:"verb" ~limit:1L (Printf.printf "%s %Ld\n");
()
Копируем sqlgg\_traits.ml и sqlgg\_sqlite3.ml из sqlgg/impl и компилируем окончательно:
$ ocamlfind ocamlc -linkpkg -package sqlite3 sqlgg_traits.ml sqlgg_sqlite3.ml test_sql.ml test.ml -o test
Запускаем
$ ./test test.db
the man exists
make 3
2011-03-26 13:09