aboutsummaryrefslogtreecommitdiffstats
path: root/lib/storable.ml
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-09-26 15:30:53 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-09-26 15:30:53 -0300
commite32ba6294781691846c3ab19281fe977350b4d0f (patch)
treef38e92ba2fc03e966d7263c7ee2e0b5d7983ebae /lib/storable.ml
parentbe375a52da6174dfda5b68617d27e1542cc80499 (diff)
downloadSakura-e32ba6294781691846c3ab19281fe977350b4d0f.tar.gz
Sakura-e32ba6294781691846c3ab19281fe977350b4d0f.zip
preparation cleanup for RNT integration
Diffstat (limited to 'lib/storable.ml')
-rw-r--r--lib/storable.ml125
1 files changed, 0 insertions, 125 deletions
diff --git a/lib/storable.ml b/lib/storable.ml
deleted file mode 100644
index 7c02732..0000000
--- a/lib/storable.ml
+++ /dev/null
@@ -1,125 +0,0 @@
-module Wire = struct
- let split_once ch value =
- match String.index_opt value ch with
- | None -> None
- | Some index ->
- Some
- (String.sub value 0 index, String.sub value (index + 1) (String.length value - index - 1))
-
- let lines bytes =
- bytes
- |> Bytes.to_string
- |> String.split_on_char '\n'
- |> List.filter (fun line -> String.trim line <> "")
-
- let fields bytes =
- lines bytes
- |> List.filter_map (fun line -> split_once '=' line)
- |> List.map (fun (key, value) -> String.trim key, String.trim value)
-
- let require_type expected fields =
- match List.assoc_opt "type" fields with
- | Some actual when actual = expected -> ()
- | Some actual ->
- invalid_arg (Printf.sprintf "expected storable type %S, got %S" expected actual)
- | None -> invalid_arg "missing storable type"
-
- let values key fields = List.filter_map (fun (k, v) -> if k = key then Some v else None) fields
-
- let required key fields =
- match List.assoc_opt key fields with
- | Some value -> value
- | None -> invalid_arg ("missing storable field: " ^ key)
-
- let attribute value =
- match split_once ':' value with
- | Some pair -> pair
- | None -> invalid_arg ("invalid attribute field: " ^ value)
-
- let encode fields =
- fields
- |> List.map (fun (key, value) -> key ^ "=" ^ value)
- |> String.concat "\n"
- |> fun value -> Bytes.of_string (value ^ "\n")
-end
-
-module Tuple = struct
- type t = {relation: string; attributes: (string * string) list}
-
- let to_bytes tuple =
- Wire.encode
- ( ["type", "tuple"; "relation", tuple.relation]
- @ List.map (fun (name, value) -> "attribute", name ^ ":" ^ value) tuple.attributes )
-
- let of_bytes bytes =
- let fields = Wire.fields bytes in
- Wire.require_type "tuple" fields;
- { relation= Wire.required "relation" fields;
- attributes= List.map Wire.attribute (Wire.values "attribute" fields) }
-end
-
-module Relation = struct
- type t =
- { name: string;
- schema: (string * string) list;
- (** Hex Merkle root of the relation's tuple set. Empty string = empty
- relation. *)
- tree_pointer: string }
-
- let to_bytes relation =
- Wire.encode
- ( [ "type", "relation";
- "name", relation.name;
- "kind", "stored";
- "tree_pointer", relation.tree_pointer ]
- @ List.map (fun (name, domain) -> "attribute", name ^ ":" ^ domain) relation.schema )
-
- let of_bytes bytes =
- let fields = Wire.fields bytes in
- Wire.require_type "relation" fields;
- { name= Wire.required "name" fields;
- schema= List.map Wire.attribute (Wire.values "attribute" fields);
- tree_pointer= Option.value (List.assoc_opt "tree_pointer" fields) ~default:"" }
-end
-
-module Multigroup = struct
- type t = {name: string; relations: Relation.t list}
-
- (* Wire format: "name|attr1:dom1,attr2:dom2|<merkle_root>"
- The third segment is the Merkle root hex; empty string = empty relation.
- A fourth segment for constraints is reserved but not yet implemented.
- TODO: add constraints serialisation once a canonical sexp representation
- is agreed upon (two syntactically distinct bodies may be semantically
- equivalent — the round-trip must account for that). *)
- let relation_value relation =
- let attrs =
- relation.Relation.schema
- |> List.map (fun (name, domain) -> name ^ ":" ^ domain)
- |> String.concat ","
- in
- relation.name ^ "|" ^ attrs ^ "|" ^ relation.tree_pointer
-
- let parse_relation value =
- match Wire.split_once '|' value with
- | None -> {Relation.name= value; schema= []; tree_pointer= ""}
- | Some (name, rest) ->
- let attrs_str, tree_pointer =
- match Wire.split_once '|' rest with None -> rest, "" | Some (a, tp) -> a, tp
- in
- let schema =
- if attrs_str = "" then []
- else attrs_str |> String.split_on_char ',' |> List.map Wire.attribute
- in
- {Relation.name; schema; tree_pointer}
-
- let to_bytes multigroup =
- Wire.encode
- ( ["type", "multigroup"; "name", multigroup.name]
- @ List.map (fun relation -> "relation", relation_value relation) multigroup.relations )
-
- let of_bytes bytes =
- let fields = Wire.fields bytes in
- Wire.require_type "multigroup" fields;
- { name= Wire.required "name" fields;
- relations= List.map parse_relation (Wire.values "relation" fields) }
-end