# HG changeset patch # User Sylvain Thénault # Date 1268814073 -3600 # Node ID 19fd1952ad63949e9a6d521ab2cec050a4c99c1e # Parent 626d31035662edbafe95fe284df3abd009532967 [schema sync] test and fix bug when updating multiple constraint for the same rdef in the same transaction diff -r 626d31035662 -r 19fd1952ad63 hooks/syncschema.py --- a/hooks/syncschema.py Wed Mar 17 09:19:02 2010 +0100 +++ b/hooks/syncschema.py Wed Mar 17 09:21:13 2010 +0100 @@ -187,11 +187,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): @@ -665,8 +666,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) @@ -688,7 +689,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) @@ -1085,11 +1086,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 ############################################ diff -r 626d31035662 -r 19fd1952ad63 hooks/test/unittest_syncschema.py --- a/hooks/test/unittest_syncschema.py Wed Mar 17 09:19:02 2010 +0100 +++ b/hooks/test/unittest_syncschema.py Wed Mar 17 09:21:13 2010 +0100 @@ -308,3 +308,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"')