Fix constraint sync during migration
authorJulien Cristau <julien.cristau@logilab.fr>
Mon, 07 Apr 2014 18:04:56 +0200
changeset 9636 e35ae8617c03
parent 9635 aaf099172bb9
child 9637 c6132d36e55d
Fix constraint sync during migration - restore constraints lost during merge in test schema. - use constraint_by_eid in BeforeDeleteCWConstraintHook as done in 3.17.14 for BeforeDeleteConstrainedByHook. Fixes handling of multiple constraints of the same type. - make sync_schema_props_perms() delete the CWConstraint entity instead of the constrained_by relation. In 3.19, the latter doesn't automatically result in the former just because the relation is composite. Simplify the constraint migration to delete all removed constraints and recreate new ones even if they share the same type; that optimization made the code more complicated for (AFAICT) no significant reason.
hooks/syncschema.py
server/migractions.py
server/test/data/migratedapp/schema.py
--- a/hooks/syncschema.py	Mon Apr 07 17:02:04 2014 +0200
+++ b/hooks/syncschema.py	Mon Apr 07 18:04:56 2014 +0200
@@ -633,7 +633,7 @@
 def _set_modifiable_constraints(rdef):
     # for proper in-place modification of in-memory schema: if rdef.constraints
     # is already a list, reuse it (we're updating multiple constraints of the
-    # same rdef in the same transactions)
+    # same rdef in the same transaction)
     if not isinstance(rdef.constraints, list):
         rdef.constraints = list(rdef.constraints)
 
@@ -1137,7 +1137,7 @@
             # KeyError, e.g. composite chain deletion
             rdef = schema.schema_by_eid(entity.reverse_constrained_by[0].eid)
             # IndexError
-            cstr = rdef.constraint_by_type(entity.type)
+            cstr = rdef.constraint_by_eid(entity.eid)
         except (KeyError, IndexError):
             self._cw.critical('constraint type no more accessible')
         else:
--- a/server/migractions.py	Mon Apr 07 17:02:04 2014 +0200
+++ b/server/migractions.py	Mon Apr 07 18:04:56 2014 +0200
@@ -607,21 +607,8 @@
             #       out of sync with newconstraints when multiple
             #       constraints of the same type are used
             for cstr in oldconstraints:
-                for newcstr in newconstraints:
-                    if newcstr.type() == cstr.type():
-                        break
-                else:
-                    newcstr = None
-                if newcstr is None:
-                    self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s',
-                                 {'x': cstr.eid}, ask_confirm=confirm)
-                else:
-                    newconstraints.remove(newcstr)
-                    value = unicode(newcstr.serialize())
-                    if value != unicode(cstr.serialize()):
-                        self.rqlexec('SET X value %(v)s WHERE X eid %(x)s',
-                                     {'x': cstr.eid, 'v': value},
-                                     ask_confirm=confirm)
+                self.rqlexec('DELETE CWConstraint C WHERE C eid %(x)s',
+                             {'x': cstr.eid}, ask_confirm=confirm)
             # 2. add new constraints
             cstrtype_map = self.cstrtype_mapping()
             self.rqlexecall(ss.constraints2rql(cstrtype_map, newconstraints,
--- a/server/test/data/migratedapp/schema.py	Mon Apr 07 17:02:04 2014 +0200
+++ b/server/test/data/migratedapp/schema.py	Mon Apr 07 18:04:56 2014 +0200
@@ -127,6 +127,7 @@
 class evaluee(RelationDefinition):
     subject = ('Personne', 'CWUser', 'Societe')
     object = ('Note')
+    constraints = [RQLVocabularyConstraint('S owned_by U')]
 
 class ecrit_par(RelationType):
     __permissions__ = {'read':   ('managers', 'users', 'guests',),