hooks/syncschema.py
changeset 9969 0f64ef873f7a
parent 9965 a8769b752299
child 9971 5e44dd9dde6b
equal deleted inserted replaced
9968:50f046bf0e50 9969:0f64ef873f7a
    37 from cubicweb.predicates import is_instance
    37 from cubicweb.predicates import is_instance
    38 from cubicweb.schema import (SCHEMA_TYPES, META_RTYPES, VIRTUAL_RTYPES,
    38 from cubicweb.schema import (SCHEMA_TYPES, META_RTYPES, VIRTUAL_RTYPES,
    39                              CONSTRAINTS, ETYPE_NAME_MAP, display_name)
    39                              CONSTRAINTS, ETYPE_NAME_MAP, display_name)
    40 from cubicweb.server import hook, schemaserial as ss
    40 from cubicweb.server import hook, schemaserial as ss
    41 from cubicweb.server.sqlutils import SQL_PREFIX
    41 from cubicweb.server.sqlutils import SQL_PREFIX
       
    42 from cubicweb.hooks.synccomputed import RecomputeAttributeOperation
    42 
    43 
    43 # core entity and relation types which can't be removed
    44 # core entity and relation types which can't be removed
    44 CORE_TYPES = BASE_TYPES | SCHEMA_TYPES | META_RTYPES | set(
    45 CORE_TYPES = BASE_TYPES | SCHEMA_TYPES | META_RTYPES | set(
    45     ('CWUser', 'CWGroup','login', 'upassword', 'name', 'in_group'))
    46     ('CWUser', 'CWGroup','login', 'upassword', 'name', 'in_group'))
    46 
    47 
    69         return
    70         return
    70     createdattrs.add(attrkey)
    71     createdattrs.add(attrkey)
    71     table = SQL_PREFIX + etype
    72     table = SQL_PREFIX + etype
    72     column = SQL_PREFIX + rtype
    73     column = SQL_PREFIX + rtype
    73     try:
    74     try:
    74         cnx.system_sql(str('ALTER TABLE %s ADD %s integer'
    75         cnx.system_sql(str('ALTER TABLE %s ADD %s integer' % (table, column)),
    75                                % (table, column)), rollback_on_failure=False)
    76                        rollback_on_failure=False)
    76         cnx.info('added column %s to table %s', column, table)
    77         cnx.info('added column %s to table %s', column, table)
    77     except Exception:
    78     except Exception:
    78         # silent exception here, if this error has not been raised because the
    79         # silent exception here, if this error has not been raised because the
    79         # column already exists, index creation will fail anyway
    80         # column already exists, index creation will fail anyway
    80         cnx.exception('error while adding column %s to table %s',
    81         cnx.exception('error while adding column %s to table %s',
    81                           table, column)
    82                       table, column)
    82     # create index before alter table which may expectingly fail during test
    83     # create index before alter table which may expectingly fail during test
    83     # (sqlite) while index creation should never fail (test for index existence
    84     # (sqlite) while index creation should never fail (test for index existence
    84     # is done by the dbhelper)
    85     # is done by the dbhelper)
    85     cnx.repo.system_source.create_index(cnx, table, column)
    86     cnx.repo.system_source.create_index(cnx, table, column)
    86     cnx.info('added index on %s(%s)', table, column)
    87     cnx.info('added index on %s(%s)', table, column)
   165         cnx, table, column = self.cnx, self.table, self.column
   166         cnx, table, column = self.cnx, self.table, self.column
   166         source = cnx.repo.system_source
   167         source = cnx.repo.system_source
   167         # drop index if any
   168         # drop index if any
   168         source.drop_index(cnx, table, column)
   169         source.drop_index(cnx, table, column)
   169         if source.dbhelper.alter_column_support:
   170         if source.dbhelper.alter_column_support:
   170             cnx.system_sql('ALTER TABLE %s DROP COLUMN %s'
   171             cnx.system_sql('ALTER TABLE %s DROP COLUMN %s' % (table, column),
   171                                % (table, column), rollback_on_failure=False)
   172                            rollback_on_failure=False)
   172             self.info('dropped column %s from table %s', column, table)
   173             self.info('dropped column %s from table %s', column, table)
   173         else:
   174         else:
   174             # not supported by sqlite for instance
   175             # not supported by sqlite for instance
   175             self.error('dropping column not supported by the backend, handle '
   176             self.error('dropping column not supported by the backend, handle '
   176                        'it yourself (%s.%s)', table, column)
   177                        'it yourself (%s.%s)', table, column)
   469         # allow unicode queries
   470         # allow unicode queries
   470         table = SQL_PREFIX + rdefdef.subject
   471         table = SQL_PREFIX + rdefdef.subject
   471         column = SQL_PREFIX + rdefdef.name
   472         column = SQL_PREFIX + rdefdef.name
   472         try:
   473         try:
   473             cnx.system_sql(str('ALTER TABLE %s ADD %s %s'
   474             cnx.system_sql(str('ALTER TABLE %s ADD %s %s'
   474                                    % (table, column, attrtype)),
   475                                % (table, column, attrtype)),
   475                                rollback_on_failure=False)
   476                            rollback_on_failure=False)
   476             self.info('added column %s to table %s', table, column)
   477             self.info('added column %s to table %s', table, column)
   477         except Exception as ex:
   478         except Exception as ex:
   478             # the column probably already exists. this occurs when
   479             # the column probably already exists. this occurs when
   479             # the entity's type has just been added or if the column
   480             # the entity's type has just been added or if the column
   480             # has not been previously dropped
   481             # has not been previously dropped
   501         # update existing entities with the default value of newly added attribute
   502         # update existing entities with the default value of newly added attribute
   502         if default is not None:
   503         if default is not None:
   503             default = convert_default_value(self.rdefdef, default)
   504             default = convert_default_value(self.rdefdef, default)
   504             cnx.system_sql('UPDATE %s SET %s=%%(default)s' % (table, column),
   505             cnx.system_sql('UPDATE %s SET %s=%%(default)s' % (table, column),
   505                                {'default': default})
   506                                {'default': default})
       
   507         # if attribute is computed, compute it
       
   508         if entity.formula:
       
   509             # add rtype attribute for RelationDefinitionSchema api compat, this
       
   510             # is what RecomputeAttributeOperation expect
       
   511             rdefdef.rtype = rdefdef.name
       
   512             RecomputeAttributeOperation.get_instance(cnx).add_data(rdefdef)
   506 
   513 
   507     def revertprecommit_event(self):
   514     def revertprecommit_event(self):
   508         # revert changes on in memory schema
   515         # revert changes on in memory schema
   509         if getattr(self, 'rdefdef', None) is None:
   516         if getattr(self, 'rdefdef', None) is None:
   510             return
   517             return