diff options
Diffstat (limited to 'lib/protocols')
| -rw-r--r-- | lib/protocols/Context.ml | 4 | ||||
| -rw-r--r-- | lib/protocols/Cursor.ml | 36 | ||||
| -rw-r--r-- | lib/protocols/Cursor.mli | 21 | ||||
| -rw-r--r-- | lib/protocols/Enumerable.ml | 21 | ||||
| -rw-r--r-- | lib/protocols/Enumerable.mli | 13 | ||||
| -rw-r--r-- | lib/protocols/Program.ml | 20 | ||||
| -rw-r--r-- | lib/protocols/Program.mli | 23 | ||||
| -rw-r--r-- | lib/protocols/Relation.ml | 15 | ||||
| -rw-r--r-- | lib/protocols/Relation.mli | 10 | ||||
| -rw-r--r-- | lib/protocols/Schematics.ml | 24 | ||||
| -rw-r--r-- | lib/protocols/Schematics.mli | 21 |
11 files changed, 197 insertions, 11 deletions
diff --git a/lib/protocols/Context.ml b/lib/protocols/Context.ml new file mode 100644 index 0000000..b7c8a37 --- /dev/null +++ b/lib/protocols/Context.ml @@ -0,0 +1,4 @@ +type t = + { snapshot : Concepts.Hash.hash + ; root : Handle.t + ; status : unit -> [`Live | `Cancelled | `Exhausted] } diff --git a/lib/protocols/Cursor.ml b/lib/protocols/Cursor.ml new file mode 100644 index 0000000..36db97d --- /dev/null +++ b/lib/protocols/Cursor.ml @@ -0,0 +1,36 @@ +module Error = struct + open Concepts.Condition + + let not_a_cursor () = + condition "not-a-cursor" "A handle was expected to carry the cursor protocol and did not" empty +end + +type batch = {tuples: Concepts.Tuple.t BatFingerTree.t; exhausted: bool} + +class type implementation = object + method fetch : int -> (batch, Concepts.Condition.condition) result +end + +type Handle.protocol += Cursor of implementation +type t = implementation + +let make impl = Cursor (impl :> implementation) +let from handle = Handle.into handle (function Cursor impl -> Some impl | _ -> None) +let require handle = from handle |> Option.to_result ~none:(Error.not_a_cursor ()) +let fetch i limit = Handle.invoke i (fun o -> o#fetch limit) + +let rec next i = + let open Utilities.Result in + let* batch = fetch i 1 in + match BatFingerTree.front batch.tuples with + | Some (_, tuple) -> Ok (Some tuple) + | None -> if batch.exhausted then Ok None else next i + +let drain i ?(limit = 256) () = + let open Utilities.Result in + let rec loop tuples = + let* batch = fetch i limit in + let tuples = BatFingerTree.append tuples batch.tuples in + if batch.exhausted then Ok tuples else loop tuples + in + loop BatFingerTree.empty diff --git a/lib/protocols/Cursor.mli b/lib/protocols/Cursor.mli new file mode 100644 index 0000000..08c7628 --- /dev/null +++ b/lib/protocols/Cursor.mli @@ -0,0 +1,21 @@ +type batch = + {tuples: Concepts.Tuple.t BatFingerTree.t; exhausted: bool} + +type t + +class type implementation = object + method fetch : int -> (batch, Concepts.Condition.condition) result +end + +val make : #implementation -> Handle.protocol +val from : Handle.t -> t Handle.interface option +val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result +val fetch : t Handle.interface -> int -> (batch, Concepts.Condition.condition) result + +val next : t Handle.interface -> (Concepts.Tuple.t option, Concepts.Condition.condition) result + +val drain : + t Handle.interface -> + ?limit:int -> + unit -> + (Concepts.Tuple.t BatFingerTree.t, Concepts.Condition.condition) result diff --git a/lib/protocols/Enumerable.ml b/lib/protocols/Enumerable.ml new file mode 100644 index 0000000..e78f265 --- /dev/null +++ b/lib/protocols/Enumerable.ml @@ -0,0 +1,21 @@ +module Error = struct + open Concepts.Condition + + let not_enumerable () = + condition "not-enumerable" + "A relation was used where the expression must iterate its members, but it does not support \ + enumeration. A procedural relation may decide membership without being able to produce it." + empty +end + +class type implementation = object + method enumerate : Context.t -> (Handle.t, Concepts.Condition.condition) result +end + +type Handle.protocol += Enumerable of implementation +type t = implementation + +let make impl = Enumerable (impl :> implementation) +let from handle = Handle.into handle (function Enumerable impl -> Some impl | _ -> None) +let require handle = from handle |> Option.to_result ~none:(Error.not_enumerable ()) +let enumerate i context = Handle.invoke i (fun o -> o#enumerate context) diff --git a/lib/protocols/Enumerable.mli b/lib/protocols/Enumerable.mli new file mode 100644 index 0000000..4a903f6 --- /dev/null +++ b/lib/protocols/Enumerable.mli @@ -0,0 +1,13 @@ +type t + +class type implementation = object + method enumerate : Context.t -> (Handle.t, Concepts.Condition.condition) result +end + +val make : #implementation -> Handle.protocol +val from : Handle.t -> t Handle.interface option + +val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result + +val enumerate : + t Handle.interface -> Context.t -> (Handle.t, Concepts.Condition.condition) result diff --git a/lib/protocols/Program.ml b/lib/protocols/Program.ml new file mode 100644 index 0000000..49e6e2d --- /dev/null +++ b/lib/protocols/Program.ml @@ -0,0 +1,20 @@ +module type PROGRAM = sig + type t +end + +module Make (P : PROGRAM) = struct + class type implementation = object + method invoke : + program:P.t -> + Context.t -> + (Handle.t, Concepts.Condition.condition) result + end + + type Handle.protocol += Program of implementation + + type t = implementation + + let make impl = Program (impl :> implementation) + let from handle = Handle.into handle (function Program impl -> Some impl | _ -> None) + let invoke i ~program ctx = Handle.invoke i (fun o -> o#invoke ~program ctx) +end diff --git a/lib/protocols/Program.mli b/lib/protocols/Program.mli new file mode 100644 index 0000000..1d6c3ae --- /dev/null +++ b/lib/protocols/Program.mli @@ -0,0 +1,23 @@ +module type PROGRAM = sig + type t +end + +module Make (P : PROGRAM) : sig + type t + + class type implementation = object + method invoke : + program:P.t -> + Context.t -> + (Handle.t, Concepts.Condition.condition) result + end + + val make : #implementation -> Handle.protocol + val from : Handle.t -> t Handle.interface option + + val invoke : + t Handle.interface -> + program:P.t -> + Context.t -> + (Handle.t, Concepts.Condition.condition) result +end diff --git a/lib/protocols/Relation.ml b/lib/protocols/Relation.ml index ece9b8e..c05337f 100644 --- a/lib/protocols/Relation.ml +++ b/lib/protocols/Relation.ml @@ -1,9 +1,15 @@ +module Error = struct + open Concepts.Condition + + let not_a_relation () = + condition "not-a-relation" "A handle was expected to carry the relation protocol and did not" + empty +end + class type implementation = object - method heading : (Concepts.Hash.hash, Concepts.Condition.condition) result method predicate : (Concepts.Hash.hash option, Concepts.Condition.condition) result method local_constraints : (Concepts.Hash.hash option, Concepts.Condition.condition) result - method tuples : (Concepts.Hash.hash, Concepts.Condition.condition) result - method contains : Concepts.Blob.t -> (bool, Concepts.Condition.condition) result + method contains : Concepts.Tuple.t -> (bool, Concepts.Condition.condition) result end type Handle.protocol += Relation of implementation @@ -11,8 +17,7 @@ type t = implementation let make impl = Relation (impl :> implementation) let from handle = Handle.into handle (function Relation impl -> Some impl | _ -> None) -let heading i = Handle.invoke i (fun o -> o#heading) +let require handle = from handle |> Option.to_result ~none:(Error.not_a_relation ()) let predicate i = Handle.invoke i (fun o -> o#predicate) let local_constraints i = Handle.invoke i (fun o -> o#local_constraints) -let tuples i = Handle.invoke i (fun o -> o#tuples) let contains i tuple = Handle.invoke i (fun o -> o#contains tuple) diff --git a/lib/protocols/Relation.mli b/lib/protocols/Relation.mli index 4aeb562..384877e 100644 --- a/lib/protocols/Relation.mli +++ b/lib/protocols/Relation.mli @@ -1,16 +1,14 @@ type t class type implementation = object - method heading : (Concepts.Hash.hash, Concepts.Condition.condition) result method predicate : (Concepts.Hash.hash option, Concepts.Condition.condition) result method local_constraints : (Concepts.Hash.hash option, Concepts.Condition.condition) result - method tuples : (Concepts.Hash.hash, Concepts.Condition.condition) result - method contains : Concepts.Blob.t -> (bool, Concepts.Condition.condition) result + method contains : Concepts.Tuple.t -> (bool, Concepts.Condition.condition) result end val make : #implementation -> Handle.protocol val from : Handle.t -> t Handle.interface option -val heading : t Handle.interface -> (Concepts.Hash.hash, Concepts.Condition.condition) result +val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result val predicate : t Handle.interface -> (Concepts.Hash.hash option, Concepts.Condition.condition) result @@ -18,5 +16,5 @@ val predicate : val local_constraints : t Handle.interface -> (Concepts.Hash.hash option, Concepts.Condition.condition) result -val tuples : t Handle.interface -> (Concepts.Hash.hash, Concepts.Condition.condition) result -val contains : t Handle.interface -> Concepts.Blob.t -> (bool, Concepts.Condition.condition) result +val contains : + t Handle.interface -> Concepts.Tuple.t -> (bool, Concepts.Condition.condition) result diff --git a/lib/protocols/Schematics.ml b/lib/protocols/Schematics.ml new file mode 100644 index 0000000..d2e50ad --- /dev/null +++ b/lib/protocols/Schematics.ml @@ -0,0 +1,24 @@ +type multigroup_description = string BatMap.String.t +type relation_description = string BatMap.String.t +type tuple_description = {relation: relation_description; attributes: string BatMap.String.t} + +(* TODO: For now the description is completely detached from actual + types and domains. Later figure out a way to represent the links + without strings. *) +type description = + | Multigroup of multigroup_description + | Relation of relation_description + | Tuple of tuple_description + +class type implementation = object + method describe : unit -> (description, Concepts.Condition.condition) result +end + +type Handle.protocol += Schematics of implementation + +type t = implementation + +let make impl = Schematics (impl :> implementation) +let from handle = + Handle.into handle (function Schematics impl -> Some impl | _ -> None) +let describe impl = Handle.invoke impl (fun o -> o#describe ()) diff --git a/lib/protocols/Schematics.mli b/lib/protocols/Schematics.mli new file mode 100644 index 0000000..dc8f320 --- /dev/null +++ b/lib/protocols/Schematics.mli @@ -0,0 +1,21 @@ +type t + +(* TODO: For now the description is completely detached from actual + types and domains. Later figure out a way to represent the links + without strings. *) +type multigroup_description = string BatMap.String.t +type relation_description = string BatMap.String.t +type tuple_description = {relation: relation_description; attributes: string BatMap.String.t} + +type description = + | Multigroup of multigroup_description + | Relation of relation_description + | Tuple of tuple_description + +class type implementation = object + method describe : unit -> (description, Concepts.Condition.condition) result +end + +val make : #implementation -> Handle.protocol +val from : Handle.t -> t Handle.interface option +val describe : t Handle.interface -> (description, Concepts.Condition.condition) result |
