001 package liquibase.change.core; 002 003 import liquibase.change.AbstractChange; 004 import liquibase.change.ChangeMetaData; 005 import liquibase.change.ColumnConfig; 006 import liquibase.database.Database; 007 import liquibase.database.core.DB2Database; 008 import liquibase.database.core.SQLiteDatabase; 009 import liquibase.database.core.SQLiteDatabase.AlterTableVisitor; 010 import liquibase.database.structure.Index; 011 import liquibase.statement.SqlStatement; 012 import liquibase.statement.core.DropColumnStatement; 013 import liquibase.statement.core.ReorganizeTableStatement; 014 import liquibase.util.StringUtils; 015 016 import java.util.ArrayList; 017 import java.util.List; 018 019 /** 020 * Drops an existing column from a table. 021 */ 022 public class DropColumnChange extends AbstractChange { 023 024 private String schemaName; 025 private String tableName; 026 private String columnName; 027 028 public DropColumnChange() { 029 super("dropColumn", "Drop Column", ChangeMetaData.PRIORITY_DEFAULT); 030 } 031 032 public String getColumnName() { 033 return columnName; 034 } 035 036 public void setColumnName(String columnName) { 037 this.columnName = columnName; 038 } 039 040 public String getSchemaName() { 041 return schemaName; 042 } 043 044 public void setSchemaName(String schemaName) { 045 this.schemaName = StringUtils.trimToNull(schemaName); 046 } 047 048 public String getTableName() { 049 return tableName; 050 } 051 052 public void setTableName(String tableName) { 053 this.tableName = tableName; 054 } 055 056 public SqlStatement[] generateStatements(Database database) { 057 058 // todo if (database instanceof SQLiteDatabase) { 059 // // return special statements for SQLite databases 060 // return generateStatementsForSQLiteDatabase(database); 061 // } 062 063 List<SqlStatement> statements = new ArrayList<SqlStatement>(); 064 String schemaName = getSchemaName() == null ? database.getDefaultSchemaName() : getSchemaName(); 065 066 statements.add(new DropColumnStatement(schemaName, getTableName(), getColumnName())); 067 if (database instanceof DB2Database) { 068 statements.add(new ReorganizeTableStatement(schemaName, getTableName())); 069 } 070 071 return statements.toArray(new SqlStatement[statements.size()]); 072 } 073 074 private SqlStatement[] generateStatementsForSQLiteDatabase(Database database) { 075 076 // SQLite does not support this ALTER TABLE operation until now. 077 // For more information see: http://www.sqlite.org/omitted.html. 078 // This is a small work around... 079 080 List<SqlStatement> statements = new ArrayList<SqlStatement>(); 081 082 // define alter table logic 083 AlterTableVisitor rename_alter_visitor = new AlterTableVisitor() { 084 public ColumnConfig[] getColumnsToAdd() { 085 return new ColumnConfig[0]; 086 } 087 088 public boolean createThisColumn(ColumnConfig column) { 089 return !column.getName().equals(getColumnName()); 090 } 091 092 public boolean copyThisColumn(ColumnConfig column) { 093 return !column.getName().equals(getColumnName()); 094 } 095 096 public boolean createThisIndex(Index index) { 097 return !index.getColumns().contains(getColumnName()); 098 } 099 }; 100 101 try { 102 // alter table 103 statements.addAll(SQLiteDatabase.getAlterTableStatements(rename_alter_visitor, database, getSchemaName(), 104 getTableName())); 105 106 } catch (Exception e) { 107 e.printStackTrace(); 108 } 109 110 return statements.toArray(new SqlStatement[statements.size()]); 111 } 112 113 public String getConfirmationMessage() { 114 return "Column " + getTableName() + "." + getColumnName() + " dropped"; 115 } 116 }