aboutsummaryrefslogtreecommitdiffstats
path: root/lib/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'lib/protocols')
-rw-r--r--lib/protocols/Context.ml4
-rw-r--r--lib/protocols/Cursor.ml36
-rw-r--r--lib/protocols/Cursor.mli21
-rw-r--r--lib/protocols/Enumerable.ml21
-rw-r--r--lib/protocols/Enumerable.mli13
-rw-r--r--lib/protocols/Program.ml20
-rw-r--r--lib/protocols/Program.mli23
-rw-r--r--lib/protocols/Relation.ml15
-rw-r--r--lib/protocols/Relation.mli10
-rw-r--r--lib/protocols/Schematics.ml24
-rw-r--r--lib/protocols/Schematics.mli21
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