# HG changeset patch # User Sylvain Thénault # Date 1243503696 -7200 # Node ID e6eed4324357546a1bd88d2a8c7133d677866b58 # Parent cb9686969ef7adea76a73114a40bb8c0d6b64d65 fix #327301: synchronize_schema doesn't update not-null constraint diff -r cb9686969ef7 -r e6eed4324357 server/schemahooks.py --- a/server/schemahooks.py Wed May 27 18:51:52 2009 +0200 +++ b/server/schemahooks.py Thu May 28 11:41:36 2009 +0200 @@ -6,8 +6,9 @@ checking for schema consistency is done in hooks.py :organization: Logilab -:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr +:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" @@ -187,7 +188,7 @@ DeleteCWRTypeOp(session, name) -class DelErdefOp(SchemaOperation): +class DelRelationDefOp(SchemaOperation): """actually remove the relation definition from the application's schema""" def commit_event(self): subjtype, rtype, objtype = self.kobj @@ -236,7 +237,7 @@ # if this is the last instance, drop associated relation type if lastrel and not rteid in pendings: execute('DELETE CWRType X WHERE X eid %(x)s', {'x': rteid}, 'x') - DelErdefOp(session, (subjschema, rschema, objschema)) + DelRelationDefOp(session, (subjschema, rschema, objschema)) # addition #################################################################### @@ -561,7 +562,7 @@ self.session.repo.schema.rename_entity_type(self.oldname, self.newname) -class UpdateRdefOp(SchemaOperation): +class UpdateRelationDefOp(SchemaOperation): """actually update some properties of a relation definition""" rschema = values = None # make pylint happy @@ -575,6 +576,19 @@ sysource.create_index(self.session, table, column) else: sysource.drop_index(self.session, table, column) + if 'cardinality' in self.values and self.rschema.is_final(): + if self.session.pool.source('system').dbdriver == 'sqlite': + # not supported (and NOT NULL not set by yams in that case, so + # no worry) + return + sqlexec = self.session.system_sql + etype, rtype = self.kobj[0], self.rschema.type + if self.values['cardinality'][0] == '1': + cmd = 'SET' + else: + cmd = 'DROP' + sqlexec('ALTER TABLE %s ALTER COLUMN %s %s NOT NULL' % ( + table, SQL_PREFIX + etype, SQL_PREFIX + rtype)) def commit_event(self): # structure should be clean, not need to remove entity's relations @@ -595,8 +609,8 @@ newvalues[prop] = entity[prop] if newvalues: subjtype = entity.from_entity[0].name - UpdateRdefOp(session, (subjtype, desttype), rschema=rschema, - values=newvalues) + UpdateRelationDefOp(session, (subjtype, desttype), + rschema=rschema, values=newvalues) class UpdateRtypeOp(SchemaOperation): diff -r cb9686969ef7 -r e6eed4324357 server/test/unittest_hooks.py --- a/server/test/unittest_hooks.py Wed May 27 18:51:52 2009 +0200 +++ b/server/test/unittest_hooks.py Thu May 28 11:41:36 2009 +0200 @@ -2,6 +2,7 @@ """functional tests for core hooks note: most schemahooks.py hooks are actually tested in unittest_migrations.py +:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ from logilab.common.testlib import TestCase, unittest_main @@ -454,6 +455,23 @@ self.failIf(self.schema['Affaire'].has_unique_values('sujet')) self.failIf(self.index_exists('Affaire', 'sujet', unique=True)) + def test_required_change_1(self): + self.execute('SET DEF cardinality "?1" ' + 'WHERE DEF relation_type RT, DEF from_entity E,' + 'RT name "nom", E name "Personne"') + self.commit() + # should now be able to add personne without nom + self.execute('INSERT Personne X') + self.commit() + + def test_required_change_2(self): + self.execute('SET DEF cardinality "11" ' + 'WHERE DEF relation_type RT, DEF from_entity E,' + 'RT name "prenom", E name "Personne"') + self.commit() + # should not be able anymore to add personne without prenom + self.assertRaises(ValidationError, self.execute, 'INSERT Personne X: X nom "toto"') + class WorkflowHooksTC(RepositoryBasedTC):