# HG changeset patch # User Sylvain Thénault # Date 1283895256 -7200 # Node ID 564a6028067c2bbd66f950ad86afb7bf1c91f30e # Parent 9fa02f352c8c90cab5764e3b5b55aacaa709ec8c [migration] more rename_entity_type fix * ensure repository caches and system tables are properly cleanup * delete relations from/to entities deleted through sql So we don't ends up with a corrupted db... diff -r 9fa02f352c8c -r 564a6028067c server/migractions.py --- a/server/migractions.py Tue Sep 07 23:24:45 2010 +0200 +++ b/server/migractions.py Tue Sep 07 23:34:16 2010 +0200 @@ -56,6 +56,7 @@ from cubicweb.dbapi import get_repository, repo_connect from cubicweb.migration import MigrationHelper, yes from cubicweb.server.session import hooks_control +from cubicweb.server import hook try: from cubicweb.server import SOURCE_TYPES, schemaserial as ss from cubicweb.server.utils import manager_userpasswd, ask_source_config @@ -880,21 +881,49 @@ self.sqlexec('UPDATE %s_relation SET eid_to=%s WHERE eid_to=%s' % (rtype, new.eid, oldeid), ask_confirm=False) # delete relations using SQL to avoid relations content removal - # triggered by schema synchronization hooks. Should add deleted eids - # into pending eids else we may get some validation error on commit - # since integrity hooks may think some required relation is - # missing... - pending = self.session.transaction_data.setdefault('pendingeids', set()) + # triggered by schema synchronization hooks. + session = self.session for rdeftype in ('CWRelation', 'CWAttribute'): + thispending = set() for eid, in self.sqlexec('SELECT cw_eid FROM cw_%s ' 'WHERE cw_from_entity=%%(eid)s OR ' ' cw_to_entity=%%(eid)s' % rdeftype, {'eid': oldeid}, ask_confirm=False): - pending.add(eid) + # we should add deleted eids into pending eids else we may + # get some validation error on commit since integrity hooks + # may think some required relation is missing... This also ensure + # repository caches are properly cleanup + hook.set_operation(session, 'pendingeids', eid, + hook.CleanupDeletedEidsCacheOp) + # and don't forget to remove record from system tables + self.repo.system_source.delete_info( + session, session.entity_from_eid(eid, rdeftype), + 'system', None) + thispending.add(eid) self.sqlexec('DELETE FROM cw_%s ' 'WHERE cw_from_entity=%%(eid)s OR ' 'cw_to_entity=%%(eid)s' % rdeftype, {'eid': oldeid}, ask_confirm=False) + # now we have to manually cleanup relations pointing to deleted + # entities + thiseids = ','.join(str(eid) for eid in thispending) + for rschema, ttypes, role in schema[rdeftype].relation_definitions(): + if rschema.type in VIRTUAL_RTYPES: + continue + sqls = [] + if role == 'object': + if rschema.inlined: + for eschema in ttypes: + sqls.append('DELETE FROM cw_%s WHERE cw_%s IN(%%s)' + % (eschema, rschema)) + else: + sqls.append('DELETE FROM %s_relation WHERE eid_to IN(%%s)' + % rschema) + elif not rschema.inlined: + sqls.append('DELETE FROM %s_relation WHERE eid_from IN(%%s)' + % rschema) + for sql in sqls: + self.sqlexec(sql % thiseids, ask_confirm=False) # remove the old type: use rql to propagate deletion self.rqlexec('DELETE CWEType ET WHERE ET name %(on)s', {'on': oldname}, ask_confirm=False)