[migration] Test and fix case of addition of an attribute with some serialized constraint 3.23
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 08 Jul 2016 10:17:14 +0200
branch3.23
changeset 11717 d41832121b29
parent 11461 f5a4e14d1dd2
child 11718 e32e328e7d1f
[migration] Test and fix case of addition of an attribute with some serialized constraint It was crashing on attempt to remove an unexisting constraint. This code may be removed safely as it's expected to be handled by the constraint removal hook. Notice that adding a vocabulary on shortpara makes yams change the varchar max size. This is arguable but not the point of this test, so simply adapt the max size defined in the schema coherently so we don't have to bother with that at this point. Grafted from f87da59faea1 in default branch.
cubicweb/hooks/syncschema.py
cubicweb/server/test/data-migractions/migratedapp/schema.py
cubicweb/server/test/unittest_migractions.py
--- a/cubicweb/hooks/syncschema.py	Thu Sep 08 11:40:50 2016 +0200
+++ b/cubicweb/hooks/syncschema.py	Fri Jul 08 10:17:14 2016 +0200
@@ -809,14 +809,19 @@
         elif cstrtype == 'UniqueConstraint' and oldcstr is None:
             syssource.update_rdef_unique(cnx, rdef)
             self.unique_changed = True
-        if cstrtype in ('BoundaryConstraint', 'IntervalBoundConstraint', 'StaticVocabularyConstraint'):
+        if cstrtype in ('BoundaryConstraint',
+                        'IntervalBoundConstraint',
+                        'StaticVocabularyConstraint'):
+            cstrname, check = y2sql.check_constraint(rdef.subject, rdef.object, rdef.rtype.type,
+                                                     newcstr, syssource.dbhelper, prefix=SQL_PREFIX)
+            # oldcstr is the new constraint when the attribute is being added in the same
+            # transaction or when constraint value is updated. So we've to take care...
             if oldcstr is not None:
                 oldcstrname = 'cstr' + md5((rdef.subject.type + rdef.rtype.type + cstrtype +
-                                            (self.oldcstr.serialize() or '')).encode('ascii')).hexdigest()
-                cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s' %
-                               (SQL_PREFIX, rdef.subject.type, oldcstrname))
-            cstrname, check = y2sql.check_constraint(rdef.subject, rdef.object, rdef.rtype.type,
-                    newcstr, syssource.dbhelper, prefix=SQL_PREFIX)
+                                            (self.oldcstr.serialize() or '')).encode('utf-8')).hexdigest()
+                if oldcstrname != cstrname:
+                    cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s'
+                                   % (SQL_PREFIX, rdef.subject.type, oldcstrname))
             cnx.system_sql('ALTER TABLE %s%s ADD CONSTRAINT %s CHECK(%s)' %
                            (SQL_PREFIX, rdef.subject.type, cstrname, check))
 
--- a/cubicweb/server/test/data-migractions/migratedapp/schema.py	Thu Sep 08 11:40:50 2016 +0200
+++ b/cubicweb/server/test/data-migractions/migratedapp/schema.py	Fri Jul 08 10:17:14 2016 +0200
@@ -87,7 +87,7 @@
     mydate = Date(default='TODAY')
     oldstyledefaultdate = Date(default='2013/01/01')
     newstyledefaultdate = Date(default=dt.date(2013, 1, 1))
-    shortpara = String(maxsize=64, default='hop')
+    shortpara = String(maxsize=11, default='hop', vocabulary=['hop', 'hop hop', 'hop hop hop'])
     ecrit_par = SubjectRelation('Personne', constraints=[RQLConstraint('S concerne A, O concerne A')])
     attachment = SubjectRelation('File')
 
--- a/cubicweb/server/test/unittest_migractions.py	Thu Sep 08 11:40:50 2016 +0200
+++ b/cubicweb/server/test/unittest_migractions.py	Fri Jul 08 10:17:14 2016 +0200
@@ -183,11 +183,14 @@
             self.assertEqual(self.schema['shortpara'].objects(), ('String', ))
             # test created column is actually a varchar(64)
             fields = self.table_schema(mh, '%sNote' % SQL_PREFIX)
-            self.assertEqual(fields['%sshortpara' % SQL_PREFIX], ('character varying', 64))
+            self.assertEqual(fields['%sshortpara' % SQL_PREFIX], ('character varying', 11))
             # test default value set on existing entities
             self.assertEqual(cnx.execute('Note X').get_entity(0, 0).shortpara, 'hop')
             # test default value set for next entities
-            self.assertEqual(cnx.create_entity('Note', shortpara=u'hophop').shortpara, u'hophop')
+            self.assertEqual(cnx.create_entity('Note', shortpara=u'hop hop').shortpara, u'hop hop')
+            # serialized constraint added
+            constraints = self.table_constraints(mh, 'cw_Personne')
+            self.assertEqual(len(constraints), 1, constraints)
 
     def test_add_attribute_unique(self):
         with self.mh() as (cnx, mh):