Browse Source

Bury + resurrect.

Stefano Cossu 7 years ago
parent
commit
d3efab525e

+ 11 - 3
lakesuperior/api/resource.py

@@ -310,7 +310,7 @@ def delete(uid, soft=True):
 
 
     if soft:
     if soft:
         rsrc = LdpFactory.from_stored(uid, repr_opts)
         rsrc = LdpFactory.from_stored(uid, repr_opts)
-        ret = rsrc.bury_rsrc(inbound)
+        ret = rsrc.bury(inbound)
 
 
         for child_uri in children:
         for child_uri in children:
             try:
             try:
@@ -319,7 +319,7 @@ def delete(uid, soft=True):
                     repr_opts={'incl_children' : False})
                     repr_opts={'incl_children' : False})
             except (TombstoneError, ResourceNotExistsError):
             except (TombstoneError, ResourceNotExistsError):
                 continue
                 continue
-            child_rsrc.bury_rsrc(inbound, tstone_pointer=rsrc.uri)
+            child_rsrc.bury(inbound, tstone_pointer=rsrc.uri)
     else:
     else:
         ret = env.app_globals.rdfly.forget_rsrc(uid, inbound)
         ret = env.app_globals.rdfly.forget_rsrc(uid, inbound)
         for child_uri in children:
         for child_uri in children:
@@ -347,4 +347,12 @@ def resurrect(uid):
 
 
     :param str uid: Resource UID.
     :param str uid: Resource UID.
     """
     """
-    return LdpFactory.from_stored(uid, strict=False).resurrect_rsrc()
+    try:
+        rsrc = LdpFactory.from_stored(uid)
+    except TombstoneError as e:
+        if e.uid != uid:
+            raise
+        else:
+            return LdpFactory.from_stored(uid, strict=False).resurrect()
+    else:
+        raise InvalidResourceError('Resource {} is not dead.'.format(uid))

+ 2 - 4
lakesuperior/model/ldp_factory.py

@@ -52,12 +52,10 @@ class LdpFactory:
 
 
         N.B. The resource must exist.
         N.B. The resource must exist.
 
 
-        :param  uid: UID of the instance.
+        :param str uid: UID of the instance.
         """
         """
-        #logger.info('Retrieving stored resource: {}'.format(uid))
+        # This will blow up if strict is True and the resource is a tombstone.
         rsrc_meta = rdfly.get_metadata(uid, strict=strict)
         rsrc_meta = rdfly.get_metadata(uid, strict=strict)
-        #logger.debug('Extracted metadata: {}'.format(
-        #        pformat(set(rsrc_meta))))
         rdf_types = set(rsrc_meta[nsc['fcres'][uid] : RDF.type])
         rdf_types = set(rsrc_meta[nsc['fcres'][uid] : RDF.type])
 
 
         if LDP_NR_TYPE in rdf_types:
         if LDP_NR_TYPE in rdf_types:

+ 18 - 40
lakesuperior/model/ldpr.py

@@ -412,23 +412,21 @@ class Ldpr(metaclass=ABCMeta):
         return ev_type
         return ev_type
 
 
 
 
-    def bury_rsrc(self, inbound, tstone_pointer=None):
+    def bury(self, inbound, tstone_pointer=None):
         """
         """
         Delete a single resource and create a tombstone.
         Delete a single resource and create a tombstone.
 
 
         :param boolean inbound: Whether to delete the inbound relationships.
         :param boolean inbound: Whether to delete the inbound relationships.
-        :param rdflib.URIRef tstone_pointer: If set to a URN, this creates a
+        :param rdflib.URIRef tstone_pointer: If set to a URI, this creates a
             pointer to the tombstone of the resource that used to contain the
             pointer to the tombstone of the resource that used to contain the
             deleted resource. Otherwise the deleted resource becomes a
             deleted resource. Otherwise the deleted resource becomes a
             tombstone.
             tombstone.
         """
         """
         logger.info('Burying resource {}'.format(self.uid))
         logger.info('Burying resource {}'.format(self.uid))
-        # Create a backup snapshot for resurrection purposes.
-        self.create_version()
-
+        # ldp:Resource is also used in rdfly.ask_rsrc_exists.
         remove_trp = {
         remove_trp = {
-            trp for trp in self.imr
-            if trp[1] != nsc['fcrepo'].hasVersion}
+            (nsc['fcrepo'].uid, nsc['rdf'].type, nsc['ldp'].Resource)
+        }
 
 
         if tstone_pointer:
         if tstone_pointer:
             add_trp = {
             add_trp = {
@@ -436,7 +434,7 @@ class Ldpr(metaclass=ABCMeta):
         else:
         else:
             add_trp = {
             add_trp = {
                 (self.uri, RDF.type, nsc['fcsystem'].Tombstone),
                 (self.uri, RDF.type, nsc['fcsystem'].Tombstone),
-                (self.uri, nsc['fcrepo'].created, thread_env.timestamp_term),
+                (self.uri, nsc['fcsystem'].buried, thread_env.timestamp_term),
             }
             }
 
 
         ib_rsrc_uris = self.imr.subjects(None, self.uri)
         ib_rsrc_uris = self.imr.subjects(None, self.uri)
@@ -453,7 +451,7 @@ class Ldpr(metaclass=ABCMeta):
         return RES_DELETED
         return RES_DELETED
 
 
 
 
-    def forget_rsrc(self, inbound=True):
+    def forget(self, inbound=True):
         """
         """
         Remove all traces of a resource and versions.
         Remove all traces of a resource and versions.
         """
         """
@@ -466,42 +464,22 @@ class Ldpr(metaclass=ABCMeta):
         return RES_DELETED
         return RES_DELETED
 
 
 
 
-    def resurrect_rsrc(self):
+    def resurrect(self):
         """
         """
         Resurrect a resource from a tombstone.
         Resurrect a resource from a tombstone.
-
-        @EXPERIMENTAL
         """
         """
-        tstone_trp = set(rdfly.get_imr(self.uid, strict=False))
-
-        ver_rsp = self.version_info.query('''
-        SELECT ?uid {
-          ?latest fcrepo:hasVersionLabel ?uid ;
-            fcrepo:created ?ts .
+        remove_trp = {
+            (self.uri, nsc['rdf'].type, nsc['fcsystem'].Tombstone),
+            (self.uri, nsc['fcsystem'].tombstone, None),
+            (self.uri, nsc['fcsystem'].buried, None),
+        }
+        add_trp = {
+            (self.uri, nsc['rdf'].type, nsc['ldp'].Resource),
         }
         }
-        ORDER BY DESC(?ts)
-        LIMIT 1
-        ''')
-        ver_uid = str(ver_rsp.bindings[0]['uid'])
-        ver_trp = set(rdfly.get_metadata(self.uid, ver_uid))
-
-        laz_gr = Graph()
-        for t in ver_trp:
-            if t[1] != RDF.type or t[2] not in {
-                nsc['fcrepo'].Version,
-            }:
-                laz_gr.add((self.uri, t[1], t[2]))
-        laz_gr.add((self.uri, RDF.type, nsc['fcrepo'].Resource))
-        if nsc['ldp'].NonRdfSource in laz_gr[:RDF.type:]:
-            laz_gr.add((self.uri, RDF.type, nsc['fcrepo'].Binary))
-        elif nsc['ldp'].Container in laz_gr[:RDF.type:]:
-            laz_gr.add((self.uri, RDF.type, nsc['fcrepo'].Container))
-
-        laz_set = set(laz_gr) | self._containment_rel()
-        self.modify(RES_CREATED, tstone_trp, laz_set)
 
 
-        return self.uri
+        self.modify(RES_CREATED, remove_trp, add_trp)
 
 
+        return self.uri
 
 
 
 
     def create_version(self, ver_uid=None):
     def create_version(self, ver_uid=None):
@@ -707,7 +685,7 @@ class Ldpr(metaclass=ABCMeta):
         """
         """
         rdfly.modify_rsrc(self.uid, remove_trp, add_trp)
         rdfly.modify_rsrc(self.uid, remove_trp, add_trp)
         # Clear IMR buffer.
         # Clear IMR buffer.
-        if hasattr(self, 'imr'):
+        if hasattr(self, '_imr'):
             delattr(self, '_imr')
             delattr(self, '_imr')
             try:
             try:
                 self.imr
                 self.imr

+ 1 - 1
lakesuperior/store/ldp_rs/rsrc_centric_layout.py

@@ -328,7 +328,7 @@ class RsrcCentricLayout:
         return userdata_gr
         return userdata_gr
 
 
 
 
-    def get_version_info(self, uid, strict=True):
+    def get_version_info(self, uid):
         """
         """
         Get all metadata about a resource's versions.
         Get all metadata about a resource's versions.
 
 

+ 23 - 0
tests/api/test_resource_api.py

@@ -362,6 +362,29 @@ class TestResourceCRUD:
             nsc['fcres'][target_uid]]
             nsc['fcres'][target_uid]]
 
 
 
 
+    def test_soft_delete(self):
+        """
+        Soft-delete a resource.
+        """
+        uid = '/test_soft_delete01'
+        rsrc_api.create_or_replace(uid)
+        rsrc_api.delete(uid)
+        with pytest.raises(TombstoneError):
+            rsrc_api.get(uid)
+
+
+    def test_resurrect(self):
+        """
+        Resurrect a soft-deleted resource.
+        """
+        uid = '/test_soft_delete02'
+        rsrc_api.create_or_replace(uid)
+        rsrc_api.delete(uid)
+        rsrc_api.resurrect(uid)
+
+        rsrc = rsrc_api.get(uid)
+        assert nsc['ldp'].Resource in rsrc.ldp_types
+
 
 
 @pytest.mark.usefixtures('db')
 @pytest.mark.usefixtures('db')
 class TestResourceVersioning:
 class TestResourceVersioning: