aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs/graph
diff options
context:
space:
mode:
Diffstat (limited to 'bsfs/graph')
-rw-r--r--bsfs/graph/ac/base.py6
-rw-r--r--bsfs/graph/ac/null.py3
-rw-r--r--bsfs/graph/graph.py17
-rw-r--r--bsfs/graph/nodes.py44
4 files changed, 30 insertions, 40 deletions
diff --git a/bsfs/graph/ac/base.py b/bsfs/graph/ac/base.py
index 80742d7..bc9aeb3 100644
--- a/bsfs/graph/ac/base.py
+++ b/bsfs/graph/ac/base.py
@@ -22,7 +22,11 @@ __all__: typing.Sequence[str] = (
## code ##
class AccessControlBase(abc.ABC):
- """
+ """Defines the interface for access control policies.
+
+ An access control policy governs which actions a user may take to query
+ or to manipulate a graph.
+
"""
# The triple store backend.
diff --git a/bsfs/graph/ac/null.py b/bsfs/graph/ac/null.py
index 288a0da..36838bd 100644
--- a/bsfs/graph/ac/null.py
+++ b/bsfs/graph/ac/null.py
@@ -24,8 +24,7 @@ __all__: typing.Sequence[str] = (
## code ##
class NullAC(base.AccessControlBase):
- """
- """
+ """The NULL access control implements a dummy policy that allows any action to any user."""
def is_protected_predicate(self, pred: schema.Predicate) -> bool:
"""Return True if a predicate cannot be modified manually."""
diff --git a/bsfs/graph/graph.py b/bsfs/graph/graph.py
index 4a36ff6..87f7a31 100644
--- a/bsfs/graph/graph.py
+++ b/bsfs/graph/graph.py
@@ -25,8 +25,15 @@ __all__: typing.Sequence[str] = (
## code ##
class Graph():
+ """The Graph class is
+
+ The Graph class provides a convenient interface to query and access a graph.
+ Since it logically builds on the concept of graphs it is easier to
+ navigate than raw triple stores. Naturally, it uses a triple store
+ as *backend*. It also controls actions via access permissions to a *user*.
+
"""
- """
+
# link to the triple storage backend.
_backend: TripleStoreBase
@@ -81,8 +88,14 @@ class Graph():
return self
def nodes(self, node_type: URI, guids: typing.Iterable[URI]) -> _nodes.Nodes:
+ """Return nodes *guids* of type *node_type* as a `bsfs.graph.Nodes` instance.
+
+ Note that the *guids* need not to exist (however, the *node_type* has
+ to be part of the schema). Inexistent guids will be created (using
+ *node_type*) once some data is assigned to them.
+
"""
- node_type = self.schema.node(node_type)
+ type_ = self.schema.node(node_type)
# NOTE: Nodes constructor materializes guids.
return _nodes.Nodes(self._backend, self._user, type_, guids)
diff --git a/bsfs/graph/nodes.py b/bsfs/graph/nodes.py
index 7b0e8f4..c417a0e 100644
--- a/bsfs/graph/nodes.py
+++ b/bsfs/graph/nodes.py
@@ -5,7 +5,6 @@ A copy of the license is provided with the project.
Author: Matthias Baumgartner, 2022
"""
# imports
-import itertools
import time
import typing
@@ -87,34 +86,14 @@ class Nodes():
pred: URI, # FIXME: URI or _schema.Predicate?
value: typing.Any,
) -> 'Nodes':
- """
- """
- try:
- # insert triples
- self.__set(pred, value)
- # save changes
- self._backend.commit()
-
- except (
- errors.PermissionDeniedError, # tried to set a protected predicate (ns.bsm.t_created)
- errors.ConsistencyError, # node types are not in the schema or don't match the predicate
- errors.InstanceError, # guids/values don't have the correct type
- TypeError, # value is supposed to be a Nodes instance
- ValueError, # multiple values passed to unique predicate
- ):
- # revert changes
- self._backend.rollback()
- # notify the client
- raise
-
- return self
+ """Set predicate *pred* to *value*."""
+ return self.set_from_iterable([(pred, value)])
def set_from_iterable(
self,
predicate_values: typing.Iterable[typing.Tuple[URI, typing.Any]], # FIXME: URI or _schema.Predicate?
) -> 'Nodes':
- """
- """
+ """Set mutliple predicate-value pairs at once."""
# TODO: Could group predicate_values by predicate to gain some efficiency
# TODO: ignore errors on some predicates; For now this could leave residual
# data (e.g. some nodes were created, some not).
@@ -137,14 +116,11 @@ class Nodes():
# notify the client
raise
+ # FIXME: How about other errors? Shouldn't I then rollback as well?!
+
return self
- def __set(
- self,
- predicate: URI,
- value: typing.Any,
- #on_error: str = 'ignore', # ignore, rollback
- ):
+ def __set(self, predicate: URI, value: typing.Any):
"""
"""
# get normalized predicate. Raises KeyError if *pred* not in the schema.
@@ -216,11 +192,9 @@ class Nodes():
else:
raise errors.UnreachableError()
- def _ensure_nodes(
- self,
- node_type: _schema.Node,
- guids: typing.Iterable[URI],
- ):
+ def _ensure_nodes(self, node_type: _schema.Node, guids: typing.Iterable[URI]):
+ """
+ """
# check node existence
guids = set(guids)
existing = set(self._backend.exists(node_type, guids))