diff options
Diffstat (limited to 'bsfs/graph')
-rw-r--r-- | bsfs/graph/ac/base.py | 6 | ||||
-rw-r--r-- | bsfs/graph/ac/null.py | 3 | ||||
-rw-r--r-- | bsfs/graph/graph.py | 17 | ||||
-rw-r--r-- | bsfs/graph/nodes.py | 44 |
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)) |