[PATCH 2 of 2 skos] [hooks] Drop replaced ExternalUri in a data operation

Denis Laxalde denis.laxalde at logilab.fr
Mon Oct 29 18:09:52 CET 2018

# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1540831776 -3600
#      Mon Oct 29 17:49:36 2018 +0100
# Node ID 14d3b880a610ef7f381511b5e2f00e00c5c18a33
# Parent  b37b306c597c49196a9e27c4153fb8ea7cc548bd
# Available At http://hg.logilab.org/review/cubes/skos
#              hg pull http://hg.logilab.org/review/cubes/skos -r 14d3b880a610
[hooks] Drop replaced ExternalUri in a data operation

We change the way a replaced ExternalUri entity is dropped to operated
after new relations got inserted. As the latter step occurs in an
operation "CreateRelationsOp", we need the drop to also occur in an
operation. Hence we create a new DropExternalUriOp holded the deletion

The reason for this change is that when the ExternalUri entity to be
replaced is involved as a composite role in a relation, by dropping the
entity before inserting new relation (as was done before), we will
possibly drop many things as a side effect of relation drop whereas we
actually mean to replace a target of the relation. This occurs in
particular using the cubicweb-eac data model where some qualified
relations (implemented as entity types, e.g. AssociationRelation) are
composite. This is change in needed for cubicweb-saem_ref to continue to
work with cubicweb-eac version 0.8.0.

diff --git a/cubicweb_skos/hooks.py b/cubicweb_skos/hooks.py
--- a/cubicweb_skos/hooks.py
+++ b/cubicweb_skos/hooks.py
@@ -46,6 +46,15 @@ class CreateRelationsOp(hook.DataOperati
                             {'x': subject_eid, 'y': object_eid})
+class DropExternalUriOp(hook.DataOperationMixIn, hook.Operation):
+    """Data operation dropping ExternalUri entities during replacement."""
+    def precommit_event(self):
+        cnx = self.cnx
+        for eid in self.get_data():
+            cnx.execute('DELETE ExternalUri X WHERE X eid %(x)s', {'x': eid})
 class ReplaceExternalUriByEntityHook(hook.Hook):
     """Abstract hook to replace an ExternalUri with the same cwuri as the selected entity. To
     activate this behaviour, simply inherit from this hook and set a proper selector.
@@ -68,8 +77,11 @@ class ReplaceExternalUriByEntityHook(hoo
             # remember the external uri's relations and store them in an operation
             relations = dump_relations(cnx, exturi_eid, 'ExternalUri')
             CreateRelationsOp.get_instance(self._cw).add_data((self.entity.eid, relations))
-            # delete the external uri before insertion of the new entity
-            cnx.execute('DELETE ExternalUri X WHERE X eid %(x)s', {'x': exturi_eid})
+            # delete the external uri before insertion of the new entity, do
+            # this in an operation normally planned after CreateRelationsOp so
+            # that relations will be inserted before the ExternalUri is
+            # deleted.
+            DropExternalUriOp.get_instance(self._cw).add_data(exturi_eid)
 class ReplaceExternalUriByConceptHook(ReplaceExternalUriByEntityHook):

More information about the saem-devel mailing list