Pārlūkot izejas kodu

More complete graph routing support.

Stefano Cossu 7 gadi atpakaļ
vecāks
revīzija
29f4d918b5

+ 1 - 1
lakesuperior/model/ldp_rs.py

@@ -58,7 +58,7 @@ class LdpRs(Ldpr):
         '''
         Calculate the delta obtained by a SPARQL Update operation.
 
-        This is a critical component of the SPARQL query prcess and does a
+        This is a critical component of the SPARQL update prcess and does a
         couple of things:
 
         1. It ensures that no resources outside of the subject of the request

+ 39 - 43
lakesuperior/model/ldpr.py

@@ -581,51 +581,50 @@ class Ldpr(metaclass=ABCMeta):
         '''
         create = create_only or not self.is_stored
 
-        self.metadata = self._srv_mgd_triples(create)
+        self._add_srv_mgd_triples(create)
         #self._ensure_single_subject_rdf(self.provided_imr.graph)
         ref_int = self.rdfly.config['referential_integrity']
         if ref_int:
             self._check_ref_int(ref_int)
 
-        self.rdfly.create_or_replace_rsrc(self.uid, self.provided_imr.graph,
-                self.metadata.graph)
+        self.rdfly.create_or_replace_rsrc(self.uid, self.provided_imr.graph)
 
         self._set_containment_rel()
 
         return self.RES_CREATED if create else self.RES_UPDATED
 
 
-    def _create_rsrc(self):
-        '''
-        Create a new resource by comparing an empty graph with the provided
-        IMR graph.
-        '''
-        self._modify_rsrc(self.RES_CREATED, add_trp=self.provided_imr.graph)
+    #def _create_rsrc(self):
+    #    '''
+    #    Create a new resource by comparing an empty graph with the provided
+    #    IMR graph.
+    #    '''
+    #    self._modify_rsrc(self.RES_CREATED, add_trp=self.provided_imr.graph)
 
-        # Set the IMR contents to the "add" triples.
-        #self.imr = self.provided_imr.graph
+    #    # Set the IMR contents to the "add" triples.
+    #    #self.imr = self.provided_imr.graph
 
-        return self.RES_CREATED
+    #    return self.RES_CREATED
 
 
-    def _replace_rsrc(self):
-        '''
-        Replace a resource.
+    #def _replace_rsrc(self):
+    #    '''
+    #    Replace a resource.
 
-        The existing resource graph is removed except for the protected terms.
-        '''
-        # The extracted IMR is used as a "minus" delta, so protected predicates
-        # must be removed.
-        for p in self.protected_pred:
-            self.imr.remove(p)
+    #    The existing resource graph is removed except for the protected terms.
+    #    '''
+    #    # The extracted IMR is used as a "minus" delta, so protected predicates
+    #    # must be removed.
+    #    for p in self.protected_pred:
+    #        self.imr.remove(p)
 
-        delta = self._dedup_deltas(self.imr.graph, self.provided_imr.graph)
-        self._modify_rsrc(self.RES_UPDATED, *delta)
+    #    delta = self._dedup_deltas(self.imr.graph, self.provided_imr.graph)
+    #    self._modify_rsrc(self.RES_UPDATED, *delta)
 
-        # Set the IMR contents to the "add" triples.
-        #self.imr = delta[1]
+    #    # Set the IMR contents to the "add" triples.
+    #    #self.imr = delta[1]
 
-        return self.RES_UPDATED
+    #    return self.RES_UPDATED
 
 
     def _bury_rsrc(self, inbound, tstone_pointer=None):
@@ -672,11 +671,11 @@ class Ldpr(metaclass=ABCMeta):
         # Remove resource itself.
         self.rdfly.modify_rsrc(self.uid, {(self.urn, None, None)}, types=None)
 
-        # Remove fragments.
-        for frag_urn in imr.graph[
-                : nsc['fcsystem'].fragmentOf : self.urn]:
-            self.rdfly.modify_rsrc(
-                    self.uid, {(frag_urn, None, None)}, types={})
+        ## Remove fragments.
+        #for frag_urn in imr.graph[
+        #        : nsc['fcsystem'].fragmentOf : self.urn]:
+        #    self.rdfly.modify_rsrc(
+        #            self.uid, {(frag_urn, None, None)}, types={})
 
         # Remove snapshots.
         for snap_urn in self.versions:
@@ -858,36 +857,33 @@ class Ldpr(metaclass=ABCMeta):
         return gr
 
 
-    def _srv_mgd_triples(self, create=False):
+    def _add_srv_mgd_triples(self, create=False):
         '''
         Add server-managed triples to a provided IMR.
 
         @param create (boolean) Whether the resource is being created.
         '''
-        metadata = Resource(Graph(), self.urn)
         # Base LDP types.
         for t in self.base_types:
-            metadata.add(RDF.type, t)
+            self.provided_imr.add(RDF.type, t)
 
         # Message digest.
         cksum = g.tbox.rdf_cksum(self.provided_imr.graph)
-        metadata.set(nsc['premis'].hasMessageDigest,
+        self.provided_imr.set(nsc['premis'].hasMessageDigest,
                 URIRef('urn:sha1:{}'.format(cksum)))
 
         # Create and modify timestamp.
         if create:
-            metadata.set(nsc['fcrepo'].created, g.timestamp_term)
-            metadata.set(nsc['fcrepo'].createdBy, self.DEFAULT_USER)
+            self.provided_imr.set(nsc['fcrepo'].created, g.timestamp_term)
+            self.provided_imr.set(nsc['fcrepo'].createdBy, self.DEFAULT_USER)
         else:
-            metadata.set(nsc['fcrepo'].created, self.metadata.value(
+            self.provided_imr.set(nsc['fcrepo'].created, self.metadata.value(
                     nsc['fcrepo'].created))
-            metadata.set(nsc['fcrepo'].createdBy, self.metadata.value(
+            self.provided_imr.set(nsc['fcrepo'].createdBy, self.metadata.value(
                     nsc['fcrepo'].createdBy))
 
-        metadata.set(nsc['fcrepo'].lastModified, g.timestamp_term)
-        metadata.set(nsc['fcrepo'].lastModifiedBy, self.DEFAULT_USER)
-
-        return metadata
+        self.provided_imr.set(nsc['fcrepo'].lastModified, g.timestamp_term)
+        self.provided_imr.set(nsc['fcrepo'].lastModifiedBy, self.DEFAULT_USER)
 
 
     def _set_containment_rel(self):

+ 41 - 24
lakesuperior/store_layouts/ldp_rs/rsrc_centric_layout.py

@@ -1,5 +1,6 @@
 import logging
 
+from collections import defaultdict
 from copy import deepcopy
 from urllib.parse import quote
 
@@ -72,6 +73,7 @@ class RsrcCentricLayout:
                 nsc['fcrepo'].Binary,
                 nsc['fcrepo'].Container,
                 nsc['fcrepo'].Pairtree,
+                nsc['fcrepo'].Resource,
                 nsc['ldp'].BasicContainer,
                 nsc['ldp'].Container,
                 nsc['ldp'].DirectContainer,
@@ -148,13 +150,14 @@ class RsrcCentricLayout:
 
     def extract_imr(
                 self, uid, ver_uid=None, strict=True, incl_inbound=False,
-                incl_children=True, embed_children=False, incl_srv_mgd=True):
+                incl_children=True, embed_children=False):
         '''
         See base_rdf_layout.extract_imr.
         '''
+        # @TODO Remove inbound functionality in favor of SPARQL query endpoint?
         inbound_construct = '\n?s1 ?p1 ?s .' if incl_inbound else ''
         inbound_qry = '''
-        OPTIONAL {
+        UNION {
           GRAPH ?g {
             ?s1 ?p1 ?s .
           }
@@ -165,8 +168,8 @@ class RsrcCentricLayout:
         ''' if incl_inbound else ''
 
         # Include and/or embed children.
-        embed_children_trp = embed_children_qry = ''
-        if incl_srv_mgd and incl_children:
+        incl_children_qry = embed_children_trp = embed_children_qry = ''
+        if incl_children:
             incl_children_qry = '''
             UNION {
               GRAPH ?strg {
@@ -174,7 +177,6 @@ class RsrcCentricLayout:
               }
             }
             '''
-
             # Embed children.
             if embed_children:
                 embed_children_trp = '?c ?cp ?co .'
@@ -183,9 +185,7 @@ class RsrcCentricLayout:
                   ?s ldp:contains ?c .
                   {}
                 }}
-                '''.format(embed_children_trp)
-        else:
-            incl_children_qry = ''
+                '''.format(embed_children_trp) # @TODO incomplete
 
         q = '''
         CONSTRUCT {{
@@ -215,9 +215,10 @@ class RsrcCentricLayout:
 
         mg = ROOT_GRAPH_URI if uid == '' else nsc['fcmeta'][uid]
         strg = ROOT_GRAPH_URI if uid == '' else nsc['fcstruct'][uid]
+        sg = self._state_uri(uid, ver_uid)
         try:
             qres = self.ds.query(q, initBindings={'mg': mg, 'strg': strg,
-                'sg': self._state_uri(uid, ver_uid)})
+                'sg': sg})
         except ResultException:
             # RDFlib bug: https://github.com/RDFLib/rdflib/issues/775
             gr = Graph()
@@ -314,7 +315,7 @@ class RsrcCentricLayout:
         return Resource(gr | Graph(), nsc['fcres'][uid])
 
 
-    def create_or_replace_rsrc(self, uid, data, metadata, ver_uid=None):
+    def create_or_replace_rsrc(self, uid, trp, ver_uid=None):
         '''
         Create a new resource or replace an existing one.
         '''
@@ -330,23 +331,35 @@ class RsrcCentricLayout:
 
         self.ds.update(drop_qry)
 
-        sg = self.ds.graph(sg_uri)
-        sg += data
-        mg = self.ds.graph(mg_uri)
-        mg += metadata
+        return self.modify_rsrc(uid, add_trp=trp)
+        #sg = self.ds.graph(sg_uri)
+        #sg += data
+        #mg = self.ds.graph(mg_uri)
+        #mg += metadata
 
 
     def modify_rsrc(self, uid, remove_trp=set(), add_trp=set()):
         '''
         See base_rdf_layout.update_rsrc.
         '''
-        for t in remove_trp:
-            target_gr = self.ds.graph(self._map_graph_uri(t, uid))
-            target_gr.remove(t)
+        remove_routes = defaultdict(set)
+        add_routes = defaultdict(set)
 
+        # Create add and remove sets for each graph.
+        for t in remove_trp:
+            target_gr_uri = self._map_graph_uri(t, uid)
+            remove_routes[target_gr_uri].add(t)
         for t in add_trp:
-            target_gr = self.ds.graph(self._map_graph_uri(t, uid))
-            target_gr.add(t)
+            target_gr_uri = self._map_graph_uri(t, uid)
+            add_routes[target_gr_uri].add(t)
+
+        # Remove and add triple sets from each graph.
+        for gr_uri, trp in remove_routes.items():
+            gr = self.ds.graph(gr_uri)
+            gr -= trp
+        for gr_uri, trp in add_routes.items():
+            gr = self.ds.graph(gr_uri)
+            gr += trp
 
 
     ## PROTECTED MEMBERS ##
@@ -359,20 +372,24 @@ class RsrcCentricLayout:
             #raise InvalidResourceError(uid,
             #        'Repository root does not accept user-defined properties.')
             return ROOT_GRAPH_URI
+
         if version_uid:
             uid += ':' + version_uid
-        else:
-            return nsc['fcstate'][uid]
+
+        return nsc['fcstate'][uid]
 
 
-    def _meta_uri(self, uid):
+    def _meta_uri(self, uid, ver_uid=None):
         '''
         Convert a UID into a request URL to the graph store.
         '''
         if not uid:
             return ROOT_GRAPH_URI
-        else:
-            return nsc['fcmeta'][uid]
+
+        if version_uid:
+            uid += ':' + version_uid
+
+        return nsc['fcmeta'][uid]
 
 
     def _map_graph_uri(self, t, uid):