Ver Fonte

Add from_rdf() factory function (experimental); fix more tests.

Stefano Cossu há 5 anos atrás
pai
commit
c7ed454db4

+ 8 - 7
lakesuperior/api/admin.py

@@ -80,15 +80,16 @@ def fixity_check(uid):
     from lakesuperior.model.ldp.ldp_factory import LDP_NR_TYPE
 
     rsrc = rsrc_api.get(uid)
-    if LDP_NR_TYPE not in rsrc.ldp_types:
-        raise IncompatibleLdpTypeError()
+    with env.app_globals.rdf_store.txn_ctx():
+        if LDP_NR_TYPE not in rsrc.ldp_types:
+            raise IncompatibleLdpTypeError()
 
-    ref_digest_term = rsrc.metadata.value(nsc['premis'].hasMessageDigest)
-    ref_digest_parts = ref_digest_term.split(':')
-    ref_cksum = ref_digest_parts[-1]
-    ref_cksum_algo = ref_digest_parts[-2]
+        ref_digest_term = rsrc.metadata.value(nsc['premis'].hasMessageDigest)
+        ref_digest_parts = ref_digest_term.split(':')
+        ref_cksum = ref_digest_parts[-1]
+        ref_cksum_algo = ref_digest_parts[-2]
 
-    calc_cksum = hashlib.new(ref_cksum_algo, rsrc.content.read()).hexdigest()
+        calc_cksum = hashlib.new(ref_cksum_algo, rsrc.content.read()).hexdigest()
 
     if calc_cksum != ref_cksum:
         raise ChecksumValidationError(uid, ref_cksum, calc_cksum)

+ 6 - 6
lakesuperior/model/ldp/ldp_factory.py

@@ -3,7 +3,6 @@ import logging
 from pprint import pformat
 from uuid import uuid4
 
-from rdflib import Graph, parser
 from rdflib.resource import Resource
 from rdflib.namespace import RDF
 
@@ -100,14 +99,15 @@ class LdpFactory:
         """
         uri = nsc['fcres'][uid]
         if rdf_data:
-            data = set(Graph().parse(
-                data=rdf_data, format=rdf_fmt, publicID=nsc['fcres'][uid]))
+            provided_imr = from_rdf(
+                uri=uri, data=rdf_data, format=rdf_fmt,
+                publicID=nsc['fcres'][uid]
+            )
         elif graph:
-            data = set(graph)
+            provided_imr = Graph(uri=uri, data={*graph})
         else:
-            data = set()
+            provided_imr = Graph(uri=uri)
 
-        provided_imr = Graph(uri=uri, data=data)
         #logger.debug('Provided graph: {}'.format(
         #        pformat(set(provided_imr))))
 

+ 3 - 2
lakesuperior/model/ldp/ldpr.py

@@ -895,8 +895,9 @@ class Ldpr(metaclass=ABCMeta):
         # Only update parent if the resource is new.
         if create:
             add_gr = Graph()
-            add_gr.add(
-                (nsc['fcres'][parent_uid], nsc['ldp'].contains, self.uri))
+            add_gr.add({
+                (nsc['fcres'][parent_uid], nsc['ldp'].contains, self.uri)
+            })
             parent_rsrc.modify(RES_UPDATED, add_trp=add_gr)
 
         # Direct or indirect container relationship.

+ 25 - 0
lakesuperior/model/rdf/graph.pyx

@@ -583,6 +583,31 @@ cdef class Graph:
 
 
 
+## FACTORY METHODS
+
+def from_rdf(store=None, uri=None, *args, **kwargs):
+    """
+    Create a Graph from a serialized RDF string.
+
+    This factory function takes the same arguments as
+    :py:meth:`rdflib.Graph.parse`.
+
+    :param store: see :py:meth:`Graph.__cinit__`.
+
+    :param uri: see :py:meth:`Graph.__cinit__`.
+
+    :param *args: Positional arguments passed to RDFlib's ``parse``.
+
+    :param *kwargs: Keyword arguments passed to RDFlib's ``parse``.
+
+    :rtype: Graph
+    """
+    gr = rdflib.Graph().parse(*args, **kwargs)
+
+    logger.info(f'graph: {set(gr)}')
+    return Graph(store=store, uri=uri, data={*gr})
+
+
 ## LOOKUP CALLBACK FUNCTIONS
 
 cdef inline void add_trp_callback(

+ 11 - 6
tests/2_api/test_admin_api.py

@@ -4,13 +4,14 @@ import pytest
 from io import BytesIO
 from uuid import uuid4
 
-from rdflib import Graph, URIRef
+from rdflib import URIRef
 
 from lakesuperior import env
 from lakesuperior.api import resource as rsrc_api
 from lakesuperior.api import admin as admin_api
 from lakesuperior.dictionaries.namespaces import ns_collection as nsc
 from lakesuperior.exceptions import ChecksumValidationError
+from lakesuperior.model.rdf.graph import Graph, from_rdf
 
 
 @pytest.mark.usefixtures('db')
@@ -25,9 +26,12 @@ class TestAdminApi:
         """
         uid1 = '/test_refint1'
         uid2 = '/test_refint2'
-        gr = Graph().parse(
-                data='<> <http://ex.org/ns#p1> <info:fcres{}> .'.format(uid1),
-                format='turtle', publicID=nsc['fcres'][uid2])
+        with env.app_globals.rdf_store.txn_ctx():
+            gr = from_rdf(
+                store=env.app_globals.rdf_store,
+                data=f'<> <http://ex.org/ns#p1> <info:fcres{uid1}> .',
+                format='turtle', publicID=nsc['fcres'][uid2]
+            )
         rsrc_api.create_or_replace(uid1, graph=gr)
 
         assert admin_api.integrity_check() == set()
@@ -76,8 +80,9 @@ class TestAdminApi:
 
         _, rsrc = rsrc_api.create_or_replace(uid, stream=content)
 
-        with open(rsrc.local_path, 'wb') as fh:
-            fh.write(uuid4().bytes)
+        with env.app_globals.rdf_store.txn_ctx():
+            with open(rsrc.local_path, 'wb') as fh:
+                fh.write(uuid4().bytes)
 
         with pytest.raises(ChecksumValidationError):
             admin_api.fixity_check(uid)

+ 46 - 35
tests/2_api/test_resource_api.py

@@ -4,7 +4,7 @@ import pytest
 from io import BytesIO
 from uuid import uuid4
 
-from rdflib import Graph, Literal, URIRef
+from rdflib import Literal, URIRef
 
 from lakesuperior import env
 from lakesuperior.api import resource as rsrc_api
@@ -14,7 +14,7 @@ from lakesuperior.exceptions import (
         TombstoneError)
 from lakesuperior.globals import RES_CREATED, RES_UPDATED
 from lakesuperior.model.ldp.ldpr import Ldpr
-from lakesuperior.model.rdf.graph import Graph
+from lakesuperior.model.rdf.graph import Graph, from_rdf
 
 
 @pytest.fixture(scope='module')
@@ -69,10 +69,11 @@ class TestResourceCRUD:
         gr = rsrc_api.get_metadata('/')
         assert isinstance(gr, Graph)
         assert len(gr) == 9
-        assert gr[gr.uri : nsc['rdf'].type : nsc['ldp'].Resource ]
-        assert not gr[
-            gr.uri : nsc['dcterms'].title : Literal("Repository Root")
-        ]
+        with env.app_globals.rdf_store.txn_ctx():
+            assert gr[gr.uri : nsc['rdf'].type : nsc['ldp'].Resource ]
+            assert not gr[
+                gr.uri : nsc['dcterms'].title : Literal("Repository Root")
+            ]
 
 
     def test_get_root_node(self):
@@ -85,9 +86,10 @@ class TestResourceCRUD:
         assert isinstance(rsrc, Ldpr)
         gr = rsrc.imr
         assert len(gr) == 10
-        assert gr[gr.uri : nsc['rdf'].type : nsc['ldp'].Resource ]
-        assert gr[
-            gr.uri : nsc['dcterms'].title : Literal('Repository Root')]
+        with env.app_globals.rdf_store.txn_ctx():
+            assert gr[gr.uri : nsc['rdf'].type : nsc['ldp'].Resource ]
+            assert gr[
+                gr.uri : nsc['dcterms'].title : Literal('Repository Root')]
 
 
     def test_get_nonexisting_node(self):
@@ -104,16 +106,18 @@ class TestResourceCRUD:
         """
         uid = '/rsrc_from_graph'
         uri = nsc['fcres'][uid]
-        gr = Graph().parse(
-            data='<> a <http://ex.org/type#A> .', format='turtle',
-            publicID=uri)
+        with env.app_globals.rdf_store.txn_ctx():
+            gr = from_rdf(
+                data='<> a <http://ex.org/type#A> .', format='turtle',
+                publicID=uri)
         evt, _ = rsrc_api.create_or_replace(uid, graph=gr)
 
         rsrc = rsrc_api.get(uid)
-        assert rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#A')]
-        assert rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : nsc['ldp'].RDFSource]
+        with env.app_globals.rdf_store.txn_ctx():
+            assert rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#A')]
+            assert rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : nsc['ldp'].RDFSource]
 
 
     def test_create_ldp_nr(self):
@@ -132,32 +136,38 @@ class TestResourceCRUD:
     def test_replace_rsrc(self):
         uid = '/test_replace'
         uri = nsc['fcres'][uid]
-        gr1 = Graph().parse(
-            data='<> a <http://ex.org/type#A> .', format='turtle',
-            publicID=uri)
+        with env.app_globals.rdf_store.txn_ctx():
+            gr1 = from_rdf(
+                data='<> a <http://ex.org/type#A> .', format='turtle',
+                publicID=uri
+            )
         evt, _ = rsrc_api.create_or_replace(uid, graph=gr1)
         assert evt == RES_CREATED
 
         rsrc = rsrc_api.get(uid)
-        assert rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#A')]
-        assert rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : nsc['ldp'].RDFSource]
-
-        gr2 = Graph().parse(
-            data='<> a <http://ex.org/type#B> .', format='turtle',
-            publicID=uri)
+        with env.app_globals.rdf_store.txn_ctx():
+            assert rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#A')]
+            assert rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : nsc['ldp'].RDFSource]
+
+        with env.app_globals.rdf_store.txn_ctx():
+            gr2 = from_rdf(
+                data='<> a <http://ex.org/type#B> .', format='turtle',
+                publicID=uri
+            )
         #pdb.set_trace()
         evt, _ = rsrc_api.create_or_replace(uid, graph=gr2)
         assert evt == RES_UPDATED
 
         rsrc = rsrc_api.get(uid)
-        assert not rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#A')]
-        assert rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#B')]
-        assert rsrc.imr[
-                rsrc.uri : nsc['rdf'].type : nsc['ldp'].RDFSource]
+        with env.app_globals.rdf_store.txn_ctx():
+            assert not rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#A')]
+            assert rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : URIRef('http://ex.org/type#B')]
+            assert rsrc.imr[
+                    rsrc.uri : nsc['rdf'].type : nsc['ldp'].RDFSource]
 
 
     def test_replace_incompatible_type(self):
@@ -169,9 +179,10 @@ class TestResourceCRUD:
         uid_rs = '/test_incomp_rs'
         uid_nr = '/test_incomp_nr'
         data = b'mock binary content'
-        gr = Graph().parse(
+        gr = from_rdf(
             data='<> a <http://ex.org/type#A> .', format='turtle',
-            publicID=nsc['fcres'][uid_rs])
+            publicID=nsc['fcres'][uid_rs]
+        )
 
         rsrc_api.create_or_replace(uid_rs, graph=gr)
         rsrc_api.create_or_replace(