Coverage Report - liquibase.sqlgenerator.core.CreateTableGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
CreateTableGenerator
35%
34/97
16%
18/110
19.333
 
 1  
 package liquibase.sqlgenerator.core;
 2  
 
 3  
 import java.util.Iterator;
 4  
 
 5  
 import liquibase.database.Database;
 6  
 import liquibase.database.core.DB2Database;
 7  
 import liquibase.database.core.InformixDatabase;
 8  
 import liquibase.database.core.MSSQLDatabase;
 9  
 import liquibase.database.core.OracleDatabase;
 10  
 import liquibase.database.core.SQLiteDatabase;
 11  
 import liquibase.database.core.SybaseASADatabase;
 12  
 import liquibase.database.core.SybaseDatabase;
 13  
 import liquibase.exception.ValidationErrors;
 14  
 import liquibase.logging.LogFactory;
 15  
 import liquibase.sql.Sql;
 16  
 import liquibase.sql.UnparsedSql;
 17  
 import liquibase.sqlgenerator.SqlGeneratorChain;
 18  
 import liquibase.statement.ForeignKeyConstraint;
 19  
 import liquibase.statement.UniqueConstraint;
 20  
 import liquibase.statement.core.CreateTableStatement;
 21  
 import liquibase.util.StringUtils;
 22  
 
 23  50
 public class CreateTableGenerator extends AbstractSqlGenerator<CreateTableStatement> {
 24  
 
 25  
     @Override
 26  
     public ValidationErrors validate(CreateTableStatement createTableStatement, Database database,
 27  
             SqlGeneratorChain sqlGeneratorChain) {
 28  33
         ValidationErrors validationErrors = new ValidationErrors();
 29  33
         validationErrors.checkRequiredField("tableName", createTableStatement.getTableName());
 30  33
         validationErrors.checkRequiredField("columns", createTableStatement.getColumns());
 31  33
         return validationErrors;
 32  
     }
 33  
 
 34  
     @Override
 35  
     public Sql[] generateSql(CreateTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
 36  2
         StringBuffer buffer = new StringBuffer();
 37  2
         buffer.append("CREATE TABLE ")
 38  
                 .append(database.escapeTableName(statement.getSchemaName(), statement.getTableName())).append(" ");
 39  2
         buffer.append("(");
 40  2
         Iterator<String> columnIterator = statement.getColumns().iterator();
 41  4
         while (columnIterator.hasNext()) {
 42  2
             String column = columnIterator.next();
 43  2
             boolean isAutoIncrement = statement.getAutoIncrementColumns().contains(column);
 44  
 
 45  2
             buffer.append(database.escapeColumnName(statement.getSchemaName(), statement.getTableName(), column));
 46  2
             buffer.append(" ").append(statement.getColumnTypes().get(column));
 47  
 
 48  2
             if ((database instanceof SQLiteDatabase) && (statement.getPrimaryKeyConstraint() != null)
 49  
                     && (statement.getPrimaryKeyConstraint().getColumns().size() == 1)
 50  
                     && (statement.getPrimaryKeyConstraint().getColumns().contains(column)) && isAutoIncrement) {
 51  0
                 String pkName = StringUtils.trimToNull(statement.getPrimaryKeyConstraint().getConstraintName());
 52  0
                 if (pkName == null) {
 53  0
                     pkName = database.generatePrimaryKeyName(statement.getTableName());
 54  
                 }
 55  0
                 if (pkName != null) {
 56  0
                     buffer.append(" CONSTRAINT ");
 57  0
                     buffer.append(database.escapeConstraintName(pkName));
 58  
                 }
 59  0
                 buffer.append(" PRIMARY KEY AUTOINCREMENT");
 60  
             }
 61  
 
 62  2
             if (statement.getDefaultValue(column) != null) {
 63  1
                 Object defaultValue = statement.getDefaultValue(column);
 64  1
                 if (database instanceof MSSQLDatabase) {
 65  0
                     buffer.append(" CONSTRAINT ").append(
 66  
                             ((MSSQLDatabase) database).generateDefaultConstraintName(statement.getTableName(), column));
 67  
                 }
 68  1
                 buffer.append(" DEFAULT ");
 69  1
                 buffer.append(statement.getColumnTypes().get(column).convertObjectToString(defaultValue, database));
 70  
             }
 71  
 
 72  2
             if (isAutoIncrement && (database.getAutoIncrementClause() != null)
 73  
                     && (!database.getAutoIncrementClause().equals(""))) {
 74  0
                 if (database.supportsAutoIncrement()) {
 75  0
                     buffer.append(" ").append(database.getAutoIncrementClause()).append(" ");
 76  
                 } else {
 77  0
                     LogFactory.getLogger().warning(
 78  
                             database.getTypeName() + " does not support autoincrement columns as request for "
 79  
                                     + (database.escapeTableName(statement.getSchemaName(), statement.getTableName())));
 80  
                 }
 81  
             }
 82  
 
 83  2
             if (statement.getNotNullColumns().contains(column)) {
 84  0
                 buffer.append(" NOT NULL");
 85  
             } else {
 86  2
                 if (database instanceof SybaseDatabase || database instanceof SybaseASADatabase) {
 87  0
                     buffer.append(" NULL");
 88  
                 }
 89  
             }
 90  
 
 91  2
             if ((database instanceof InformixDatabase) && (statement.getPrimaryKeyConstraint() != null)
 92  
                     && (statement.getPrimaryKeyConstraint().getColumns().size() == 1)
 93  
                     && (statement.getPrimaryKeyConstraint().getColumns().contains(column))) {
 94  0
                 buffer.append(" PRIMARY KEY");
 95  
             }
 96  
 
 97  2
             if (columnIterator.hasNext()) {
 98  0
                 buffer.append(", ");
 99  
             }
 100  2
         }
 101  
 
 102  2
         buffer.append(",");
 103  
 
 104  
         // TODO informixdb
 105  2
         if (!((database instanceof SQLiteDatabase) && (statement.getPrimaryKeyConstraint() != null)
 106  
                 && (statement.getPrimaryKeyConstraint().getColumns().size() == 1) && statement
 107  
                 .getAutoIncrementColumns().contains(statement.getPrimaryKeyConstraint().getColumns().get(0)))
 108  
                 &&
 109  
 
 110  
                 !((database instanceof InformixDatabase) && (statement.getPrimaryKeyConstraint() != null) && (statement
 111  
                         .getPrimaryKeyConstraint().getColumns().size() == 1))) {
 112  
             // ...skip this code block for sqlite if a single column primary key
 113  
             // with an autoincrement constraint exists.
 114  
             // This constraint is added after the column type.
 115  
 
 116  2
             if (statement.getPrimaryKeyConstraint() != null
 117  
                     && statement.getPrimaryKeyConstraint().getColumns().size() > 0) {
 118  0
                 if (!(database instanceof InformixDatabase)) {
 119  0
                     String pkName = StringUtils.trimToNull(statement.getPrimaryKeyConstraint().getConstraintName());
 120  0
                     if (pkName == null) {
 121  
                         // TODO ORA-00972: identifier is too long
 122  
                         // If tableName lenght is more then 28 symbols
 123  
                         // then generated pkName will be incorrect
 124  0
                         pkName = database.generatePrimaryKeyName(statement.getTableName());
 125  
                     }
 126  0
                     if (pkName != null) {
 127  0
                         buffer.append(" CONSTRAINT ");
 128  0
                         buffer.append(database.escapeConstraintName(pkName));
 129  
                     }
 130  
                 }
 131  0
                 buffer.append(" PRIMARY KEY (");
 132  0
                 buffer.append(database.escapeColumnNameList(StringUtils.join(statement.getPrimaryKeyConstraint()
 133  
                         .getColumns(), ", ")));
 134  0
                 buffer.append(")");
 135  
                 // Setting up table space for PK's index if it exist
 136  0
                 if (database instanceof OracleDatabase && statement.getPrimaryKeyConstraint().getTablespace() != null) {
 137  0
                     buffer.append(" USING INDEX TABLESPACE ");
 138  0
                     buffer.append(statement.getPrimaryKeyConstraint().getTablespace());
 139  
                 }
 140  0
                 buffer.append(",");
 141  
             }
 142  
         }
 143  
 
 144  2
         for (ForeignKeyConstraint fkConstraint : statement.getForeignKeyConstraints()) {
 145  0
             if (!(database instanceof InformixDatabase)) {
 146  0
                 buffer.append(" CONSTRAINT ");
 147  0
                 buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
 148  
             }
 149  0
             String referencesString = fkConstraint.getReferences();
 150  0
             if (!referencesString.contains(".") && database.getDefaultSchemaName() != null) {
 151  0
                 referencesString = database.getDefaultSchemaName() + "." + referencesString;
 152  
             }
 153  0
             buffer.append(" FOREIGN KEY (")
 154  
                     .append(database.escapeColumnName(statement.getSchemaName(), statement.getTableName(),
 155  
                             fkConstraint.getColumn())).append(") REFERENCES ").append(referencesString);
 156  
 
 157  0
             if (fkConstraint.isDeleteCascade()) {
 158  0
                 buffer.append(" ON DELETE CASCADE");
 159  
             }
 160  
 
 161  0
             if ((database instanceof InformixDatabase)) {
 162  0
                 buffer.append(" CONSTRAINT ");
 163  0
                 buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
 164  
             }
 165  
 
 166  0
             if (fkConstraint.isInitiallyDeferred()) {
 167  0
                 buffer.append(" INITIALLY DEFERRED");
 168  
             }
 169  0
             if (fkConstraint.isDeferrable()) {
 170  0
                 buffer.append(" DEFERRABLE");
 171  
             }
 172  0
             buffer.append(",");
 173  0
         }
 174  
 
 175  2
         for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
 176  0
             if (uniqueConstraint.getConstraintName() != null && !constraintNameAfterUnique(database)) {
 177  0
                 buffer.append(" CONSTRAINT ");
 178  0
                 buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
 179  
             }
 180  0
             buffer.append(" UNIQUE (");
 181  0
             buffer.append(database.escapeColumnNameList(StringUtils.join(uniqueConstraint.getColumns(), ", ")));
 182  0
             buffer.append(")");
 183  0
             if (uniqueConstraint.getConstraintName() != null && constraintNameAfterUnique(database)) {
 184  0
                 buffer.append(" CONSTRAINT ");
 185  0
                 buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
 186  
             }
 187  0
             buffer.append(",");
 188  
         }
 189  
 
 190  
         // if (constraints != null && constraints.getCheck() != null) {
 191  
         // buffer.append(constraints.getCheck()).append(" ");
 192  
         // }
 193  
         // }
 194  
 
 195  2
         String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";
 196  
 
 197  
         // if (StringUtils.trimToNull(tablespace) != null && database.supportsTablespaces()) {
 198  
         // if (database instanceof MSSQLDatabase) {
 199  
         // buffer.append(" ON ").append(tablespace);
 200  
         // } else if (database instanceof DB2Database) {
 201  
         // buffer.append(" IN ").append(tablespace);
 202  
         // } else {
 203  
         // buffer.append(" TABLESPACE ").append(tablespace);
 204  
         // }
 205  
         // }
 206  
 
 207  2
         if (statement.getTablespace() != null && database.supportsTablespaces()) {
 208  0
             if (database instanceof MSSQLDatabase || database instanceof SybaseASADatabase) {
 209  0
                 sql += " ON " + statement.getTablespace();
 210  0
             } else if (database instanceof DB2Database || database instanceof InformixDatabase) {
 211  0
                 sql += " IN " + statement.getTablespace();
 212  
             } else {
 213  0
                 sql += " TABLESPACE " + statement.getTablespace();
 214  
             }
 215  
         }
 216  
 
 217  2
         return new Sql[] { new UnparsedSql(sql) };
 218  
     }
 219  
 
 220  
     private boolean constraintNameAfterUnique(Database database) {
 221  0
         return database instanceof InformixDatabase;
 222  
     }
 223  
 
 224  
 }