server/migractions.py
branchstable
changeset 6190 564a6028067c
parent 6189 9fa02f352c8c
child 6200 6e8c847ae397
equal deleted inserted replaced
6189:9fa02f352c8c 6190:564a6028067c
    54                              PURE_VIRTUAL_RTYPES,
    54                              PURE_VIRTUAL_RTYPES,
    55                              CubicWebRelationSchema, order_eschemas)
    55                              CubicWebRelationSchema, order_eschemas)
    56 from cubicweb.dbapi import get_repository, repo_connect
    56 from cubicweb.dbapi import get_repository, repo_connect
    57 from cubicweb.migration import MigrationHelper, yes
    57 from cubicweb.migration import MigrationHelper, yes
    58 from cubicweb.server.session import hooks_control
    58 from cubicweb.server.session import hooks_control
       
    59 from cubicweb.server import hook
    59 try:
    60 try:
    60     from cubicweb.server import SOURCE_TYPES, schemaserial as ss
    61     from cubicweb.server import SOURCE_TYPES, schemaserial as ss
    61     from cubicweb.server.utils import manager_userpasswd, ask_source_config
    62     from cubicweb.server.utils import manager_userpasswd, ask_source_config
    62     from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
    63     from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
    63 except ImportError: # LAX
    64 except ImportError: # LAX
   878             # backport is / is_instance_of relation to new type
   879             # backport is / is_instance_of relation to new type
   879             for rtype in ('is', 'is_instance_of'):
   880             for rtype in ('is', 'is_instance_of'):
   880                 self.sqlexec('UPDATE %s_relation SET eid_to=%s WHERE eid_to=%s'
   881                 self.sqlexec('UPDATE %s_relation SET eid_to=%s WHERE eid_to=%s'
   881                              % (rtype, new.eid, oldeid), ask_confirm=False)
   882                              % (rtype, new.eid, oldeid), ask_confirm=False)
   882             # delete relations using SQL to avoid relations content removal
   883             # delete relations using SQL to avoid relations content removal
   883             # triggered by schema synchronization hooks. Should add deleted eids
   884             # triggered by schema synchronization hooks.
   884             # into pending eids else we may get some validation error on commit
   885             session = self.session
   885             # since integrity hooks may think some required relation is
       
   886             # missing...
       
   887             pending = self.session.transaction_data.setdefault('pendingeids', set())
       
   888             for rdeftype in ('CWRelation', 'CWAttribute'):
   886             for rdeftype in ('CWRelation', 'CWAttribute'):
       
   887                 thispending = set()
   889                 for eid, in self.sqlexec('SELECT cw_eid FROM cw_%s '
   888                 for eid, in self.sqlexec('SELECT cw_eid FROM cw_%s '
   890                                          'WHERE cw_from_entity=%%(eid)s OR '
   889                                          'WHERE cw_from_entity=%%(eid)s OR '
   891                                          ' cw_to_entity=%%(eid)s' % rdeftype,
   890                                          ' cw_to_entity=%%(eid)s' % rdeftype,
   892                                          {'eid': oldeid}, ask_confirm=False):
   891                                          {'eid': oldeid}, ask_confirm=False):
   893                     pending.add(eid)
   892                     # we should add deleted eids into pending eids else we may
       
   893                     # get some validation error on commit since integrity hooks
       
   894                     # may think some required relation is missing... This also ensure
       
   895                     # repository caches are properly cleanup
       
   896                     hook.set_operation(session, 'pendingeids', eid,
       
   897                                        hook.CleanupDeletedEidsCacheOp)
       
   898                     # and don't forget to remove record from system tables
       
   899                     self.repo.system_source.delete_info(
       
   900                         session, session.entity_from_eid(eid, rdeftype),
       
   901                         'system', None)
       
   902                     thispending.add(eid)
   894                 self.sqlexec('DELETE FROM cw_%s '
   903                 self.sqlexec('DELETE FROM cw_%s '
   895                              'WHERE cw_from_entity=%%(eid)s OR '
   904                              'WHERE cw_from_entity=%%(eid)s OR '
   896                              'cw_to_entity=%%(eid)s' % rdeftype,
   905                              'cw_to_entity=%%(eid)s' % rdeftype,
   897                              {'eid': oldeid}, ask_confirm=False)
   906                              {'eid': oldeid}, ask_confirm=False)
       
   907                 # now we have to manually cleanup relations pointing to deleted
       
   908                 # entities
       
   909                 thiseids = ','.join(str(eid) for eid in thispending)
       
   910                 for rschema, ttypes, role in schema[rdeftype].relation_definitions():
       
   911                     if rschema.type in VIRTUAL_RTYPES:
       
   912                         continue
       
   913                     sqls = []
       
   914                     if role == 'object':
       
   915                         if rschema.inlined:
       
   916                             for eschema in ttypes:
       
   917                                 sqls.append('DELETE FROM cw_%s WHERE cw_%s IN(%%s)'
       
   918                                             % (eschema, rschema))
       
   919                         else:
       
   920                             sqls.append('DELETE FROM %s_relation WHERE eid_to IN(%%s)'
       
   921                                         % rschema)
       
   922                     elif not rschema.inlined:
       
   923                         sqls.append('DELETE FROM %s_relation WHERE eid_from IN(%%s)'
       
   924                                     % rschema)
       
   925                     for sql in sqls:
       
   926                         self.sqlexec(sql % thiseids, ask_confirm=False)
   898             # remove the old type: use rql to propagate deletion
   927             # remove the old type: use rql to propagate deletion
   899             self.rqlexec('DELETE CWEType ET WHERE ET name %(on)s', {'on': oldname},
   928             self.rqlexec('DELETE CWEType ET WHERE ET name %(on)s', {'on': oldname},
   900                          ask_confirm=False)
   929                          ask_confirm=False)
   901         else:
   930         else:
   902             self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(on)s',
   931             self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(on)s',