aboutsummaryrefslogtreecommitdiff
path: root/lib/configuration/of_json.ml
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@dailly.me>2024-03-14 08:26:58 +0100
committerSébastien Dailly <sebastien@dailly.me>2024-03-14 08:26:58 +0100
commit6b377719c10d5ab3343fd5221f99a4a21008e25a (patch)
treea7c1e9a820d339a2f161af3e09cf9e3161286796 /lib/configuration/of_json.ml
Initial commitmain
Diffstat (limited to 'lib/configuration/of_json.ml')
-rw-r--r--lib/configuration/of_json.ml134
1 files changed, 134 insertions, 0 deletions
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]