blob: 6cb17b8a821aae9794b0d04af6f0c3370e14bc51 (
plain) (
tree)
|
|
let default_batch = 50
type cursor_batch = {
cursor_id : string;
rows : Tuple.materialized list;
has_more : bool;
}
type exec_result =
| Batch of cursor_batch
| Closed of Management.Database.t
let sessions : Session.t option ref = ref None
let set_sessions s = sessions := Some s
module Make (Storage : Management.Physical.S) = struct
module DrlExec = Drl.Executor.Make(Storage)
module Alg = Algebra.Make(Storage)
type error =
| ParseError of string
| QueryError of DrlExec.error
| CursorError of string
let sexp_of_error e =
let open Sexplib.Sexp in
match e with
| ParseError s -> List [Atom "parse-error"; Atom s]
| QueryError e -> DrlExec.sexp_of_error e
| CursorError s -> List [Atom "cursor-error"; Atom s]
let get_sessions () =
match !sessions with
| Some s -> Ok s
| None -> Error (CursorError "The session registry has not been initialised; ensure `set_sessions` is called at startup.")
let ( let* ) = Result.bind
let execute
(storage : Storage.t)
(db : Management.Database.t)
(stmt : Ast.statement)
: (exec_result, error) result =
match stmt with
| Ast.Begin { query; limit } ->
let* reg = get_sessions () in
let* rel =
DrlExec.execute storage db query
|> Result.map_error (fun e -> QueryError e)
in
let gen = Alg.to_generator storage rel in
let query_str = Drl.Parser.to_string query in
let cur = Session.register reg ~db ~query:query_str ~generator:gen in
let batch = Option.value ~default:default_batch limit in
let* (rows, has_more) =
Session.fetch reg ~id:cur.Session.id ~limit:batch
|> Result.map_error (fun s -> CursorError s)
in
Ok (Batch { cursor_id = cur.Session.id; rows; has_more })
| Ast.Fetch { cursor; limit } ->
let* reg = get_sessions () in
let batch = Option.value ~default:default_batch limit in
let* (rows, has_more) =
Session.fetch reg ~id:cursor ~limit:batch
|> Result.map_error (fun s -> CursorError s)
in
Ok (Batch { cursor_id = cursor; rows; has_more })
| Ast.Close { cursor } ->
let* reg = get_sessions () in
Session.close reg ~id:cursor;
Ok (Closed db)
end
module Memory = Make(Management.Physical.Memory)
|