Coverage Report - liquibase.change.core.AddLookupTableChange
 
Classes in this File Line Coverage Branch Coverage Complexity
AddLookupTableChange
88%
68/77
100%
20/20
1.524
 
 1  
 package liquibase.change.core;
 2  
 
 3  
 import liquibase.change.AbstractChange;
 4  
 import liquibase.change.Change;
 5  
 import liquibase.change.ChangeMetaData;
 6  
 import liquibase.database.Database;
 7  
 import liquibase.database.core.DB2Database;
 8  
 import liquibase.database.core.InformixDatabase;
 9  
 import liquibase.database.core.MSSQLDatabase;
 10  
 import liquibase.database.core.OracleDatabase;
 11  
 import liquibase.database.core.SybaseASADatabase;
 12  
 import liquibase.statement.SqlStatement;
 13  
 import liquibase.statement.core.RawSqlStatement;
 14  
 import liquibase.statement.core.ReorganizeTableStatement;
 15  
 
 16  
 import java.util.ArrayList;
 17  
 import java.util.Arrays;
 18  
 import java.util.List;
 19  
 
 20  
 /**
 21  
  * Extracts data from an existing column to create a lookup table. A foreign key is created between the old column and
 22  
  * the new lookup table.
 23  
  */
 24  
 public class AddLookupTableChange extends AbstractChange {
 25  
 
 26  
     private String existingTableSchemaName;
 27  
     private String existingTableName;
 28  
     private String existingColumnName;
 29  
 
 30  
     private String newTableSchemaName;
 31  
     private String newTableName;
 32  
     private String newColumnName;
 33  
     private String newColumnDataType;
 34  
     private String constraintName;
 35  
 
 36  
     public AddLookupTableChange() {
 37  16
         super("addLookupTable", "Add Lookup Table", ChangeMetaData.PRIORITY_DEFAULT);
 38  16
     }
 39  
 
 40  
     public String getExistingTableSchemaName() {
 41  74
         return existingTableSchemaName;
 42  
     }
 43  
 
 44  
     public void setExistingTableSchemaName(String existingTableSchemaName) {
 45  1
         this.existingTableSchemaName = existingTableSchemaName;
 46  1
     }
 47  
 
 48  
     public String getExistingTableName() {
 49  183
         return existingTableName;
 50  
     }
 51  
 
 52  
     public void setExistingTableName(String existingTableName) {
 53  2
         this.existingTableName = existingTableName;
 54  2
     }
 55  
 
 56  
     public String getExistingColumnName() {
 57  214
         return existingColumnName;
 58  
     }
 59  
 
 60  
     public void setExistingColumnName(String existingColumnName) {
 61  2
         this.existingColumnName = existingColumnName;
 62  2
     }
 63  
 
 64  
     public String getNewTableSchemaName() {
 65  74
         return newTableSchemaName;
 66  
     }
 67  
 
 68  
     public void setNewTableSchemaName(String newTableSchemaName) {
 69  1
         this.newTableSchemaName = newTableSchemaName;
 70  1
     }
 71  
 
 72  
     public String getNewTableName() {
 73  308
         return newTableName;
 74  
     }
 75  
 
 76  
     public void setNewTableName(String newTableName) {
 77  1
         this.newTableName = newTableName;
 78  1
     }
 79  
 
 80  
     public String getNewColumnName() {
 81  252
         return newColumnName;
 82  
     }
 83  
 
 84  
     public void setNewColumnName(String newColumnName) {
 85  1
         this.newColumnName = newColumnName;
 86  1
     }
 87  
 
 88  
     public String getNewColumnDataType() {
 89  59
         return newColumnDataType;
 90  
     }
 91  
 
 92  
     public void setNewColumnDataType(String newColumnDataType) {
 93  1
         this.newColumnDataType = newColumnDataType;
 94  1
     }
 95  
 
 96  
     public String getConstraintName() {
 97  0
         return constraintName;
 98  
     }
 99  
 
 100  
     public String getFinalConstraintName() {
 101  59
         if (constraintName == null) {
 102  44
             return ("FK_" + getExistingTableName() + "_" + getNewTableName()).toUpperCase();
 103  
         } else {
 104  15
             return constraintName;
 105  
         }
 106  
     }
 107  
 
 108  
     public void setConstraintName(String constraintName) {
 109  1
         this.constraintName = constraintName;
 110  1
     }
 111  
 
 112  
     @Override
 113  
     protected Change[] createInverses() {
 114  0
         DropForeignKeyConstraintChange dropFK = new DropForeignKeyConstraintChange();
 115  0
         dropFK.setBaseTableSchemaName(getExistingTableSchemaName());
 116  0
         dropFK.setBaseTableName(getExistingTableName());
 117  0
         dropFK.setConstraintName(getFinalConstraintName());
 118  
 
 119  0
         DropTableChange dropTable = new DropTableChange();
 120  0
         dropTable.setSchemaName(getNewTableSchemaName());
 121  0
         dropTable.setTableName(getNewTableName());
 122  
 
 123  0
         return new Change[] { dropFK, dropTable, };
 124  
     }
 125  
 
 126  
     public SqlStatement[] generateStatements(Database database) {
 127  59
         List<SqlStatement> statements = new ArrayList<SqlStatement>();
 128  
 
 129  59
         String newTableSchemaName = getNewTableSchemaName() == null ? database.getDefaultSchemaName()
 130  
                 : getNewTableSchemaName();
 131  59
         String existingTableSchemaName = getExistingTableSchemaName() == null ? database.getDefaultSchemaName()
 132  
                 : getExistingTableSchemaName();
 133  
 
 134  59
         SqlStatement[] createTablesSQL = { new RawSqlStatement("CREATE TABLE "
 135  
                 + database.escapeTableName(newTableSchemaName, getNewTableName()) + " AS SELECT DISTINCT "
 136  
                 + getExistingColumnName() + " AS " + getNewColumnName() + " FROM "
 137  
                 + database.escapeTableName(existingTableSchemaName, getExistingTableName()) + " WHERE "
 138  
                 + getExistingColumnName() + " IS NOT NULL") };
 139  59
         if (database instanceof MSSQLDatabase) {
 140  4
             createTablesSQL = new SqlStatement[] { new RawSqlStatement("SELECT DISTINCT " + getExistingColumnName()
 141  
                     + " AS " + getNewColumnName() + " INTO "
 142  
                     + database.escapeTableName(newTableSchemaName, getNewTableName()) + " FROM "
 143  
                     + database.escapeTableName(existingTableSchemaName, getExistingTableName()) + " WHERE "
 144  
                     + getExistingColumnName() + " IS NOT NULL"), };
 145  55
         } else if (database instanceof SybaseASADatabase) {
 146  4
             createTablesSQL = new SqlStatement[] { new RawSqlStatement("SELECT DISTINCT " + getExistingColumnName()
 147  
                     + " AS " + getNewColumnName() + " INTO "
 148  
                     + database.escapeTableName(newTableSchemaName, getNewTableName()) + " FROM "
 149  
                     + database.escapeTableName(existingTableSchemaName, getExistingTableName()) + " WHERE "
 150  
                     + getExistingColumnName() + " IS NOT NULL"), };
 151  51
         } else if (database instanceof DB2Database) {
 152  4
             createTablesSQL = new SqlStatement[] {
 153  
                     new RawSqlStatement("CREATE TABLE "
 154  
                             + database.escapeTableName(newTableSchemaName, getNewTableName()) + " AS (SELECT "
 155  
                             + getExistingColumnName() + " AS " + getNewColumnName() + " FROM "
 156  
                             + database.escapeTableName(existingTableSchemaName, getExistingTableName())
 157  
                             + ") WITH NO DATA"),
 158  
                     new RawSqlStatement("INSERT INTO "
 159  
                             + database.escapeTableName(newTableSchemaName, getNewTableName()) + " SELECT DISTINCT "
 160  
                             + getExistingColumnName() + " FROM "
 161  
                             + database.escapeTableName(existingTableSchemaName, getExistingTableName()) + " WHERE "
 162  
                             + getExistingColumnName() + " IS NOT NULL"), };
 163  47
         } else if (database instanceof InformixDatabase) {
 164  4
             createTablesSQL = new SqlStatement[] {
 165  
                     new RawSqlStatement("CREATE TABLE "
 166  
                             + database.escapeTableName(newTableSchemaName, getNewTableName()) + " ( "
 167  
                             + getNewColumnName() + " " + getNewColumnDataType() + " )"),
 168  
                     new RawSqlStatement("INSERT INTO "
 169  
                             + database.escapeTableName(newTableSchemaName, getNewTableName()) + " ( "
 170  
                             + getNewColumnName() + " ) SELECT DISTINCT " + getExistingColumnName() + " FROM "
 171  
                             + database.escapeTableName(existingTableSchemaName, getExistingTableName()) + " WHERE "
 172  
                             + getExistingColumnName() + " IS NOT NULL"), };
 173  
         }
 174  
 
 175  59
         statements.addAll(Arrays.asList(createTablesSQL));
 176  
 
 177  59
         if (!(database instanceof OracleDatabase)) {
 178  55
             AddNotNullConstraintChange addNotNullChange = new AddNotNullConstraintChange();
 179  55
             addNotNullChange.setSchemaName(newTableSchemaName);
 180  55
             addNotNullChange.setTableName(getNewTableName());
 181  55
             addNotNullChange.setColumnName(getNewColumnName());
 182  55
             addNotNullChange.setColumnDataType(getNewColumnDataType());
 183  55
             statements.addAll(Arrays.asList(addNotNullChange.generateStatements(database)));
 184  
         }
 185  
 
 186  59
         if (database instanceof DB2Database) {
 187  4
             statements.add(new ReorganizeTableStatement(newTableSchemaName, getNewTableName()));
 188  
         }
 189  
 
 190  59
         AddPrimaryKeyChange addPKChange = new AddPrimaryKeyChange();
 191  59
         addPKChange.setSchemaName(newTableSchemaName);
 192  59
         addPKChange.setTableName(getNewTableName());
 193  59
         addPKChange.setColumnNames(getNewColumnName());
 194  59
         statements.addAll(Arrays.asList(addPKChange.generateStatements(database)));
 195  
 
 196  59
         if (database instanceof DB2Database) {
 197  4
             statements.add(new ReorganizeTableStatement(newTableSchemaName, getNewTableName()));
 198  
         }
 199  
 
 200  59
         AddForeignKeyConstraintChange addFKChange = new AddForeignKeyConstraintChange();
 201  59
         addFKChange.setBaseTableSchemaName(existingTableSchemaName);
 202  59
         addFKChange.setBaseTableName(getExistingTableName());
 203  59
         addFKChange.setBaseColumnNames(getExistingColumnName());
 204  59
         addFKChange.setReferencedTableSchemaName(newTableSchemaName);
 205  59
         addFKChange.setReferencedTableName(getNewTableName());
 206  59
         addFKChange.setReferencedColumnNames(getNewColumnName());
 207  
 
 208  59
         addFKChange.setConstraintName(getFinalConstraintName());
 209  59
         statements.addAll(Arrays.asList(addFKChange.generateStatements(database)));
 210  
 
 211  59
         return statements.toArray(new SqlStatement[statements.size()]);
 212  
     }
 213  
 
 214  
     public String getConfirmationMessage() {
 215  1
         return "Lookup table added for " + getExistingTableName() + "." + getExistingColumnName();
 216  
     }
 217  
 }