diff options
Diffstat (limited to 'test/triple_store/test_sparql.py')
-rw-r--r-- | test/triple_store/test_sparql.py | 769 |
1 files changed, 0 insertions, 769 deletions
diff --git a/test/triple_store/test_sparql.py b/test/triple_store/test_sparql.py deleted file mode 100644 index 8d98749..0000000 --- a/test/triple_store/test_sparql.py +++ /dev/null @@ -1,769 +0,0 @@ -""" - -Part of the bsfs test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" -# imports -import rdflib -import unittest - -# bsie imports -from bsfs import schema as _schema -from bsfs.namespace import ns -from bsfs.utils import errors, URI - -# objects to test -from bsfs.triple_store.sparql import SparqlStore - - -## code ## - -class TestSparqlStore(unittest.TestCase): - def setUp(self): - self.schema = _schema.Schema.from_string(''' - prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix xsd: <http://www.w3.org/2001/XMLSchema#> - - prefix bsfs: <http://bsfs.ai/schema/> - prefix bse: <http://bsfs.ai/schema/Entity#> - - bsfs:Entity rdfs:subClassOf bsfs:Node . - bsfs:Tag rdfs:subClassOf bsfs:Node . - bsfs:User rdfs:subClassOf bsfs:Node . - xsd:string rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Literal . - - # non-unique literal - bse:comment rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:string ; - bsfs:unique "false"^^xsd:boolean . - - # unique literal - bse:filesize rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:integer ; - bsfs:unique "true"^^xsd:boolean . - - # non-unique node - bse:tag rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:Tag ; - bsfs:unique "false"^^xsd:boolean . - - # unique node - bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:User ; - bsfs:unique "true"^^xsd:boolean . - - ''') - - def test_essentials(self): - store = SparqlStore.Open() - # equality - self.assertEqual(store, store) - self.assertEqual(hash(store), hash(store)) - self.assertNotEqual(store, SparqlStore.Open()) - self.assertNotEqual(hash(store), hash(SparqlStore.Open())) - # string conversion - self.assertEqual(str(store), 'SparqlStore(uri=None)') - self.assertEqual(repr(store), 'SparqlStore(uri=None)') - # open - self.assertIsInstance(SparqlStore.Open(), SparqlStore) - - - def test__has_type(self): - # setup store - store = SparqlStore.Open() - store.schema = _schema.Schema.from_string(''' - prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix xsd: <http://www.w3.org/2001/XMLSchema#> - prefix bsfs: <http://bsfs.ai/schema/> - - bsfs:Entity rdfs:subClassOf bsfs:Node . - bsfs:Document rdfs:subClassOf bsfs:Entity . - bsfs:Image rdfs:subClassOf bsfs:Entity . - bsfs:PDF rdfs:subClassOf bsfs:Document . - - ''') - # add some instances - store.create(store.schema.node(ns.bsfs.Entity), {URI('http://example.com/me/entity#1234')}) - store.create(store.schema.node(ns.bsfs.Document), {URI('http://example.com/me/document#1234')}) - store.create(store.schema.node(ns.bsfs.Image), {URI('http://example.com/me/image#1234')}) - store.create(store.schema.node(ns.bsfs.PDF), {URI('http://example.com/me/pdf#1234')}) - - # node_type must be in the schema - self.assertRaises(errors.ConsistencyError, store._has_type, URI('http://example.com/me/entity#1234'), store.schema.node(ns.bsfs.Node).get_child(ns.bsfs.invalid)) - - # returns False on inexistent nodes - self.assertFalse(store._has_type(URI('http://example.com/me/entity#4321'), store.schema.node(ns.bsfs.Entity))) - self.assertFalse(store._has_type(URI('http://example.com/me/document#4321'), store.schema.node(ns.bsfs.Document))) - self.assertFalse(store._has_type(URI('http://example.com/me/image#4321'), store.schema.node(ns.bsfs.Image))) - self.assertFalse(store._has_type(URI('http://example.com/me/pdf#4321'), store.schema.node(ns.bsfs.PDF))) - - # _has_type checks direct types - self.assertTrue(store._has_type(URI('http://example.com/me/entity#1234'), store.schema.node(ns.bsfs.Entity))) - self.assertTrue(store._has_type(URI('http://example.com/me/document#1234'), store.schema.node(ns.bsfs.Document))) - self.assertTrue(store._has_type(URI('http://example.com/me/image#1234'), store.schema.node(ns.bsfs.Image))) - self.assertTrue(store._has_type(URI('http://example.com/me/pdf#1234'), store.schema.node(ns.bsfs.PDF))) - - # _has_type checks type hierarchy - self.assertFalse(store._has_type(URI('http://example.com/me/entity#1234'), store.schema.node(ns.bsfs.Document))) - self.assertFalse(store._has_type(URI('http://example.com/me/entity#1234'), store.schema.node(ns.bsfs.Image))) - self.assertFalse(store._has_type(URI('http://example.com/me/entity#1234'), store.schema.node(ns.bsfs.PDF))) - - self.assertTrue(store._has_type(URI('http://example.com/me/document#1234'), store.schema.node(ns.bsfs.Entity))) - self.assertFalse(store._has_type(URI('http://example.com/me/document#1234'), store.schema.node(ns.bsfs.Image))) - self.assertFalse(store._has_type(URI('http://example.com/me/document#1234'), store.schema.node(ns.bsfs.PDF))) - - self.assertTrue(store._has_type(URI('http://example.com/me/image#1234'), store.schema.node(ns.bsfs.Entity))) - self.assertFalse(store._has_type(URI('http://example.com/me/image#1234'), store.schema.node(ns.bsfs.Document))) - self.assertFalse(store._has_type(URI('http://example.com/me/image#1234'), store.schema.node(ns.bsfs.PDF))) - - self.assertTrue(store._has_type(URI('http://example.com/me/pdf#1234'), store.schema.node(ns.bsfs.Entity))) - self.assertTrue(store._has_type(URI('http://example.com/me/pdf#1234'), store.schema.node(ns.bsfs.Document))) - self.assertFalse(store._has_type(URI('http://example.com/me/pdf#1234'), store.schema.node(ns.bsfs.Image))) - - - def test_schema(self): - # setup - store = SparqlStore.Open() - curr = self.schema - p_comment = curr.predicate(ns.bse.comment) - p_filesize = curr.predicate(ns.bse.filesize) - p_tag = curr.predicate(ns.bse.tag) - p_author = curr.predicate(ns.bse.author) - - # migrate to an initial schema - store.schema = curr - # store has migrated - self.assertEqual(store.schema, curr) - - # add some instances - ent_ids = {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')} - tag_ids = {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')} - store.create(curr.node(ns.bsfs.Entity), ent_ids) - store.create(curr.node(ns.bsfs.Tag), tag_ids) - store.create(curr.node(ns.bsfs.User), {URI('http://example.com/me')}) - # add some triples - store.set(curr.node(ns.bsfs.Entity), ent_ids, p_comment, {'foo', 'bar'}) - store.set(curr.node(ns.bsfs.Entity), ent_ids, p_filesize, {1234}) - store.set(curr.node(ns.bsfs.Entity), ent_ids, p_tag, - {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')}) - store.set(curr.node(ns.bsfs.Entity), ent_ids, p_author, - {URI('http://example.com/me')}) - # check instances - instances = { - # 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)), - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.User)), - # comments - (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)), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_comment.uri), rdflib.Literal('bar', datatype=rdflib.XSD.string)), - # filesize - (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)), - # tags - (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')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), - # author - (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) - - # add some classes to the schema - curr = curr + _schema.Schema.from_string(''' - prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix xsd: <http://www.w3.org/2001/XMLSchema#> - prefix bsfs: <http://bsfs.ai/schema/> - prefix bse: <http://bsfs.ai/schema/Entity#> - prefix bst: <http://bsfs.ai/schema/Tag#> - prefix bsc: <http://bsfs.ai/schema/Collection#> - - bsfs:Entity rdfs:subClassOf bsfs:Node . - bsfs:Tag rdfs:subClassOf bsfs:Node . - bsfs:Collection rdfs:subClassOf bsfs:Node . - xsd:boolean rdfs:subClassOf bsfs:Literal . - - # literal - bse:shared rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:boolean ; - bsfs:unique "true"^^xsd:boolean . - - # node - bse:partOf rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:Collection ; - bsfs:unique "false"^^xsd:boolean . - - # predicates across auxiliary node classes - bst:usedIn rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Tag ; - rdfs:range bsfs:Collection ; - bsfs:unique "false"^^xsd:boolean . - - bsc:tag rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Collection ; - rdfs:range bsfs:Tag ; - bsfs:unique "false"^^xsd:boolean . - - bst:principal rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Tag ; - rdfs:range bsfs:Node ; - bsfs:unique "true"^^xsd:boolean . - - ''') - # store migrated to the new schema - store.schema = curr - self.assertEqual(store.schema, curr) - # instances have not changed - 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) - p_usedIn = curr.predicate('http://bsfs.ai/schema/Tag#usedIn') - p_ctag = curr.predicate('http://bsfs.ai/schema/Collection#tag') - p_principal = curr.predicate('http://bsfs.ai/schema/Tag#principal') - store.create(curr.node(ns.bsfs.Collection), {URI('http://example.com/me/collection#1234'), URI('http://example.com/me/collection#4321')}) - # add some more triples - store.set(curr.node(ns.bsfs.Entity), ent_ids, p_shared, {True}) - store.set(curr.node(ns.bsfs.Entity), ent_ids, p_partOf, - {URI('http://example.com/me/collection#1234'), URI('http://example.com/me/collection#4321')}) - store.set(curr.node(ns.bsfs.Tag), {URI('http://example.com/me/tag#1234')}, p_usedIn, - {URI('http://example.com/me/collection#1234')}) - store.set(curr.node(ns.bsfs.Collection), {URI('http://example.com/me/collection#4321')}, p_ctag, - {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')}) - 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 | { - # 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)), - # partOf - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_partOf.uri), rdflib.URIRef('http://example.com/me/collection#1234')), - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_partOf.uri), rdflib.URIRef('http://example.com/me/collection#4321')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_partOf.uri), rdflib.URIRef('http://example.com/me/collection#1234')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_partOf.uri), rdflib.URIRef('http://example.com/me/collection#4321')), - # shared - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_shared.uri), rdflib.Literal('true', datatype=rdflib.XSD.boolean)), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_shared.uri), rdflib.Literal('true', datatype=rdflib.XSD.boolean)), - # auxiliary node connections - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(p_usedIn.uri), rdflib.URIRef('http://example.com/me/collection#1234')), - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(p_principal.uri), rdflib.URIRef('http://example.com/me/collection#1234')), - (rdflib.URIRef('http://example.com/me/collection#4321'), rdflib.URIRef(p_ctag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), - (rdflib.URIRef('http://example.com/me/collection#4321'), rdflib.URIRef(p_ctag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), - }) - - - # remove some classes from the schema - curr = _schema.Schema.from_string(''' - prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix xsd: <http://www.w3.org/2001/XMLSchema#> - prefix bsfs: <http://bsfs.ai/schema/> - prefix bse: <http://bsfs.ai/schema/Entity#> - prefix bst: <http://bsfs.ai/schema/Tag#> - - bsfs:Entity rdfs:subClassOf bsfs:Node . - bsfs:Tag rdfs:subClassOf bsfs:Node . - bsfs:User rdfs:subClassOf bsfs:Node . - - xsd:boolean rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Literal . - - bse:filesize rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:integer ; - bsfs:unique "true"^^xsd:boolean . - - bse:tag rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:Tag ; - bsfs:unique "false"^^xsd:boolean . - - bse:shared rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:boolean ; - bsfs:unique "true"^^xsd:boolean . - - bst:principal rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Tag ; - rdfs:range bsfs:Node ; - bsfs:unique "true"^^xsd:boolean . - - # removed: bsfs:Collection - # removed: xsd:string - # removed: bse:comment (bsfs:Entity -> xsd:string) - # removed: bse:partOf (bsfs:Entity -> bsfs:Collection) - # removed: bse:author (bsfs:entity -> bsfs:User) - # removed: bst:usedIn (bsfs:Tag -> bsfs:Collection) - # removed: bsc:tag (bsfs:Collection -> bsfs:Tag) - - ''') - # store migrated to the new schema - store.schema = curr - self.assertEqual(store.schema, curr) - # instances of old classes were removed - 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)), - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.User)), - # filesize - (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)), - # tags - (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')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), - # shared - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_shared.uri), rdflib.Literal('true', datatype=rdflib.XSD.boolean)), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_shared.uri), rdflib.Literal('true', datatype=rdflib.XSD.boolean)), - }) - - # can only assign schema instances - self.assertRaises(TypeError, setattr, store, 'schema', None) - self.assertRaises(TypeError, setattr, store, 'schema', 1234) - self.assertRaises(TypeError, setattr, store, 'schema', 'foo') - class Foo(): pass - self.assertRaises(TypeError, setattr, store, 'schema', Foo()) - - # cannot migrate to incompatible schema - invalid = _schema.Schema.from_string(''' - prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix xsd: <http://www.w3.org/2001/XMLSchema#> - prefix bsfs: <http://bsfs.ai/schema/> - prefix bse: <http://bsfs.ai/schema/Entity#> - - bsfs:Entity rdfs:subClassOf bsfs:Node . - bsfs:Tag rdfs:subClassOf bsfs:Entity . # inconsistent with previous tag definition - - bse:tag rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:Tag ; - bsfs:unique "false"^^xsd:boolean . - - ''') - self.assertRaises(errors.ConsistencyError, setattr, store, 'schema', invalid) - invalid = _schema.Schema.from_string(''' - prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix xsd: <http://www.w3.org/2001/XMLSchema#> - prefix bsfs: <http://bsfs.ai/schema/> - prefix bse: <http://bsfs.ai/schema/Entity#> - - bsfs:Entity rdfs:subClassOf bsfs:Node . - bsfs:User rdfs:subClassOf bsfs:Node . - - # inconsistent predicate - bse:tag rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:User; - bsfs:unique "false"^^xsd:boolean . - - ''') - self.assertRaises(errors.ConsistencyError, setattr, store, 'schema', invalid) - - - def test_transaction(self): - # store setup - store = SparqlStore.Open() - store.schema = self.schema - p_tag = store.schema.predicate(ns.bse.tag) - p_filesize = store.schema.predicate(ns.bse.filesize) - # prepare node types - ent_type = store.schema.node(ns.bsfs.Entity) - tag_type = store.schema.node(ns.bsfs.Tag) - ent_ids = {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')} - tag_ids = {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')} - # target instances - instances = { - # 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)), - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - # links - (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')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), - } - - # add some data - store.create(ent_type, ent_ids) - store.create(tag_type, tag_ids) - 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 | { - (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()) - - # add some data once more - store.create(ent_type, ent_ids) - store.create(tag_type, tag_ids) - 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 | { - (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 | { - (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)), - }) - - # add additional data - 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 | { - (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')), - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(4321, datatype=rdflib.XSD.integer)), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_filesize.uri), rdflib.Literal(4321, datatype=rdflib.XSD.integer)), - }) - - # rollback undoes only changes since last commit - store.rollback() - 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)), - }) - - - def test_exists(self): - # store setup - store = SparqlStore.Open() - store.schema = self.schema - # prepare node types - ent_type = store.schema.node(ns.bsfs.Entity) - tag_type = store.schema.node(ns.bsfs.Tag) - # create node instances - ent_ids = { - URI('http://example.com/me/entity#1234'), - URI('http://example.com/me/entity#4321'), - } - tag_ids = { - URI('http://example.com/me/tag#1234'), - URI('http://example.com/me/tag#4321'), - } - store.create(ent_type, ent_ids) - store.create(tag_type, tag_ids) - - # exists returns all existing nodes of the correct type - self.assertSetEqual(ent_ids, set(store.exists(ent_type, ent_ids))) - self.assertSetEqual(tag_ids, set(store.exists(tag_type, tag_ids))) - # exists returns only nodes that match the type - self.assertSetEqual(set(), set(store.exists(ent_type, tag_ids))) - self.assertSetEqual({URI('http://example.com/me/entity#1234')}, set(store.exists(ent_type, { - URI('http://example.com/me/tag#1234'), - URI('http://example.com/me/entity#1234'), - }))) - # exists returns only nodes that exist - self.assertSetEqual(set(), set(store.exists(ent_type, { - URI('http://example.com/me/entity#foo'), - URI('http://example.com/me/entity#bar'), - }))) - self.assertSetEqual({URI('http://example.com/me/entity#1234')}, set(store.exists(ent_type, { - URI('http://example.com/me/entity#foo'), - URI('http://example.com/me/entity#1234'), - }))) - - - def test_create(self): - # setup - store = SparqlStore.Open() - store.schema = self.schema - - # node type must be valid - self.assertRaises(errors.ConsistencyError, store.create, self.schema.node(ns.bsfs.Entity).get_child(ns.bsfs.invalid), { - URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')}) - - # 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), { - (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), { - # 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)), - # new triples - (rdflib.URIRef('http://example.com/me/entity#5678'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), - }) - - # 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), { - # 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)), - (rdflib.URIRef('http://example.com/me/entity#5678'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), - # new triples - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - }) - - # 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), { - # 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)), - (rdflib.URIRef('http://example.com/me/entity#5678'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), - # new triples - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Tag)), - }) - - - def test_set(self): - # store setup - store = SparqlStore.Open() - store.schema = self.schema - # prepare node types - ent_type = store.schema.node(ns.bsfs.Entity) - user_type = store.schema.node(ns.bsfs.User) - tag_type = store.schema.node(ns.bsfs.Tag) - # prepare predicates - p_filesize = store.schema.predicate(ns.bse.filesize) - p_comment = store.schema.predicate(ns.bse.comment) - p_author = store.schema.predicate(ns.bse.author) - p_tag = store.schema.predicate(ns.bse.tag) - p_invalid = store.schema.predicate(ns.bsfs.Predicate).get_child(ns.bsfs.foo, range=store.schema.node(ns.bsfs.Tag)) - # create node instances - ent_ids = { - URI('http://example.com/me/entity#1234'), - URI('http://example.com/me/entity#4321'), - } - tag_ids = { - URI('http://example.com/me/tag#1234'), - URI('http://example.com/me/tag#4321'), - URI('http://example.com/me/tag#foo'), - URI('http://example.com/me/tag#bar'), - URI('http://example.com/me/tag#foobar'), - URI('http://example.com/me/tag#xyz'), - } - user_ids = { - URI('http://example.com/me/user#1234'), - URI('http://example.com/me/user#4321'), - } - store.create(ent_type, ent_ids) - store.create(tag_type, tag_ids) - store.create(user_type, user_ids) - - # invalid node_type is not permitted - self.assertRaises(errors.ConsistencyError, store.set, self.schema.node(ns.bsfs.Node).get_child(ns.bse.foo), - ent_ids, p_comment, {'hello world'}) - - # invalid predicate is not permitted - self.assertRaises(errors.ConsistencyError, store.set, ent_type, ent_ids, p_invalid, {'http://example.com/me/tag#1234'}) - - # predicate must match node_type - self.assertRaises(errors.ConsistencyError, store.set, tag_type, tag_ids, p_filesize, {1234}) - - # empty value does not change the 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)) - - # cannot set multiple values on unique predicates - self.assertRaises(ValueError, store.set, ent_type, ent_ids, p_filesize, {1234, 4321}) - 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')}) - - # value nodes must exist - self.assertRaises(errors.InstanceError, store.set, ent_type, ent_ids, p_author, {URI('http://example.com/me/user#invalid')}) - self.assertRaises(errors.InstanceError, store.set, ent_type, ent_ids, p_tag, {URI('http://example.com/me/tag#invalid')}) - - # value node types must be consistent with the predicate - self.assertRaises(errors.InstanceError, store.set, ent_type, ent_ids, p_author, {URI('http://example.com/me/entity#1234')}) - self.assertRaises(errors.InstanceError, store.set, ent_type, ent_ids, p_tag, {URI('http://example.com/me/entity#1234')}) - - # all value nodes must exist and be consistent - self.assertRaises(errors.InstanceError, store.set, ent_type, ent_ids, p_tag, { - URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#invalid'), URI('http://example.com/me/entity#1234')}) - - - # set unique literal - 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)) - 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)) - # 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)) - 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)) - # 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)) - 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)) - 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)) - 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 non-unique literal - store.set(ent_type, ent_ids, p_comment, {'foobar'}) - 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({ - (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({ - (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)), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_comment.uri), rdflib.Literal('bar', datatype=rdflib.XSD.string)), - })) - # non-unique literals are appended by set - store.set(ent_type, ent_ids, p_comment, {'hello world'}) - 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)), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_comment.uri), rdflib.Literal('foo', datatype=rdflib.XSD.string)), - (rdflib.URIRef('http://example.com/me/entity#4321'), 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('hello world', datatype=rdflib.XSD.string)), - })) - - # set unique node - 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)) - 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)) - # 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)) - 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)) - # 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)) - 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)) - 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)) - 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 non-unique node - store.set(ent_type, ent_ids, p_tag, {'http://example.com/me/tag#foobar'}) - 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({ - (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({ - (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')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), - })) - # 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({ - (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')), - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#bar')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), - (rdflib.URIRef('http://example.com/me/entity#4321'), 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#foo')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(p_tag.uri), rdflib.URIRef('http://example.com/me/tag#bar')), - })) - - # nothing happens when no guids are given - 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)) - - # guids must be instances of node_type - self.assertRaises(errors.InstanceError, store.set, ent_type, tag_ids, p_comment, {'xyz'}) - # inexistent guids - self.assertRaises(errors.InstanceError, store.set, ent_type, {URI('http://example.com/me/entity#foobar')}, p_comment, {'xyz'}) - - -## main ## - -if __name__ == '__main__': - unittest.main() - -## EOF ## |