# HG changeset patch # User Sylvain Thénault # Date 1443089880 -7200 # Node ID 8e504786df3cd988f326433d457734438a20cd15 # Parent cf800aa43f481fdd4979ac2abb76aeb3e15cce7b [hooks/syncschema] Turn DropColumnOp into a data operation While writing a test for a migration issue where "NOT NULL" was added to an inlined relation column, I ran into a case where the same column was deleted twice, which of course results in an error. This is because the "ecrit_par" relation used by the test is ambiguous. I've hence turned the DropColumnOp into a data operation to ensure we'll delete the column only once in such case. Related to #6211101 diff -r cf800aa43f48 -r 8e504786df3c hooks/syncschema.py --- a/hooks/syncschema.py Tue Nov 24 10:16:55 2015 +0100 +++ b/hooks/syncschema.py Thu Sep 24 12:18:00 2015 +0200 @@ -159,24 +159,26 @@ cnx.transaction_data.setdefault('pendingrtypes', set()).add(rtype) -class DropColumn(hook.Operation): +class DropColumn(hook.DataOperationMixIn, hook.Operation): """actually remove the attribut's column from entity table in the system database """ - table = column = None # make pylint happy def precommit_event(self): - cnx, table, column = self.cnx, self.table, self.column - source = cnx.repo.system_source - # drop index if any - source.drop_index(cnx, table, column) - if source.dbhelper.alter_column_support: - cnx.system_sql('ALTER TABLE %s DROP COLUMN %s' % (table, column), - rollback_on_failure=False) - self.info('dropped column %s from table %s', column, table) - else: - # not supported by sqlite for instance - self.error('dropping column not supported by the backend, handle ' - 'it yourself (%s.%s)', table, column) + cnx = self.cnx + for etype, attr in self.get_data(): + table = SQL_PREFIX + etype + column = SQL_PREFIX + attr + source = cnx.repo.system_source + # drop index if any + source.drop_index(cnx, table, column) + if source.dbhelper.alter_column_support: + cnx.system_sql('ALTER TABLE %s DROP COLUMN %s' % (table, column), + rollback_on_failure=False) + self.info('dropped column %s from table %s', column, table) + else: + # not supported by sqlite for instance + self.error('dropping column not supported by the backend, handle ' + 'it yourself (%s.%s)', table, column) # XXX revertprecommit_event @@ -361,8 +363,7 @@ # drop existant columns #if cnx.repo.system_source.dbhelper.alter_column_support: for etype in rschema.subjects(): - DropColumn(cnx, table=SQL_PREFIX + str(etype), - column=SQL_PREFIX + rtype) + DropColumn.get_instance(cnx).add_data((str(etype), rtype)) else: for etype in rschema.subjects(): try: @@ -607,8 +608,7 @@ if rset[0][0] == 0 and not cnx.deleted_in_transaction(rdef.subject.eid): ptypes = cnx.transaction_data.setdefault('pendingrtypes', set()) ptypes.add(rschema.type) - DropColumn(cnx, table=SQL_PREFIX + str(rdef.subject), - column=SQL_PREFIX + str(rschema)) + DropColumn.get_instance(cnx).add_data((str(rdef.subject), str(rschema))) elif lastrel: DropRelationTable(cnx, str(rschema)) # then update the in-memory schema