Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
82 lines (61 sloc) 3.43 KB

sqlgg

Тут будет про 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