[schema] fix pb with ambiguous relation used within UniqueTogetherConstraint by having CWUniqueTogetherConstraint.relation targeting CWRType instead of CWAttribute/CWRelation. This fixes 3.10.7 migration. stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 13 Jan 2011 12:36:08 +0100
branchstable
changeset 6815 a84190d4e78c
parent 6814 48402faff043
child 6816 f61de39cd396
[schema] fix pb with ambiguous relation used within UniqueTogetherConstraint by having CWUniqueTogetherConstraint.relation targeting CWRType instead of CWAttribute/CWRelation. This fixes 3.10.7 migration.
hooks/syncschema.py
misc/migration/3.10.7_Any.py
schemas/bootstrap.py
server/migractions.py
server/schemaserial.py
server/test/unittest_migractions.py
--- a/hooks/syncschema.py	Thu Jan 13 12:34:17 2011 +0100
+++ b/hooks/syncschema.py	Thu Jan 13 12:36:08 2011 +0100
@@ -705,14 +705,14 @@
             syssource.update_rdef_unique(session, rdef)
             self.unique_changed = True
 
+
 class CWUniqueTogetherConstraintAddOp(MemSchemaOperation):
     entity = None # make pylint happy
     def precommit_event(self):
         session = self.session
         prefix = SQL_PREFIX
         table = '%s%s' % (prefix, self.entity.constraint_of[0].name)
-        cols = ['%s%s' % (prefix, r.rtype.name)
-                for r in self.entity.relations]
+        cols = ['%s%s' % (prefix, r.name) for r in self.entity.relations]
         dbhelper= session.pool.source('system').dbhelper
         sqls = dbhelper.sqls_create_multicol_unique_index(table, cols)
         for sql in sqls:
@@ -722,9 +722,10 @@
 
     def postcommit_event(self):
         eschema = self.session.vreg.schema.schema_by_eid(self.entity.constraint_of[0].eid)
-        attrs = [r.rtype.name for r in self.entity.relations]
+        attrs = [r.name for r in self.entity.relations]
         eschema._unique_together.append(attrs)
 
+
 class CWUniqueTogetherConstraintDelOp(MemSchemaOperation):
     entity = oldcstr = None # for pylint
     cols = [] # for pylint
@@ -747,6 +748,7 @@
                            if set(ut) != cols]
         eschema._unique_together = unique_together
 
+
 # operations for in-memory schema synchronization  #############################
 
 class MemSchemaCWETypeDel(MemSchemaOperation):
@@ -1142,9 +1144,9 @@
         schema = self._cw.vreg.schema
         cstr = self._cw.entity_from_eid(self.eidfrom)
         entity = schema.schema_by_eid(self.eidto)
-        cols = [r.rtype.name
-                for r in cstr.relations]
-        CWUniqueTogetherConstraintDelOp(self._cw, entity=entity, oldcstr=cstr, cols=cols)
+        cols = [r.name for r in cstr.relations]
+        CWUniqueTogetherConstraintDelOp(self._cw, entity=entity,
+                                        oldcstr=cstr, cols=cols)
 
 
 # permissions synchronization hooks ############################################
--- a/misc/migration/3.10.7_Any.py	Thu Jan 13 12:34:17 2011 +0100
+++ b/misc/migration/3.10.7_Any.py	Thu Jan 13 12:36:08 2011 +0100
@@ -1,2 +1,8 @@
+add_relation_definition('CWUniqueTogetherConstraint', 'relations', 'CWRType')
+rql('SET C relations RT WHERE C relations RDEF, RDEF relation_type RT')
+commit()
+drop_relation_definition('CWUniqueTogetherConstraint', 'relations', 'CWAttribute')
+drop_relation_definition('CWUniqueTogetherConstraint', 'relations', 'CWRelation')
+
 add_attribute('TrInfo', 'tr_count')
 sync_schema_props_perms('TrInfo')
--- a/schemas/bootstrap.py	Thu Jan 13 12:34:17 2011 +0100
+++ b/schemas/bootstrap.py	Thu Jan 13 12:36:08 2011 +0100
@@ -159,10 +159,10 @@
     __permissions__ = PUB_SYSTEM_ENTITY_PERMS
     constraint_of = SubjectRelation('CWEType', cardinality='1*', composite='object',
                                     inlined=True)
-    relations = SubjectRelation(('CWAttribute', 'CWRelation'), cardinality='+*',
-                                 constraints=[RQLConstraint(
-           'O from_entity X, S constraint_of X, O relation_type T, '
-           'T final TRUE OR (T final FALSE AND T inlined TRUE)')])
+    relations = SubjectRelation('CWRType', cardinality='+*',
+                                constraints=[RQLConstraint(
+           'S constraint_of ET, RDEF relation_type O, RDEF from_entity ET, '
+           'O final TRUE OR (O final FALSE AND O inlined TRUE)')])
 
 
 class CWConstraintType(EntityType):
--- a/server/migractions.py	Thu Jan 13 12:34:17 2011 +0100
+++ b/server/migractions.py	Thu Jan 13 12:36:08 2011 +0100
@@ -536,38 +536,21 @@
             unique_together = set([frozenset(ut)
                                    for ut in eschema._unique_together])
             for ut in repo_unique_together - unique_together:
-                restrictions  = ', '.join(['C relations R%(i)d, '
-                                           'R%(i)d relation_type T%(i)d, '
-                                           'R%(i)d from_entity X, '
-                                           'T%(i)d name %%(T%(i)d)s' % {'i': i,
-                                                                        'col':col}
-                                           for (i, col) in enumerate(ut)])
-                substs = {'etype': etype}
+                restrictions = []
+                substs = {'x': repoeschema.eid}
                 for i, col in enumerate(ut):
+                    restrictions.append('C relations T%(i)d, '
+                                       'T%(i)d name %%(T%(i)d)s' % {'i': i})
                     substs['T%d'%i] = col
                 self.rqlexec('DELETE CWUniqueTogetherConstraint C '
                              'WHERE C constraint_of E, '
-                             '      E name %%(etype)s,'
-                             '      %s' % restrictions,
+                             '      E eid %%(x)s,'
+                             '      %s' % ', '.join( restrictions),
                              substs)
             for ut in unique_together - repo_unique_together:
-                relations = ', '.join(['C relations R%d' % i
-                                       for (i, col) in enumerate(ut)])
-                restrictions  = ', '.join(['R%(i)d relation_type T%(i)d, '
-                                           'R%(i)d from_entity E, '
-                                           'T%(i)d name %%(T%(i)d)s' % {'i': i,
-                                                                        'col':col}
-                                           for (i, col) in enumerate(ut)])
-                substs = {'etype': etype}
-                for i, col in enumerate(ut):
-                    substs['T%d'%i] = col
-                self.rqlexec('INSERT CWUniqueTogetherConstraint C:'
-                             '       C constraint_of E, '
-                             '       %s '
-                             'WHERE '
-                             '      E name %%(etype)s,'
-                             '      %s' % (relations, restrictions),
-                             substs)
+                rql, substs = ss.uniquetogether2rql(eschema, ut)
+                substs['x'] = repoeschema.eid
+                self.rqlexec(rql, substs)
 
     def _synchronize_rdef_schema(self, subjtype, rtype, objtype,
                                  syncperms=True, syncprops=True):
--- a/server/schemaserial.py	Thu Jan 13 12:34:17 2011 +0100
+++ b/server/schemaserial.py	Thu Jan 13 12:36:08 2011 +0100
@@ -235,7 +235,7 @@
             uniquecstreid, eeid, releid = values
             eschema = schema.schema_by_eid(eeid)
             relations = unique_togethers.setdefault(uniquecstreid, (eschema, []))
-            relations[1].append(ertidx[releid].rtype.type)
+            relations[1].append(ertidx[releid])
         for eschema, unique_together in unique_togethers.itervalues():
             eschema._unique_together.append(tuple(sorted(unique_together)))
     schema.infer_specialization_rules()
@@ -355,6 +355,7 @@
     for eschema in eschemas:
         for unique_together in eschema._unique_together:
             execschemarql(execute, eschema, [uniquetogether2rql(eschema, unique_together)])
+    # serialize yams inheritance relationships
     for rql, kwargs in specialize2rql(schema):
         execute(rql, kwargs, build_descr=False)
         if pb is not None:
@@ -417,23 +418,17 @@
     restrictions = []
     substs = {}
     for i, name in enumerate(unique_together):
-        rschema = eschema.rdef(name)
-        var = 'R%d' % i
+        rschema = eschema.schema.rschema(name)
         rtype = 'T%d' % i
-        substs[rtype] = rschema.rtype.type
-        relations.append('C relations %s' % var)
-        restrictions.append('%(var)s from_entity X, '
-                            '%(var)s relation_type %(rtype)s, '
-                            '%(rtype)s name %%(%(rtype)s)s' \
-                            % {'var': var,
-                               'rtype':rtype})
+        substs[rtype] = rschema.type
+        relations.append('C relations %s' % rtype)
+        restrictions.append('%(rtype)s name %%(%(rtype)s)s' % {'rtype': rtype})
     relations = ', '.join(relations)
     restrictions = ', '.join(restrictions)
     rql = ('INSERT CWUniqueTogetherConstraint C: '
            '    C constraint_of X, %s  '
            'WHERE '
-           '    X eid %%(x)s, %s' )
-
+           '    X eid %%(x)s, %s')
     return rql % (relations, restrictions), substs
 
 
--- a/server/test/unittest_migractions.py	Thu Jan 13 12:34:17 2011 +0100
+++ b/server/test/unittest_migractions.py	Thu Jan 13 12:36:08 2011 +0100
@@ -432,7 +432,7 @@
                                            ('nom', 'prenom', 'datenaiss'))
         rset = cursor.execute('Any C WHERE C is CWUniqueTogetherConstraint, C constraint_of ET, ET name "Personne"')
         self.assertEqual(len(rset), 1)
-        relations = [r.rtype.name for r in rset.get_entity(0, 0).relations]
+        relations = [r.name for r in rset.get_entity(0, 0).relations]
         self.assertItemsEqual(relations, ('nom', 'prenom', 'datenaiss'))
 
     def _erqlexpr_rset(self, action, ertype):