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 |