# HG changeset patch # User Sylvain Thénault # Date 1274381403 -7200 # Node ID afd1face1faf19c055447d2677ed8f0c3c0afb3a # Parent 1a534c596bffb1943691258a6ccbd45d5302b9ab [schema migration] make some stuff to ease file 1.9 migration : we want to kill the Image entity so that existing image are turned into (existing entity type) File entities diff -r 1a534c596bff -r afd1face1faf hooks/syncschema.py --- a/hooks/syncschema.py Thu May 20 20:50:00 2010 +0200 +++ b/hooks/syncschema.py Thu May 20 20:50:03 2010 +0200 @@ -34,7 +34,8 @@ from cubicweb import ValidationError from cubicweb.selectors import implements -from cubicweb.schema import META_RTYPES, VIRTUAL_RTYPES, CONSTRAINTS, display_name +from cubicweb.schema import (META_RTYPES, VIRTUAL_RTYPES, CONSTRAINTS, + ETYPE_NAME_MAP, display_name) from cubicweb.server import hook, schemaserial as ss from cubicweb.server.sqlutils import SQL_PREFIX @@ -815,9 +816,10 @@ if name in CORE_ETYPES: raise ValidationError(self.entity.eid, {None: self._cw._('can\'t be deleted')}) # delete every entities of this type - self._cw.execute('DELETE %s X' % name) + if not name in ETYPE_NAME_MAP: + self._cw.execute('DELETE %s X' % name) + MemSchemaCWETypeDel(self._cw, name) DropTable(self._cw, table=SQL_PREFIX + name) - MemSchemaCWETypeDel(self._cw, name) class AfterDelCWETypeHook(DelCWETypeHook): @@ -982,7 +984,11 @@ def __call__(self): session = self._cw - rdef = session.vreg.schema.schema_by_eid(self.eidfrom) + try: + rdef = session.vreg.schema.schema_by_eid(self.eidfrom) + except KeyError: + self.critical('cant get schema rdef associated to %s', self.eidfrom) + return subjschema, rschema, objschema = rdef.as_triple() pendings = session.transaction_data.get('pendingeids', ()) pendingrdefs = session.transaction_data.setdefault('pendingrdefs', set()) @@ -1003,7 +1009,6 @@ # we have to update physical schema systematically for final and inlined # relations, but only if it's the last instance for this relation type # for other relations - if (rschema.final or rschema.inlined): rset = execute('Any COUNT(X) WHERE X is %s, X relation_type R, ' 'R eid %%(x)s, X from_entity E, E name %%(name)s' diff -r 1a534c596bff -r afd1face1faf schema.py --- a/schema.py Thu May 20 20:50:00 2010 +0200 +++ b/schema.py Thu May 20 20:50:03 2010 +0200 @@ -568,7 +568,14 @@ rdef.name = rdef.name.lower() rdef.subject = bw_normalize_etype(rdef.subject) rdef.object = bw_normalize_etype(rdef.object) - rdefs = super(CubicWebSchema, self).add_relation_def(rdef) + try: + rdefs = super(CubicWebSchema, self).add_relation_def(rdef) + except BadSchemaDefinition: + reversed_etype_map = dict( (v, k) for k, v in ETYPE_NAME_MAP.iteritems() ) + if rdef.subject in reversed_etype_map or rdef.object in reversed_etype_map: + self.warning('huuuu') + return + raise if rdefs: try: self._eid_index[rdef.eid] = rdefs diff -r 1a534c596bff -r afd1face1faf server/migractions.py --- a/server/migractions.py Thu May 20 20:50:00 2010 +0200 +++ b/server/migractions.py Thu May 20 20:50:03 2010 +0200 @@ -51,7 +51,8 @@ from yams.schema2sql import eschema2sql, rschema2sql from cubicweb import AuthenticationError -from cubicweb.schema import (META_RTYPES, VIRTUAL_RTYPES, +from cubicweb.schema import (ETYPE_NAME_MAP, META_RTYPES, VIRTUAL_RTYPES, + PURE_VIRTUAL_RTYPES, CubicWebRelationSchema, order_eschemas) from cubicweb.dbapi import get_repository, repo_connect from cubicweb.migration import MigrationHelper, yes @@ -851,9 +852,23 @@ `oldname` is a string giving the name of the existing entity type `newname` is a string giving the name of the renamed entity type """ - self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(oldname)s', - {'newname' : unicode(newname), 'oldname' : oldname}, - ask_confirm=False) + schema = self.repo.schema + if newname in schema: + assert oldname in ETYPE_NAME_MAP, \ + '%s should be mappend to %s in ETYPE_NAME_MAP' % (oldname, newname) + attrs = ','.join([SQL_PREFIX + rschema.type + for rschema in schema[newname].subject_relations() + if (rschema.final or rschema.inlined) + and not rschema in PURE_VIRTUAL_RTYPES]) + self.sqlexec('INSERT INTO %s%s(%s) SELECT %s FROM %s%s' % ( + SQL_PREFIX, newname, attrs, attrs, SQL_PREFIX, oldname)) + # use rql to propagate deletion. XXX we may miss some stuff since + # only the bootstrap schema is set. + self.rqlexec('DELETE CWEType ET WHERE ET name %(n)s', {'n': oldname}) + else: + self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(oldname)s', + {'newname' : unicode(newname), 'oldname' : oldname}, + ask_confirm=False) if commit: self.commit() diff -r 1a534c596bff -r afd1face1faf server/schemaserial.py --- a/server/schemaserial.py Thu May 20 20:50:00 2010 +0200 +++ b/server/schemaserial.py Thu May 20 20:50:03 2010 +0200 @@ -27,7 +27,9 @@ from yams import schema as schemamod, buildobjs as ybo -from cubicweb.schema import CONSTRAINTS, ETYPE_NAME_MAP, VIRTUAL_RTYPES +from cubicweb import CW_SOFTWARE_ROOT +from cubicweb.schema import (CONSTRAINTS, ETYPE_NAME_MAP, + VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES) from cubicweb.server import sqlutils def group_mapping(cursor, interactive=True): @@ -100,17 +102,28 @@ sidx[eid] = eschema continue if etype in ETYPE_NAME_MAP: + needcopy = False netype = ETYPE_NAME_MAP[etype] # can't use write rql queries at this point, use raw sql - session.system_sql('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s' - % {'p': sqlutils.SQL_PREFIX}, - {'x': eid, 'n': netype}) - session.system_sql('UPDATE entities SET type=%(n)s WHERE type=%(x)s', - {'x': etype, 'n': netype}) + sqlexec = session.system_sql + if sqlexec('SELECT 1 FROM %(p)sCWEType WHERE %(p)sname=%%(n)s' + % {'p': sqlutils.SQL_PREFIX}, {'n': netype}).fetchone(): + # the new type already exists, we should merge + assert etype.lower() != netype.lower() + needcopy = True + else: + # the new type doesn't exist, we should rename + sqlexec('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s' + % {'p': sqlutils.SQL_PREFIX}, {'x': eid, 'n': netype}) + if etype.lower() != netype.lower(): + sqlexec('ALTER TABLE %s%s RENAME TO %s%s' % ( + sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype)) + sqlexec('UPDATE entities SET type=%(n)s WHERE type=%(x)s', + {'x': etype, 'n': netype}) session.commit(False) try: - session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s', - {'x': etype, 'n': netype}) + sqlexec('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s', + {'x': etype, 'n': netype}) except: pass tocleanup = [eid] @@ -118,6 +131,12 @@ if etype == eidetype) repo.clear_caches(tocleanup) session.commit(False) + if needcopy: + from logilab.common.testlib import mock_object + sidx[eid] = mock_object(type=netype) + # copy / CWEType entity removal expected to be done through + # rename_entity_type in a migration script + continue etype = netype etype = ybo.EntityType(name=etype, description=desc, eid=eid) eschema = schema.add_entity_type(etype)