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', |