From 6b377719c10d5ab3343fd5221f99a4a21008e25a Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Thu, 14 Mar 2024 08:26:58 +0100 Subject: Initial commit --- lib/configuration/of_json.ml | 134 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 lib/configuration/of_json.ml (limited to 'lib/configuration/of_json.ml') diff --git a/lib/configuration/of_json.ml b/lib/configuration/of_json.ml new file mode 100644 index 0000000..f9171b9 --- /dev/null +++ b/lib/configuration/of_json.ml @@ -0,0 +1,134 @@ +open StdLabels +module Table = ImportDataTypes.Table +module Path = ImportDataTypes.Path +module Expression = ImportExpression.T + +open Ppx_yojson_conv_lib.Yojson_conv.Primitives + +let current_syntax = 1 + +let rec expression_of_yojson : + (Yojson.Safe.t -> 'a) -> Yojson.Safe.t -> 'a Expression.t = + fun f expr -> + match expr with + | `Null -> Empty + | `List l -> Concat (List.map ~f:(expression_of_yojson f) l) + | `String s as json -> ( + try Path (f json) with + | _ -> Literal s) + | `Assoc [ (fn, `List [ `List l1; `List l2 ]) ] + when String.equal "counter" (String.lowercase_ascii fn) -> + Window + ( Expression.Counter, + List.map ~f:(expression_of_yojson f) l1, + List.map ~f:(expression_of_yojson f) l2 ) + | `Assoc [ (fn, `List [ expr1; `List l2; `List l3 ]) ] + when String.equal "previous" (String.lowercase_ascii fn) -> + Window + ( Expression.Previous (expression_of_yojson f expr1), + List.map ~f:(expression_of_yojson f) l2, + List.map ~f:(expression_of_yojson f) l3 ) + | `Assoc [ (fn, `List l) ] when String.equal "nvl" (String.lowercase_ascii fn) + -> Nvl (List.map ~f:(expression_of_yojson f) l) + | `Assoc [ (fn, `List l) ] -> + Function + (String.lowercase_ascii fn, List.map ~f:(expression_of_yojson f) l) + | json -> ( + try Path (f json) with + | _ -> + let str_json = Yojson.Safe.pretty_to_string json in + raise + (ImportErrors.JsonError { json = str_json; element = "Expression" }) + ) + +type 'a expression = 'a Expression.t +type column = Path.column + +let column_of_yojson : Yojson.Safe.t -> int = function + | `Int i -> i + | `String s -> ImportCSV.Csv.column_of_string s + | _ -> raise (Invalid_argument "column") + +let yojson_of_column i = `String (ImportCSV.Csv.column_to_string i) + +type path = Syntax.Path.t = { + alias : string option; [@default None] [@yojson_drop_default ( = )] + (* External file to load, when the information is missing, load in + the current file *) + column : column; +} +[@@deriving of_yojson] + +let path_of_yojson : Yojson.Safe.t -> path = function + | `String s -> + Scanf.sscanf s ":%s@.%s" (fun table column -> + if String.equal column "" then + { alias = None; column = ImportCSV.Csv.column_of_string table } + else + { + alias = Some table; + column = ImportCSV.Csv.column_of_string column; + }) + | other -> path_of_yojson other + +let yojson_of_path : path -> Yojson.Safe.t = + fun { alias; column } -> + let table = + match alias with + | None -> "" + | Some table -> String.cat table "." + in + + `String + (String.concat ~sep:"" + [ ":"; table; ImportCSV.Csv.column_to_string column ]) + +type table = Table.t = { + file : string; + tab : int; [@default 1] [@yojson_drop_default ( = )] + name : string; +} +[@@deriving of_yojson] + +type extern = { + source : string option; [@default None] [@yojson_drop_default ( = )] + intern_key : column expression; + target : table; + extern_key : column expression; + allow_missing : bool; [@default false] [@yojson_drop_default ( = )] + match_rule : string option; [@default None] [@yojson_drop_default ( = )] +} +[@@deriving of_yojson] + +type syntax_v1_extern = Syntax.extern + +let syntax_v1_extern_of_yojson yojson = + let e = extern_of_yojson yojson in + let intern_key : path Expression.t = + Expression.map e.intern_key ~f:(fun column -> + Syntax.Path.{ column; alias = e.source }) + in + Syntax. + { + extern_key = e.extern_key; + intern_key; + target = e.target; + allow_missing = e.allow_missing; + match_rule = e.match_rule; + } + +type predicate = unit + +let predicate_of_yojson _ = () +let yojson_of_predicate () = `Null + +type t = Syntax.t = { + version : int; [@default current_syntax] + source : table; + externals : syntax_v1_extern list; [@default []] + columns : path expression list; + filters : path expression list; [@default []] [@yojson_drop_default ( = )] + sort : path expression list; [@default []] [@yojson_drop_default ( = )] + uniq : path expression list; [@default []] [@yojson_drop_default ( = )] +} +[@@deriving of_yojson] -- cgit v1.2.3