[migration] fix add_relation_type() for symmetric relations
To check if the corresponding SQL table has to created, CWRelationAddOp
tests that the tablename is not in the 'createdtables' session variable
(i.e. the table hasn't been created before in the same transaction) and
that len(rschema.rdefs) is not greater to 1, that is the relation already
existed in the database before this transaction.
In case of symmetric relations, len(rschema).rdefs will be at least 2
since rdefs will store both (subj, obj) and (obj, subj) relation
definitions.
--- a/hooks/syncschema.py Thu Aug 26 11:35:02 2010 +0200
+++ b/hooks/syncschema.py Fri Aug 27 08:56:58 2010 +0200
@@ -521,10 +521,16 @@
insert_rdef_on_subclasses(session, eschema, rschema, rdefdef,
{'composite': entity.composite})
else:
+ if rschema.symmetric:
+ # for symmetric relations, rdefs will store relation definitions
+ # in both ways (i.e. (subj -> obj) and (obj -> subj))
+ relation_already_defined = len(rschema.rdefs) > 2
+ else:
+ relation_already_defined = len(rschema.rdefs) > 1
# need to create the relation if no relation definition in the
# schema and if it has not been added during other event of the same
# transaction
- if not (len(rschema.rdefs) > 1 or
+ if not (relation_already_defined or
rtype in session.transaction_data.get('createdtables', ())):
rschema = schema.rschema(rtype)
# create the necessary table
--- a/server/test/data/migratedapp/schema.py Thu Aug 26 11:35:02 2010 +0200
+++ b/server/test/data/migratedapp/schema.py Fri Aug 27 08:56:58 2010 +0200
@@ -138,6 +138,9 @@
cp = String(maxsize=12)
ville= String(maxsize=32)
+class same_as(RelationDefinition):
+ subject = ('Societe',)
+ object = 'ExternalUri'
class evaluee(RelationDefinition):
subject = ('Personne', 'CWUser', 'Societe')
--- a/server/test/unittest_migractions.py Thu Aug 26 11:35:02 2010 +0200
+++ b/server/test/unittest_migractions.py Fri Aug 27 08:56:58 2010 +0200
@@ -545,5 +545,15 @@
self.assertEquals(self.schema['Note'].specializes(), None)
self.assertEquals(self.schema['Text'].specializes(), None)
+
+ def test_add_symmetric_relation_type(self):
+ same_as_sql = self.mh.sqlexec("SELECT sql FROM sqlite_master WHERE type='table' "
+ "and name='same_as_relation'")
+ self.failIf(same_as_sql)
+ self.mh.cmd_add_relation_type('same_as')
+ same_as_sql = self.mh.sqlexec("SELECT sql FROM sqlite_master WHERE type='table' "
+ "and name='same_as_relation'")
+ self.failUnless(same_as_sql)
+
if __name__ == '__main__':
unittest_main()