[integrity] keep ordering for schema integrity checks
set_operation gained a new containercls argument, so one can choose
to use list or set (by default). Use this when registering schema
integrity check operation.
--- a/entities/test/unittest_wfobjs.py Tue May 18 14:26:19 2010 +0200
+++ b/entities/test/unittest_wfobjs.py Tue May 18 14:28:44 2010 +0200
@@ -56,7 +56,7 @@
self.commit()
wf.add_state(u'foo')
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'state_of-subject': 'workflow already have a state of that name'})
+ self.assertEquals(ex.errors, {'name-subject': 'workflow already have a state of that name'})
# no pb if not in the same workflow
wf2 = add_wf(self, 'Company')
foo = wf2.add_state(u'foo', initial=True)
--- a/hooks/integrity.py Tue May 18 14:26:19 2010 +0200
+++ b/hooks/integrity.py Tue May 18 14:28:44 2010 +0200
@@ -136,10 +136,10 @@
if rdef.role_cardinality(role) in '1+':
if role == 'subject':
set_operation(self._cw, '_cwisrel', (eid, rschema.type),
- _CheckSRelationOp)
+ _CheckSRelationOp, list)
else:
set_operation(self._cw, '_cwiorel', (eid, rschema.type),
- _CheckORelationOp)
+ _CheckORelationOp, list)
def before_delete_relation(self):
rtype = self.rtype
@@ -153,10 +153,10 @@
card = session.schema_rproperty(rtype, eidfrom, eidto, 'cardinality')
if card[0] in '1+' and not session.deleted_in_transaction(eidfrom):
set_operation(self._cw, '_cwisrel', (eidfrom, rtype),
- _CheckSRelationOp)
+ _CheckSRelationOp, list)
if card[1] in '1+' and not session.deleted_in_transaction(eidto):
set_operation(self._cw, '_cwiorel', (eidto, rtype),
- _CheckORelationOp)
+ _CheckORelationOp, list)
class _CheckConstraintsOp(hook.LateOperation):
@@ -205,7 +205,7 @@
if constraints:
hook.set_operation(self._cw, 'check_constraints_op',
(self.eidfrom, self.rtype, self.eidto, tuple(constraints)),
- _CheckConstraintsOp)
+ _CheckConstraintsOp, list)
class CheckAttributeConstraintHook(IntegrityHook):
@@ -226,7 +226,7 @@
if constraints:
hook.set_operation(self._cw, 'check_constraints_op',
(self.entity.eid, attr, None, tuple(constraints)),
- _CheckConstraintsOp)
+ _CheckConstraintsOp, list)
class CheckUniqueHook(IntegrityHook):
--- a/server/hook.py Tue May 18 14:26:19 2010 +0200
+++ b/server/hook.py Tue May 18 14:28:44 2010 +0200
@@ -473,23 +473,27 @@
set_log_methods(Operation, getLogger('cubicweb.session'))
+def _container_add(container, value):
+ {set: set.add, list: list.append}[container.__class__](container, value)
-def set_operation(session, datakey, value, opcls, **opkwargs):
+def set_operation(session, datakey, value, opcls, containercls=set, **opkwargs):
"""Search for session.transaction_data[`datakey`] (expected to be a set):
* if found, simply append `value`
- * else, initialize it to set([`value`]) and instantiate the given `opcls`
- operation class with additional keyword arguments.
+ * else, initialize it to containercls([`value`]) and instantiate the given
+ `opcls` operation class with additional keyword arguments. `containercls`
+ is a set by default. Give `list` if you want to keep arrival ordering.
You should use this instead of creating on operation for each `value`,
since handling operations becomes coslty on massive data import.
"""
try:
- session.transaction_data[datakey].add(value)
+ _container_add(session.transaction_data[datakey], value)
except KeyError:
opcls(session, **opkwargs)
- session.transaction_data[datakey] = set((value,))
+ session.transaction_data[datakey] = containercls()
+ _container_add(session.transaction_data[datakey], value)
class LateOperation(Operation):