From edd5390b6db1550f6a80a46f0eaf5f3916997532 Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Sun, 18 Dec 2022 14:06:58 +0100 Subject: information hiding --- bsfs/graph/ac/base.py | 12 +++--- bsfs/graph/graph.py | 20 +++++----- bsfs/graph/nodes.py | 58 +++++++++++++-------------- bsfs/triple_store/sparql.py | 81 ++++++++++++++++++++------------------ test/graph/test_nodes.py | 54 +++++++++++++------------- test/triple_store/test_sparql.py | 84 ++++++++++++++++++++-------------------- 6 files changed, 158 insertions(+), 151 deletions(-) diff --git a/bsfs/graph/ac/base.py b/bsfs/graph/ac/base.py index eef444b..80742d7 100644 --- a/bsfs/graph/ac/base.py +++ b/bsfs/graph/ac/base.py @@ -25,19 +25,19 @@ class AccessControlBase(abc.ABC): """ """ - # - __backend: TripleStoreBase + # The triple store backend. + _backend: TripleStoreBase - # - __user: URI + # The current user. + _user: URI def __init__( self, backend: TripleStoreBase, user: URI, ): - self.__backend = backend - self.__user = URI(user) + self._backend = backend + self._user = URI(user) @abc.abstractmethod def is_protected_predicate(self, pred: schema.Predicate) -> bool: diff --git a/bsfs/graph/graph.py b/bsfs/graph/graph.py index d5e1b88..71973c2 100644 --- a/bsfs/graph/graph.py +++ b/bsfs/graph/graph.py @@ -27,33 +27,33 @@ class Graph(): """ """ # link to the triple storage backend. - __backend: TripleStoreBase + _backend: TripleStoreBase # user uri. - __user: URI + _user: URI def __init__(self, backend: TripleStoreBase, user: URI): - self.__backend = backend - self.__user = user + self._backend = backend + self._user = user def __hash__(self) -> int: - return hash((type(self), self.__backend, self.__user)) + return hash((type(self), self._backend, self._user)) def __eq__(self, other) -> bool: return isinstance(other, type(self)) \ - and self.__backend == other.__backend \ - and self.__user == other.__user + and self._backend == other._backend \ + and self._user == other._user def __repr__(self) -> str: - return f'{typename(self)}(backend={repr(self.__backend)}, user={self.__user})' + return f'{typename(self)}(backend={repr(self._backend)}, user={self._user})' def __str__(self) -> str: - return f'{typename(self)}({str(self.__backend)}, {self.__user})' + return f'{typename(self)}({str(self._backend)}, {self._user})' @property def schema(self) -> Schema: """Return the store's local schema.""" - return self.__backend.schema + return self._backend.schema """ def nodes(self, node_type: URI, guids: typing.Iterable[URI]) -> _nodes.Nodes: diff --git a/bsfs/graph/nodes.py b/bsfs/graph/nodes.py index 7d2e9b3..7b0e8f4 100644 --- a/bsfs/graph/nodes.py +++ b/bsfs/graph/nodes.py @@ -32,16 +32,16 @@ class Nodes(): """ # triple store backend. - __backend: TripleStoreBase + _backend: TripleStoreBase # user uri. - __user: URI + _user: URI # node type. - __node_type: _schema.Node + _node_type: _schema.Node # guids of nodes. Can be empty. - __guids: typing.Set[URI] + _guids: typing.Set[URI] def __init__( self, @@ -50,37 +50,37 @@ class Nodes(): node_type: _schema.Node, guids: typing.Iterable[URI], ): - self.__backend = backend - self.__user = user - self.__node_type = node_type - self.__guids = set(guids) - self.__ac = ac.NullAC(self.__backend, self.__user) + self._backend = backend + self._user = user + self._node_type = node_type + self._guids = set(guids) + self.__ac = ac.NullAC(self._backend, self._user) def __eq__(self, other: typing.Any) -> bool: return isinstance(other, Nodes) \ - and self.__backend == other.__backend \ - and self.__user == other.__user \ - and self.__node_type == other.__node_type \ - and self.__guids == other.__guids + and self._backend == other._backend \ + and self._user == other._user \ + and self._node_type == other._node_type \ + and self._guids == other._guids def __hash__(self) -> int: - return hash((type(self), self.__backend, self.__user, self.__node_type, tuple(sorted(self.__guids)))) + return hash((type(self), self._backend, self._user, self._node_type, tuple(sorted(self._guids)))) def __repr__(self) -> str: - return f'{typename(self)}({self.__backend}, {self.__user}, {self.__node_type}, {self.__guids})' + return f'{typename(self)}({self._backend}, {self._user}, {self._node_type}, {self._guids})' def __str__(self) -> str: - return f'{typename(self)}({self.__node_type}, {self.__guids})' + return f'{typename(self)}({self._node_type}, {self._guids})' @property def node_type(self) -> _schema.Node: """Return the node's type.""" - return self.__node_type + return self._node_type @property def guids(self) -> typing.Iterator[URI]: """Return all node guids.""" - return iter(self.__guids) + return iter(self._guids) def set( self, @@ -93,7 +93,7 @@ class Nodes(): # insert triples self.__set(pred, value) # save changes - self.__backend.commit() + self._backend.commit() except ( errors.PermissionDeniedError, # tried to set a protected predicate (ns.bsm.t_created) @@ -103,7 +103,7 @@ class Nodes(): ValueError, # multiple values passed to unique predicate ): # revert changes - self.__backend.rollback() + self._backend.rollback() # notify the client raise @@ -123,7 +123,7 @@ class Nodes(): for pred, value in predicate_values: self.__set(pred, value) # save changes - self.__backend.commit() + self._backend.commit() except ( errors.PermissionDeniedError, # tried to set a protected predicate (ns.bsm.t_created) @@ -133,7 +133,7 @@ class Nodes(): ValueError, # multiple values passed to unique predicate ): # revert changes - self.__backend.rollback() + self._backend.rollback() # notify the client raise @@ -148,7 +148,7 @@ class Nodes(): """ """ # get normalized predicate. Raises KeyError if *pred* not in the schema. - pred = self.__backend.schema.predicate(predicate) + pred = self._backend.schema.predicate(predicate) # node_type must be a subclass of the predicate's domain node_type = self.node_type @@ -177,7 +177,7 @@ class Nodes(): # insert literals # TODO: Support passing iterators as values for non-unique predicates - self.__backend.set( + self._backend.set( node_type, guids, pred, @@ -206,7 +206,7 @@ class Nodes(): targets = set(self.__ac.link_to_node(value.node_type, targets)) # insert node links - self.__backend.set( + self._backend.set( node_type, guids, pred, @@ -223,7 +223,7 @@ class Nodes(): ): # check node existence guids = set(guids) - existing = set(self.__backend.exists(node_type, guids)) + existing = set(self._backend.exists(node_type, guids)) # get nodes to be created missing = guids - existing # create nodes if need be @@ -231,10 +231,10 @@ class Nodes(): # check which missing nodes can be created missing = set(self.__ac.createable(node_type, missing)) # create nodes - self.__backend.create(node_type, missing) + self._backend.create(node_type, missing) # add bookkeeping triples - self.__backend.set(node_type, missing, - self.__backend.schema.predicate(ns.bsm.t_created), [time.time()]) + self._backend.set(node_type, missing, + self._backend.schema.predicate(ns.bsm.t_created), [time.time()]) # add permission triples self.__ac.create(node_type, missing) # return available nodes diff --git a/bsfs/triple_store/sparql.py b/bsfs/triple_store/sparql.py index 3eab869..d9ed55a 100644 --- a/bsfs/triple_store/sparql.py +++ b/bsfs/triple_store/sparql.py @@ -10,9 +10,8 @@ import typing import rdflib # bsfs imports -from bsfs.utils import URI -from bsfs.utils import errors -import bsfs.schema as _schema +from bsfs import schema as bsc +from bsfs.utils import errors, URI # inner-module imports from . import base @@ -26,7 +25,7 @@ __all__: typing.Sequence[str] = ( ## code ## -class Transaction(): +class _Transaction(): """Lightweight rdflib transactions for in-memory databases.""" def __init__(self, graph): @@ -58,11 +57,20 @@ class SparqlStore(base.TripleStoreBase): """ """ - def __init__(self, uri: typing.Optional[URI] = None): - super().__init__(uri) - self.graph = rdflib.Graph() - self.transaction = Transaction(self.graph) - self.__schema = _schema.Schema.Empty() + # The rdflib graph. + _graph: rdflib.Graph + + # Current transaction. + _transaction: _Transaction + + # The local schema. + _schema: bsc.Schema + + def __init__(self): + super().__init__(None) + self._graph = rdflib.Graph() + self._transaction = _Transaction(self._graph) + self._schema = bsc.Schema.Empty() @classmethod def Open( @@ -73,15 +81,14 @@ class SparqlStore(base.TripleStoreBase): return cls(None) def commit(self): - self.transaction.commit() + self._transaction.commit() def rollback(self): - self.transaction.rollback() + self._transaction.rollback() @property - def schema(self) -> _schema.Schema: - """Return the current schema.""" - return self.__schema + def schema(self) -> bsc.Schema: + return self._schema @schema.setter def schema(self, schema: _schema.Schema): @@ -106,7 +113,7 @@ class SparqlStore(base.TripleStoreBase): """ # check args: Schema instanace - if not isinstance(schema, _schema.Schema): + if not isinstance(schema, bsc.Schema): raise TypeError(schema) # check compatibility: No contradicting definitions if not self.schema.consistent_with(schema): @@ -124,21 +131,21 @@ class SparqlStore(base.TripleStoreBase): # remove predicate instances for pred in sub.predicates: - for src, trg in self.graph.subject_objects(rdflib.URIRef(pred.uri)): - self.transaction.remove((src, rdflib.URIRef(pred.uri), trg)) + for src, trg in self._graph.subject_objects(rdflib.URIRef(pred.uri)): + self._transaction.remove((src, rdflib.URIRef(pred.uri), trg)) # remove node instances for node in sub.nodes: # iterate through node instances - for inst in self.graph.subjects(rdflib.RDF.type, rdflib.URIRef(node.uri)): + for inst in self._graph.subjects(rdflib.RDF.type, rdflib.URIRef(node.uri)): # remove triples where the instance is in the object position - for src, pred in self.graph.subject_predicates(inst): - self.transaction.remove((src, pred, inst)) + for src, pred in self._graph.subject_predicates(inst): + self._transaction.remove((src, pred, inst)) # remove triples where the instance is in the subject position - for pred, trg in self.graph.predicate_objects(inst): - self.transaction.remove((inst, pred, trg)) + for pred, trg in self._graph.predicate_objects(inst): + self._transaction.remove((inst, pred, trg)) # remove instance - self.transaction.remove((inst, rdflib.RDF.type, rdflib.URIRef(node.uri))) + self._transaction.remove((inst, rdflib.RDF.type, rdflib.URIRef(node.uri))) # NOTE: Nothing to do for literals @@ -146,15 +153,15 @@ class SparqlStore(base.TripleStoreBase): self.commit() # migrate schema - self.__schema = schema + self._schema = schema - def _has_type(self, subject: URI, node_type: _schema.Node) -> bool: + def _has_type(self, subject: URI, node_type: bsc.Node) -> bool: """Return True if *subject* is a node of class *node_type* or a subclass thereof.""" if node_type not in self.schema.nodes(): raise errors.ConsistencyError(f'{node_type} is not defined in the schema') - subject_types = list(self.graph.objects(rdflib.URIRef(subject), rdflib.RDF.type)) + subject_types = list(self._graph.objects(rdflib.URIRef(subject), rdflib.RDF.type)) if len(subject_types) == 0: return False elif len(subject_types) == 1: @@ -170,7 +177,7 @@ class SparqlStore(base.TripleStoreBase): def exists( self, - node_type: _schema.Node, + node_type: bsc.Node, guids: typing.Iterable[URI], ): """ @@ -179,7 +186,7 @@ class SparqlStore(base.TripleStoreBase): def create( self, - node_type: _schema.Node, + node_type: bsc.Node, guids: typing.Iterable[URI], ): """ @@ -195,13 +202,13 @@ class SparqlStore(base.TripleStoreBase): # FIXME: node exists and may have a different type! ignore? raise? report? continue # add node - self.transaction.add((guid, rdflib.RDF.type, rdflib.URIRef(node_type.uri))) + self._transaction.add((guid, rdflib.RDF.type, rdflib.URIRef(node_type.uri))) def set( self, - node_type: _schema.Node, # FIXME: is the node_type even needed? Couldn't I infer from the predicate? + node_type: bsc.Node, guids: typing.Iterable[URI], - predicate: _schema.Predicate, + predicate: bsc.Predicate, values: typing.Iterable[typing.Any], ): # check node_type @@ -218,7 +225,7 @@ class SparqlStore(base.TripleStoreBase): return if predicate.unique and len(values) != 1: raise ValueError(values) - if isinstance(predicate.range, _schema.Node): + if isinstance(predicate.range, bsc.Node): values = set(values) # materialize to safeguard against iterators passed as argument inconsistent = {val for val in values if not self._has_type(val, predicate.range)} # catches nodes that don't exist and nodes that have an inconsistent type @@ -236,18 +243,18 @@ class SparqlStore(base.TripleStoreBase): for guid, value in itertools.product(guids, values): guid = rdflib.URIRef(guid) # convert value - if isinstance(predicate.range, _schema.Literal): + if isinstance(predicate.range, bsc.Literal): value = rdflib.Literal(value, datatype=rdflib.URIRef(predicate.range.uri)) - elif isinstance(predicate.range, _schema.Node): + elif isinstance(predicate.range, bsc.Node): value = rdflib.URIRef(value) else: raise errors.UnreachableError() # clear triples for unique predicates if predicate.unique: - for obj in self.graph.objects(guid, pred): + for obj in self._graph.objects(guid, pred): if obj != value: - self.transaction.remove((guid, pred, obj)) + self._transaction.remove((guid, pred, obj)) # add triple - self.transaction.add((guid, pred, value)) + self._transaction.add((guid, pred, value)) ## EOF ## diff --git a/test/graph/test_nodes.py b/test/graph/test_nodes.py index 1fbd1e5..71fbb10 100644 --- a/test/graph/test_nodes.py +++ b/test/graph/test_nodes.py @@ -157,10 +157,10 @@ class TestNodes(unittest.TestCase): # missing nodes are created self.assertSetEqual(self.ent_ids, nodes._ensure_nodes(self.ent_type, self.ent_ids)) # get creation time from backend manually - time_triples = list(self.backend.graph.objects(rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri))) + time_triples = list(self.backend._graph.objects(rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri))) t_ent_created = float(time_triples[0]) if len(time_triples) > 0 else 0.0 # check triples - self.assertSetEqual(set(self.backend.graph), { + self.assertSetEqual(set(self.backend._graph), { # entity definitions (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -171,7 +171,7 @@ class TestNodes(unittest.TestCase): # existing nodes remain unchanged self.assertSetEqual(self.ent_ids, nodes._ensure_nodes(self.ent_type, self.ent_ids)) - self.assertSetEqual(set(self.backend.graph), { + self.assertSetEqual(set(self.backend._graph), { # entity definitions (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -183,10 +183,10 @@ class TestNodes(unittest.TestCase): # type and guids don't need to match the node instance's members self.assertSetEqual(self.tag_ids, nodes._ensure_nodes(self.tag_type, self.tag_ids)) # get creation time from backend manually - time_triples = list(self.backend.graph.objects(rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(self.t_created.uri))) + time_triples = list(self.backend._graph.objects(rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(self.t_created.uri))) t_tag_created = float(time_triples[0]) if len(time_triples) > 0 else 0.0 # check triples - self.assertSetEqual(set(self.backend.graph), { + self.assertSetEqual(set(self.backend._graph), { # previous triples (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -202,7 +202,7 @@ class TestNodes(unittest.TestCase): def test___set(self): # setup nodes = Nodes(self.backend, self.user, self.ent_type, {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')}) - self.assertSetEqual(set(self.backend.graph), set()) + self.assertSetEqual(set(self.backend._graph), set()) set_ = nodes._Nodes__set # node_type must match predicate's domain @@ -214,10 +214,10 @@ class TestNodes(unittest.TestCase): # set literal value set_(self.p_filesize.uri, 1234) # get creation time from backend manually - time_triples = list(self.backend.graph.objects(rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri))) + time_triples = list(self.backend._graph.objects(rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri))) t_ent_created = float(time_triples[0]) if len(time_triples) > 0 else 0.0 # verify triples - self.assertSetEqual(set(self.backend.graph), { + self.assertSetEqual(set(self.backend._graph), { # entity definitions (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -233,10 +233,10 @@ class TestNodes(unittest.TestCase): tags = Nodes(self.backend, self.user, self.tag_type, {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')}) set_(self.p_tag.uri, tags) # get creation time from backend manually - time_triples = list(self.backend.graph.objects(rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(self.t_created.uri))) + time_triples = list(self.backend._graph.objects(rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(self.t_created.uri))) t_tag_created = float(time_triples[0]) if len(time_triples) > 0 else 0.0 # verify triples - self.assertSetEqual(set(self.backend.graph), { + self.assertSetEqual(set(self.backend._graph), { # previous values (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -265,11 +265,11 @@ class TestNodes(unittest.TestCase): Nodes(self.backend, self.user, self.ent_type, self.ent_ids)) def test_set(self): - self.assertSetEqual(set(self.backend.graph), set()) + self.assertSetEqual(set(self.backend._graph), set()) nodes = Nodes(self.backend, self.user, self.ent_type, self.ent_ids) # can set literal values self.assertEqual(nodes, nodes.set(self.p_filesize.uri, 1234)) - self.assertTrue(set(self.backend.graph).issuperset({ + self.assertTrue(set(self.backend._graph).issuperset({ # nodes exist (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -279,7 +279,7 @@ class TestNodes(unittest.TestCase): })) # can set node values self.assertEqual(nodes, nodes.set(self.p_tag.uri, Nodes(self.backend, self.user, self.tag_type, self.tag_ids))) - self.assertTrue(set(self.backend.graph).issuperset({ + self.assertTrue(set(self.backend._graph).issuperset({ # nodes exist (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -293,33 +293,33 @@ class TestNodes(unittest.TestCase): })) # cannot set protected predicate - curr = set(self.backend.graph) + curr = set(self.backend._graph) self.assertRaises(errors.PermissionDeniedError, nodes.set, self.t_created.uri, 12345) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # predicate.domain must match node_type self.assertRaises(errors.ConsistencyError, nodes.set, self.p_representative.uri, nodes) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # value's node_type must match predicate's range self.assertRaises(errors.ConsistencyError, nodes.set, self.p_tag.uri, nodes) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # value type must match predicate's range type self.assertRaises(TypeError, nodes.set, self.p_tag.uri, 'invalid') - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # cannot assing multiple values to unique predicate self.assertRaises(ValueError, nodes.set, self.p_author.uri, Nodes(self.backend, self.user, self.user_type, {URI('http://example.com/me/user#1234'), URI('http://example.com/me/user#4321')})) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) def test_set_from_iterable(self): - self.assertSetEqual(set(self.backend.graph), set()) + self.assertSetEqual(set(self.backend._graph), set()) nodes = Nodes(self.backend, self.user, self.ent_type, self.ent_ids) # can set literal and node values simultaneously self.assertEqual(nodes, nodes.set_from_iterable({ self.p_filesize.uri: 1234, self.p_tag.uri: Nodes(self.backend, self.user, self.tag_type, self.tag_ids), }.items())) - self.assertTrue(set(self.backend.graph).issuperset({ + self.assertTrue(set(self.backend._graph).issuperset({ # nodes exist (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), @@ -335,22 +335,22 @@ class TestNodes(unittest.TestCase): })) # cannot set protected predicate - curr = set(self.backend.graph) + curr = set(self.backend._graph) self.assertRaises(errors.PermissionDeniedError, nodes.set_from_iterable, ((self.p_filesize.uri, 1234), (self.t_created.uri, 12345))) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # predicate.domain must match node_type self.assertRaises(errors.ConsistencyError, nodes.set_from_iterable, ((self.p_filesize.uri, 1234), (self.p_representative.uri, nodes))) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # value's node_type must match predicate's range self.assertRaises(errors.ConsistencyError, nodes.set_from_iterable, ((self.p_filesize.uri, 1234), (self.p_tag.uri, nodes))) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # value type must match predicate's range type self.assertRaises(TypeError, nodes.set_from_iterable, ((self.p_filesize.uri, 1234), (self.p_tag.uri, 'invalid'))) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) # cannot assing multiple values to unique predicate self.assertRaises(ValueError, nodes.set_from_iterable, ((self.p_filesize.uri, 1234), (self.p_author.uri, Nodes(self.backend, self.user, self.user_type, {URI('http://example.com/me/user#1234'), URI('http://example.com/me/user#4321')})))) - self.assertSetEqual(curr, set(self.backend.graph)) + self.assertSetEqual(curr, set(self.backend._graph)) ## main ## diff --git a/test/triple_store/test_sparql.py b/test/triple_store/test_sparql.py index f047235..ecf3a07 100644 --- a/test/triple_store/test_sparql.py +++ b/test/triple_store/test_sparql.py @@ -179,7 +179,7 @@ class TestSparqlStore(unittest.TestCase): (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me')), } - self.assertSetEqual(set(store.graph), instances) + self.assertSetEqual(set(store._graph), instances) # add some classes to the schema curr = curr + _schema.Schema.from_string(''' @@ -228,7 +228,7 @@ class TestSparqlStore(unittest.TestCase): store.schema = curr self.assertEqual(store.schema, curr) # instances have not changed - self.assertSetEqual(set(store.graph), instances) + self.assertSetEqual(set(store._graph), instances) # add some instances of the new classes p_partOf = curr.predicate(ns.bse.partOf) p_shared = curr.predicate(ns.bse.shared) @@ -247,7 +247,7 @@ class TestSparqlStore(unittest.TestCase): store.set(curr.node(ns.bsfs.Tag), {URI('http://example.com/me/tag#1234')}, p_principal, {URI('http://example.com/me/collection#1234')}) # new instances are now in the graph - self.assertSetEqual(set(store.graph), instances | { + self.assertSetEqual(set(store._graph), instances | { # collections (rdflib.URIRef('http://example.com/me/collection#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Collection)), (rdflib.URIRef('http://example.com/me/collection#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Collection)), @@ -315,7 +315,7 @@ class TestSparqlStore(unittest.TestCase): store.schema = curr self.assertEqual(store.schema, curr) # instances of old classes were removed - self.assertSetEqual(set(store.graph), { + self.assertSetEqual(set(store._graph), { # node instances (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), @@ -409,14 +409,14 @@ class TestSparqlStore(unittest.TestCase): store.set(ent_type, ent_ids, p_tag, tag_ids) store.set(ent_type, ent_ids, p_filesize, {1234}) # current transaction is visible - self.assertSetEqual(set(store.graph), instances | { + self.assertSetEqual(set(store._graph), instances | { (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), }) # rollback undoes previous changes store.rollback() - self.assertSetEqual(set(store.graph), set()) + self.assertSetEqual(set(store._graph), set()) # add some data once more store.create(ent_type, ent_ids) @@ -424,14 +424,14 @@ class TestSparqlStore(unittest.TestCase): store.set(ent_type, ent_ids, p_tag, tag_ids) store.set(ent_type, ent_ids, p_filesize, {1234}) # current transaction is visible - self.assertSetEqual(set(store.graph), instances | { + self.assertSetEqual(set(store._graph), instances | { (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), }) # commit saves changes store.commit() - self.assertSetEqual(set(store.graph), instances | { + self.assertSetEqual(set(store._graph), instances | { (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), }) @@ -440,7 +440,7 @@ class TestSparqlStore(unittest.TestCase): store.create(ent_type, {URI('http://example.com/me/entity#hello')}) store.set(ent_type, {URI('http://example.com/me/entity#hello')}, p_tag, tag_ids) store.set(ent_type, ent_ids, p_filesize, {4321}) - self.assertSetEqual(set(store.graph), instances | { + self.assertSetEqual(set(store._graph), instances | { (rdflib.URIRef('http://example.com/me/entity#hello'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#hello'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), (rdflib.URIRef('http://example.com/me/entity#hello'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), @@ -450,7 +450,7 @@ class TestSparqlStore(unittest.TestCase): # rollback undoes only changes since last commit store.rollback() - self.assertSetEqual(set(store.graph), instances | { + self.assertSetEqual(set(store._graph), instances | { (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), }) @@ -507,14 +507,14 @@ class TestSparqlStore(unittest.TestCase): # can create some nodes ent_type = store.schema.node(ns.bsfs.Entity) store.create(ent_type, {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')}) - self.assertSetEqual(set(store.graph), { + self.assertSetEqual(set(store._graph), { (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), }) # existing nodes are skipped store.create(ent_type, {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#5678')}) - self.assertSetEqual(set(store.graph), { + self.assertSetEqual(set(store._graph), { # previous triples (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), @@ -525,7 +525,7 @@ class TestSparqlStore(unittest.TestCase): # can create nodes of a different type tag_type = store.schema.node(ns.bsfs.Tag) store.create(tag_type, {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')}) - self.assertSetEqual(set(store.graph), { + self.assertSetEqual(set(store._graph), { # previous triples (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), @@ -538,7 +538,7 @@ class TestSparqlStore(unittest.TestCase): # creation does not change types of existing nodes tag_type = store.schema.node(ns.bsfs.Tag) store.create(tag_type, {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')}) - self.assertSetEqual(set(store.graph), { + self.assertSetEqual(set(store._graph), { # previous triples (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), @@ -595,12 +595,12 @@ class TestSparqlStore(unittest.TestCase): self.assertRaises(errors.ConsistencyError, store.set, tag_type, tag_ids, p_filesize, {1234}) # empty value does not change the graph - plen = len(store.graph) + plen = len(store._graph) store.set(ent_type, ent_ids, p_filesize, []) store.set(ent_type, ent_ids, p_comment, []) store.set(ent_type, ent_ids, p_author, []) store.set(ent_type, ent_ids, p_tag, []) - self.assertEqual(plen, len(store.graph)) + self.assertEqual(plen, len(store._graph)) # cannot set multiple values on unique predicates self.assertRaises(ValueError, store.set, ent_type, ent_ids, p_filesize, {1234, 4321}) @@ -623,50 +623,50 @@ class TestSparqlStore(unittest.TestCase): store.set(ent_type, ent_ids, p_filesize, {1234}) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) # re-assigning the same node changes nothing store.set(ent_type, ent_ids, p_filesize, {1234}) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) # cannot set multiple unique literals self.assertRaises(ValueError, store.set, ent_type, ent_ids, p_filesize, {1234, 4321}) # same test as above # unique literals are overwritten by set store.set(ent_type, ent_ids, p_filesize, {4321}) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('4321', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) self.assertNotIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('4321', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) self.assertNotIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), - set(store.graph)) + set(store._graph)) # set non-unique literal store.set(ent_type, ent_ids, p_comment, {'foobar'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foobar', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foobar', datatype=rdflib.XSD.string)), })) # re-assigning the same node changes nothing store.set(ent_type, ent_ids, p_comment, {'foobar'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foobar', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foobar', datatype=rdflib.XSD.string)), })) # can set multiple non-unique literals at once store.set(ent_type, ent_ids, p_comment, {'foo', 'bar'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foo', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('bar', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foo', datatype=rdflib.XSD.string)), @@ -674,7 +674,7 @@ class TestSparqlStore(unittest.TestCase): })) # non-unique literals are appended by set store.set(ent_type, ent_ids, p_comment, {'hello world'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foo', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('bar', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_comment.uri), rdflib.Literal('hello world', datatype=rdflib.XSD.string)), @@ -687,50 +687,50 @@ class TestSparqlStore(unittest.TestCase): store.set(ent_type, ent_ids, p_author, {URI('http://example.com/me/user#1234')}) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#1234')), - set(store.graph)) + set(store._graph)) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#1234')), - set(store.graph)) + set(store._graph)) # re-assigning the same node changes nothing store.set(ent_type, ent_ids, p_author, {URI('http://example.com/me/user#1234')}) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#1234')), - set(store.graph)) + set(store._graph)) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#1234')), - set(store.graph)) + set(store._graph)) # cannot set multiple unique nodes self.assertRaises(ValueError, store.set, ent_type, ent_ids, p_author, {URI('http://example.com/me/user#1234'), URI('http://example.com/me/user#4321')}) # unique nodes are overwritten by set store.set(ent_type, ent_ids, p_author, {URI('http://example.com/me/user#4321')}) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#4321')), - set(store.graph)) + set(store._graph)) self.assertNotIn( (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#1234')), - set(store.graph)) + set(store._graph)) self.assertIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#4321')), - set(store.graph)) + set(store._graph)) self.assertNotIn( (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_author.uri), rdflib.URIRef('http://example.com/me/user#1234')), - set(store.graph)) + set(store._graph)) # set non-unique node store.set(ent_type, ent_ids, p_tag, {'http://example.com/me/tag#foobar'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#foobar')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#foobar')), })) # re-assigning the same node changes nothing store.set(ent_type, ent_ids, p_tag, {'http://example.com/me/tag#foobar'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#foobar')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#foobar')), })) # can set multiple non-unique literals at once store.set(ent_type, ent_ids, p_tag, {'http://example.com/me/tag#1234', 'http://example.com/me/tag#4321'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), @@ -738,7 +738,7 @@ class TestSparqlStore(unittest.TestCase): })) # non-unique nodes are appended by set store.set(ent_type, ent_ids, p_tag, {'http://example.com/me/tag#foo', 'http://example.com/me/tag#bar'}) - self.assertTrue(set(store.graph).issuperset({ + self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#foo')), @@ -750,10 +750,10 @@ class TestSparqlStore(unittest.TestCase): })) # nothing happens when no guids are given - plen = len(store.graph) + plen = len(store._graph) store.set(ent_type, set(), p_comment, {'xyz'}) store.set(ent_type, set(), p_tag, {URI('http://example.com/me/tag#xyz')}) - self.assertEqual(plen, len(store.graph)) + self.assertEqual(plen, len(store._graph)) # guids must be instances of node_type self.assertRaises(errors.InstanceError, store.set, ent_type, tag_ids, p_comment, {'xyz'}) -- cgit v1.2.3