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 }