[schema] stop using RQLUniqueConstraint (closes #3753250)
authorAurelien Campeas <aurelien.campeas@logilab.fr>
Thu, 17 Apr 2014 12:34:51 +0200
changeset 10092 f0363da0b5a0
parent 10091 09878c2f8621
child 10093 516a44ae2cc9
[schema] stop using RQLUniqueConstraint (closes #3753250) The last uses are replaced with unique together constraints.
entities/test/unittest_wfobjs.py
misc/migration/3.20.0_Any.py
schemas/workflow.py
--- a/entities/test/unittest_wfobjs.py	Thu Apr 03 14:17:16 2014 +0200
+++ b/entities/test/unittest_wfobjs.py	Thu Apr 17 12:34:51 2014 +0200
@@ -50,11 +50,13 @@
             wf = add_wf(shell, 'Company')
             wf.add_state(u'foo', initial=True)
             shell.commit()
-            wf.add_state(u'foo')
             with self.assertRaises(ValidationError) as cm:
-                shell.commit()
-            self.assertEqual({'name-subject': 'workflow already has a state of that name'},
+                wf.add_state(u'foo')
+            self.assertEqual({'name': u'name is part of violated unicity constraint',
+                              'state_of': u'state_of is part of violated unicity constraint',
+                              'unicity constraint': u'some relations violate a unicity constraint'},
                              cm.exception.errors)
+            shell.rollback()
             # no pb if not in the same workflow
             wf2 = add_wf(shell, 'Company')
             foo = wf2.add_state(u'foo', initial=True)
@@ -62,10 +64,12 @@
             # gnark gnark
             bar = wf.add_state(u'bar')
             shell.commit()
-            bar.cw_set(name=u'foo')
             with self.assertRaises(ValidationError) as cm:
-                shell.commit()
-            self.assertEqual({'name-subject': 'workflow already has a state of that name'},
+                bar.cw_set(name=u'foo')
+            shell.rollback()
+            self.assertEqual({'name': u'name is part of violated unicity constraint',
+                              'state_of': u'state_of is part of violated unicity constraint',
+                              'unicity constraint': u'some relations violate a unicity constraint'},
                              cm.exception.errors)
 
     def test_duplicated_transition(self):
@@ -74,10 +78,13 @@
             foo = wf.add_state(u'foo', initial=True)
             bar = wf.add_state(u'bar')
             wf.add_transition(u'baz', (foo,), bar, ('managers',))
-            wf.add_transition(u'baz', (bar,), foo)
             with self.assertRaises(ValidationError) as cm:
-                shell.commit()
-            self.assertEqual(cm.exception.errors, {'name-subject': 'workflow already has a transition of that name'})
+                wf.add_transition(u'baz', (bar,), foo)
+            self.assertEqual({'name': u'name is part of violated unicity constraint',
+                              'transition_of': u'transition_of is part of violated unicity constraint',
+                              'unicity constraint': u'some relations violate a unicity constraint'},
+                             cm.exception.errors)
+            shell.rollback()
             # no pb if not in the same workflow
             wf2 = add_wf(shell, 'Company')
             foo = wf.add_state(u'foo', initial=True)
@@ -87,10 +94,13 @@
             # gnark gnark
             biz = wf.add_transition(u'biz', (bar,), foo)
             shell.commit()
-            biz.cw_set(name=u'baz')
             with self.assertRaises(ValidationError) as cm:
-                shell.commit()
-            self.assertEqual(cm.exception.errors, {'name-subject': 'workflow already has a transition of that name'})
+                biz.cw_set(name=u'baz')
+            shell.rollback()
+            self.assertEqual({'name': u'name is part of violated unicity constraint',
+                              'transition_of': u'transition_of is part of violated unicity constraint',
+                              'unicity constraint': u'some relations violate a unicity constraint'},
+                             cm.exception.errors)
 
 
 class WorkflowTC(CubicWebTC):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.20.0_Any.py	Thu Apr 17 12:34:51 2014 +0200
@@ -0,0 +1,6 @@
+sync_schema_props_perms('State')
+sync_schema_props_perms('state_of')
+sync_schema_props_perms('BaseTransition')
+sync_schema_props_perms('Transition')
+sync_schema_props_perms('WorkflowTransition')
+sync_schema_props_perms('transition_of')
--- a/schemas/workflow.py	Thu Apr 03 14:17:16 2014 +0200
+++ b/schemas/workflow.py	Thu Apr 17 12:34:51 2014 +0200
@@ -24,7 +24,7 @@
 from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
                             SubjectRelation,
                             RichString, String, Int)
-from cubicweb.schema import RQLConstraint, RQLUniqueConstraint
+from cubicweb.schema import RQLConstraint
 from cubicweb.schemas import (PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS,
                               RO_REL_PERMS)
 
@@ -62,11 +62,8 @@
     workflows
     """
     __permissions__ = PUB_SYSTEM_ENTITY_PERMS
-
-    name = String(required=True, indexed=True, internationalizable=True,
-                  maxsize=256,
-                  constraints=[RQLUniqueConstraint('S name N, S state_of WF, Y state_of WF, Y name N', 'Y',
-                                                   _('workflow already has a state of that name'))])
+    __unique_together__ = [('name', 'state_of')]
+    name = String(required=True, indexed=True, internationalizable=True, maxsize=256)
     description = RichString(default_format='text/rest',
                              description=_('semantic description of this state'))
 
@@ -76,27 +73,21 @@
                                          constraints=[RQLConstraint('S state_of WF, O transition_of WF',
                                                                     msg=_('state and transition don\'t belong the the same workflow'))],
                                          description=_('allowed transitions from this state'))
-    state_of = SubjectRelation('Workflow', cardinality='1*', composite='object',
-                               description=_('workflow to which this state belongs'),
-                               constraints=[RQLUniqueConstraint('S name N, Y state_of O, Y name N', 'Y',
-                                                                _('workflow already has a state of that name'))])
+    state_of = SubjectRelation('Workflow', cardinality='1*', composite='object', inlined=True,
+                               description=_('workflow to which this state belongs'))
 
 
 class BaseTransition(EntityType):
     """abstract base class for transitions"""
     __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    __unique_together__ = [('name', 'transition_of')]
 
-    name = String(required=True, indexed=True, internationalizable=True,
-                  maxsize=256,
-                  constraints=[RQLUniqueConstraint('S name N, S transition_of WF, Y transition_of WF, Y name N', 'Y',
-                                                   _('workflow already has a transition of that name'))])
+    name = String(required=True, indexed=True, internationalizable=True, maxsize=256)
     type = String(vocabulary=(_('normal'), _('auto')), default='normal')
     description = RichString(description=_('semantic description of this transition'))
 
-    transition_of = SubjectRelation('Workflow', cardinality='1*', composite='object',
-                                    description=_('workflow to which this transition belongs'),
-                                    constraints=[RQLUniqueConstraint('S name N, Y transition_of O, Y name N', 'Y',
-                                                                     _('workflow already has a transition of that name'))])
+    transition_of = SubjectRelation('Workflow', cardinality='1*', composite='object', inlined=True,
+                                    description=_('workflow to which this transition belongs'))
 
 
 class require_group(RelationDefinition):