aboutsummaryrefslogtreecommitdiffstats
path: root/lib/storable.ml
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-05-18 12:35:26 -0300
committerGitHub <noreply@github.com>2026-05-18 12:35:26 -0300
commitcf0fffed43d0ca7618cd0013411151e057b7a32a (patch)
tree35915aee3f7160b9ff6b41c3c0502b34050f642c /lib/storable.ml
parente3d3e20dfea253de291d5b31059cd55c0eaabf02 (diff)
downloadSakura-cf0fffed43d0ca7618cd0013411151e057b7a32a.tar.gz
Sakura-cf0fffed43d0ca7618cd0013411151e057b7a32a.zip
RNT interface
Co-authored-by: Estevan Castilho <tevo@riajuu.net>
Diffstat (limited to 'lib/storable.ml')
-rw-r--r--lib/storable.ml38
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/storable.ml b/lib/storable.ml
index 5d87846..5527044 100644
--- a/lib/storable.ml
+++ b/lib/storable.ml
@@ -63,11 +63,17 @@ module Tuple = struct
end
module Relation = struct
- type t = { name : string; schema : (string * string) list }
+ 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") ]
+ ([ ("type", "relation"); ("name", relation.name); ("kind", "stored");
+ ("tree_pointer", relation.tree_pointer) ]
@ List.map
(fun (name, domain) -> ("attribute", name ^ ":" ^ domain))
relation.schema)
@@ -76,31 +82,43 @@ module Relation = struct
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);
+ 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.name ^ "|" ^ attrs ^ "|" ^ relation.tree_pointer
let parse_relation value =
match Wire.split_once '|' value with
- | None -> { Relation.name = value; schema = [] }
- | Some (name, attrs) ->
+ | 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 = "" then []
- else attrs |> String.split_on_char ',' |> List.map Wire.attribute
+ if attrs_str = "" then []
+ else attrs_str |> String.split_on_char ',' |> List.map Wire.attribute
in
- { Relation.name; schema }
+ { Relation.name; schema; tree_pointer }
let to_bytes multigroup =
Wire.encode