backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 17 Mar 2010 09:23:27 +0100
changeset 4930 9fcc9ae2aebe
parent 4929 84684417beb9 (current diff)
parent 4928 cbca73dc9753 (diff)
child 4933 433174d9394f
backport stable
hooks/syncschema.py
hooks/test/unittest_syncschema.py
sobjects/notification.py
--- a/hooks/syncschema.py	Wed Mar 17 09:23:17 2010 +0100
+++ b/hooks/syncschema.py	Wed Mar 17 09:23:27 2010 +0100
@@ -188,11 +188,12 @@
         # every schema operation is triggering a schema update
         MemSchemaNotifyChanges(session)
 
-    def prepare_constraints(self, subjtype, rtype, objtype):
-        rdef = rtype.rdef(subjtype, objtype)
-        constraints = rdef.constraints
-        self.constraints = list(constraints)
-        rdef.constraints = self.constraints
+    def prepare_constraints(self, rdef):
+        # if constraints is already a list, reuse it (we're updating multiple
+        # constraints of the same rdef in the same transactions
+        if not isinstance(rdef.constraints, list):
+            rdef.constraints = list(rdef.constraints)
+        self.constraints = rdef.constraints
 
 
 class MemSchemaEarlyOperation(MemSchemaOperation):
@@ -549,7 +550,7 @@
 
 class SourceDbCWConstraintDel(hook.Operation):
     """actually remove a constraint of a relation definition"""
-    rtype = subjtype = objtype = None # make pylint happy
+    rtype = subjtype = None # make pylint happy
 
     def precommit_event(self):
         cstrtype = self.cstr.type()
@@ -671,8 +672,8 @@
             self.cancelled = True
             return
         rdef = self.session.vreg.schema.schema_by_eid(rdef.eid)
+        self.prepare_constraints(rdef)
         subjtype, rtype, objtype = rdef.as_triple()
-        self.prepare_constraints(subjtype, rtype, objtype)
         cstrtype = self.entity.type
         self.cstr = rtype.rdef(subjtype, objtype).constraint_by_type(cstrtype)
         self.newcstr = CONSTRAINTS[cstrtype].deserialize(self.entity.value)
@@ -694,7 +695,7 @@
     """
     rtype = subjtype = objtype = None # make pylint happy
     def precommit_event(self):
-        self.prepare_constraints(self.subjtype, self.rtype, self.objtype)
+        self.prepare_constraints(self.rdef)
 
     def commit_event(self):
         self.constraints.remove(self.cstr)
@@ -1094,11 +1095,9 @@
         except IndexError:
             self._cw.critical('constraint type no more accessible')
         else:
-            subjtype, rtype, objtype = rdef.as_triple()
-            SourceDbCWConstraintDel(self._cw, subjtype=subjtype, rtype=rtype,
-                                    objtype=objtype, cstr=cstr)
-            MemSchemaCWConstraintDel(self._cw, subjtype=subjtype, rtype=rtype,
-                                     objtype=objtype, cstr=cstr)
+            SourceDbCWConstraintDel(self._cw, cstr=cstr,
+                                    subjtype=rdef.subject, rtype=rdef.rtype)
+            MemSchemaCWConstraintDel(self._cw, rdef=rdef, cstr=cstr)
 
 
 # permissions synchronization hooks ############################################
--- a/hooks/test/unittest_syncschema.py	Wed Mar 17 09:23:17 2010 +0100
+++ b/hooks/test/unittest_syncschema.py	Wed Mar 17 09:23:27 2010 +0100
@@ -293,3 +293,17 @@
         rset = req.execute('Any X WHERE X has_text "rick.roll"')
         self.assertIn(req.user.eid, [item[0] for item in rset])
 
+    def test_update_constraint(self):
+        rdef = self.schema['Transition'].rdef('type')
+        cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
+        if not getattr(cstr, 'eid', None):
+            self.skip('start me alone') # bug in schema reloading, constraint's eid not restored
+        self.execute('SET X value %(v)s WHERE X eid %(x)s',
+                     {'x': cstr.eid, 'v': u"u'normal', u'auto', u'new'"}, 'x')
+        self.execute('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X '
+                     'WHERE CT name %(ct)s, EDEF eid %(x)s',
+                     {'ct': 'SizeConstraint', 'value': u'max=10', 'x': rdef.eid}, 'x')
+        self.commit()
+        cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
+        self.assertEquals(cstr.values, (u'normal', u'auto', u'new'))
+        self.execute('INSERT Transition T: T name "hop", T type "new"')
--- a/sobjects/notification.py	Wed Mar 17 09:23:17 2010 +0100
+++ b/sobjects/notification.py	Wed Mar 17 09:23:27 2010 +0100
@@ -130,7 +130,7 @@
       override call)
     """
     __abstract__ = True
-    id = 'notif_entity_updated'
+    __regid__ = 'notif_entity_updated'
     msgid_timestamp = False
     message = _('updated')
     no_detailed_change_attrs = ()