Search in sources :

Example 1 with UniqueConstraint

use of liquibase.statement.UniqueConstraint in project liquibase by liquibase.

the class CreateTableGenerator method generateSql.

@Override
public Sql[] generateSql(CreateTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    if (database instanceof InformixDatabase) {
        AbstractSqlGenerator<CreateTableStatement> gen = new CreateTableGeneratorInformix();
        return gen.generateSql(statement, database, sqlGeneratorChain);
    }
    List<Sql> additionalSql = new ArrayList<Sql>();
    StringBuffer buffer = new StringBuffer();
    buffer.append("CREATE TABLE ").append(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())).append(" ");
    buffer.append("(");
    boolean isSinglePrimaryKeyColumn = statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().size() == 1;
    boolean isPrimaryKeyAutoIncrement = false;
    Iterator<String> columnIterator = statement.getColumns().iterator();
    List<String> primaryKeyColumns = new LinkedList<String>();
    BigInteger mysqlTableOptionStartWith = null;
    while (columnIterator.hasNext()) {
        String column = columnIterator.next();
        DatabaseDataType columnType = statement.getColumnTypes().get(column).toDatabaseDataType(database);
        buffer.append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), column, true));
        buffer.append(" ").append(columnType);
        AutoIncrementConstraint autoIncrementConstraint = null;
        for (AutoIncrementConstraint currentAutoIncrementConstraint : statement.getAutoIncrementConstraints()) {
            if (column.equals(currentAutoIncrementConstraint.getColumnName())) {
                autoIncrementConstraint = currentAutoIncrementConstraint;
                break;
            }
        }
        boolean isAutoIncrementColumn = autoIncrementConstraint != null;
        boolean isPrimaryKeyColumn = statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().contains(column);
        isPrimaryKeyAutoIncrement = isPrimaryKeyAutoIncrement || isPrimaryKeyColumn && isAutoIncrementColumn;
        if (isPrimaryKeyColumn) {
            primaryKeyColumns.add(column);
        }
        if ((database instanceof SQLiteDatabase) && isSinglePrimaryKeyColumn && isPrimaryKeyColumn && isAutoIncrementColumn) {
            String pkName = StringUtils.trimToNull(statement.getPrimaryKeyConstraint().getConstraintName());
            if (pkName == null) {
                pkName = database.generatePrimaryKeyName(statement.getTableName());
            }
            if (pkName != null) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(pkName));
            }
            buffer.append(" PRIMARY KEY");
        }
        // for the serial data type in postgres, there should be no default value
        if (!columnType.isAutoIncrement() && statement.getDefaultValue(column) != null) {
            Object defaultValue = statement.getDefaultValue(column);
            if (database instanceof MSSQLDatabase) {
                String constraintName = statement.getDefaultValueConstraintName(column);
                if (constraintName == null) {
                    constraintName = ((MSSQLDatabase) database).generateDefaultConstraintName(statement.getTableName(), column);
                }
                buffer.append(" CONSTRAINT ").append(database.escapeObjectName(constraintName, ForeignKey.class));
            }
            if (database instanceof OracleDatabase && statement.getDefaultValue(column).toString().startsWith("GENERATED ALWAYS ")) {
                buffer.append(" ");
            } else {
                buffer.append(" DEFAULT ");
            }
            if (defaultValue instanceof SequenceNextValueFunction) {
                buffer.append(database.generateDatabaseFunctionValue((SequenceNextValueFunction) defaultValue));
            } else {
                buffer.append(statement.getColumnTypes().get(column).objectToSql(defaultValue, database));
            }
        }
        if (isAutoIncrementColumn) {
            // TODO: check if database supports auto increment on non primary key column
            if (database.supportsAutoIncrement()) {
                String autoIncrementClause = database.getAutoIncrementClause(autoIncrementConstraint.getStartWith(), autoIncrementConstraint.getIncrementBy());
                if (!"".equals(autoIncrementClause)) {
                    buffer.append(" ").append(autoIncrementClause);
                }
                if (autoIncrementConstraint.getStartWith() != null) {
                    if (database instanceof PostgresDatabase) {
                        String sequenceName = statement.getTableName() + "_" + column + "_seq";
                        additionalSql.add(new UnparsedSql("alter sequence " + database.escapeSequenceName(statement.getCatalogName(), statement.getSchemaName(), sequenceName) + " start with " + autoIncrementConstraint.getStartWith(), new Sequence().setName(sequenceName).setSchema(statement.getCatalogName(), statement.getSchemaName())));
                    } else if (database instanceof MySQLDatabase) {
                        mysqlTableOptionStartWith = autoIncrementConstraint.getStartWith();
                    }
                }
            } else {
                LogFactory.getLogger().warning(database.getShortName() + " does not support autoincrement columns as requested for " + (database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())));
            }
        }
        if (statement.getNotNullColumns().contains(column)) {
            buffer.append(" NOT NULL");
        } else {
            if (database instanceof SybaseDatabase || database instanceof SybaseASADatabase || database instanceof MySQLDatabase || (database instanceof MSSQLDatabase && columnType.toString().toLowerCase().contains("timestamp"))) {
                buffer.append(" NULL");
            }
        }
        if (database instanceof InformixDatabase && isSinglePrimaryKeyColumn && isPrimaryKeyColumn) {
        //buffer.append(" PRIMARY KEY");
        }
        if (database instanceof MySQLDatabase && statement.getColumnRemarks(column) != null) {
            buffer.append(" COMMENT '" + database.escapeStringForDatabase(statement.getColumnRemarks(column)) + "'");
        }
        if (columnIterator.hasNext()) {
            buffer.append(", ");
        }
    }
    buffer.append(",");
    if (!((database instanceof SQLiteDatabase) && isSinglePrimaryKeyColumn && isPrimaryKeyAutoIncrement) && !((database instanceof InformixDatabase) && isSinglePrimaryKeyColumn)) {
        if (statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().size() > 0) {
            if (database.supportsPrimaryKeyNames()) {
                String pkName = StringUtils.trimToNull(statement.getPrimaryKeyConstraint().getConstraintName());
                if (pkName == null) {
                    // TODO ORA-00972: identifier is too long
                    // If tableName lenght is more then 28 symbols
                    // then generated pkName will be incorrect
                    pkName = database.generatePrimaryKeyName(statement.getTableName());
                }
                if (pkName != null) {
                    buffer.append(" CONSTRAINT ");
                    buffer.append(database.escapeConstraintName(pkName));
                }
            }
            buffer.append(" PRIMARY KEY (");
            buffer.append(database.escapeColumnNameList(StringUtils.join(statement.getPrimaryKeyConstraint().getColumns(), ", ")));
            buffer.append(")");
            // Setting up table space for PK's index if it exist
            if ((database instanceof OracleDatabase || database instanceof PostgresDatabase) && statement.getPrimaryKeyConstraint().getTablespace() != null) {
                buffer.append(" USING INDEX TABLESPACE ");
                buffer.append(statement.getPrimaryKeyConstraint().getTablespace());
            }
            buffer.append(",");
        }
    }
    for (ForeignKeyConstraint fkConstraint : statement.getForeignKeyConstraints()) {
        if (!(database instanceof InformixDatabase)) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
        }
        String referencesString = fkConstraint.getReferences();
        buffer.append(" FOREIGN KEY (").append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), fkConstraint.getColumn())).append(") REFERENCES ");
        if (referencesString != null) {
            if (!referencesString.contains(".") && database.getDefaultSchemaName() != null && database.getOutputDefaultSchema()) {
                referencesString = database.escapeObjectName(database.getDefaultSchemaName(), Schema.class) + "." + referencesString;
            }
            buffer.append(referencesString);
        } else {
            buffer.append(database.escapeObjectName(fkConstraint.getReferencedTableCatalogName(), fkConstraint.getReferencedTableSchemaName(), fkConstraint.getReferencedTableName(), Table.class)).append("(").append(database.escapeColumnNameList(fkConstraint.getReferencedColumnNames())).append(")");
        }
        if (fkConstraint.isDeleteCascade()) {
            buffer.append(" ON DELETE CASCADE");
        }
        if ((database instanceof InformixDatabase)) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
        }
        if (fkConstraint.isInitiallyDeferred()) {
            buffer.append(" INITIALLY DEFERRED");
        }
        if (fkConstraint.isDeferrable()) {
            buffer.append(" DEFERRABLE");
        }
        buffer.append(",");
    }
    for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
        if (uniqueConstraint.getConstraintName() != null && !constraintNameAfterUnique(database)) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
        }
        buffer.append(" UNIQUE (");
        buffer.append(database.escapeColumnNameList(StringUtils.join(uniqueConstraint.getColumns(), ", ")));
        buffer.append(")");
        if (uniqueConstraint.getConstraintName() != null && constraintNameAfterUnique(database)) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
        }
        buffer.append(",");
    }
    //        if (constraints != null && constraints.getCheckConstraint() != null) {
    //            buffer.append(constraints.getCheckConstraint()).append(" ");
    //        }
    //    }
    String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";
    if (database instanceof MySQLDatabase && mysqlTableOptionStartWith != null) {
        LogFactory.getLogger().info("[MySQL] Using last startWith statement (" + mysqlTableOptionStartWith.toString() + ") as table option.");
        sql += " " + ((MySQLDatabase) database).getTableOptionAutoIncrementStartWithClause(mysqlTableOptionStartWith);
    }
    if (statement.getTablespace() != null && database.supportsTablespaces()) {
        if (database instanceof MSSQLDatabase || database instanceof SybaseASADatabase) {
            sql += " ON " + statement.getTablespace();
        } else if (database instanceof DB2Database || database instanceof InformixDatabase) {
            sql += " IN " + statement.getTablespace();
        } else {
            sql += " TABLESPACE " + statement.getTablespace();
        }
    }
    if (database instanceof MySQLDatabase && statement.getRemarks() != null) {
        sql += " COMMENT='" + database.escapeStringForDatabase(statement.getRemarks()) + "' ";
    }
    additionalSql.add(0, new UnparsedSql(sql, getAffectedTable(statement)));
    return additionalSql.toArray(new Sql[additionalSql.size()]);
}
Also used : ForeignKeyConstraint(liquibase.statement.ForeignKeyConstraint) ArrayList(java.util.ArrayList) UniqueConstraint(liquibase.statement.UniqueConstraint) DatabaseDataType(liquibase.datatype.DatabaseDataType) SequenceNextValueFunction(liquibase.statement.SequenceNextValueFunction) AutoIncrementConstraint(liquibase.statement.AutoIncrementConstraint) UnparsedSql(liquibase.sql.UnparsedSql) CreateTableStatement(liquibase.statement.core.CreateTableStatement) LinkedList(java.util.LinkedList) Sql(liquibase.sql.Sql) UnparsedSql(liquibase.sql.UnparsedSql) BigInteger(java.math.BigInteger)

Example 2 with UniqueConstraint

use of liquibase.statement.UniqueConstraint in project liquibase by liquibase.

the class CreateTableGeneratorInformix method generateSql.

@Override
public Sql[] generateSql(CreateTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    StringBuilder buffer = new StringBuilder();
    buffer.append("CREATE TABLE ").append(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())).append(" ");
    buffer.append("(");
    boolean isSinglePrimaryKeyColumn = statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().size() == 1;
    boolean isPrimaryKeyAutoIncrement = false;
    Iterator<String> columnIterator = statement.getColumns().iterator();
    List<String> primaryKeyColumns = new LinkedList<String>();
    while (columnIterator.hasNext()) {
        String column = columnIterator.next();
        buffer.append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), column));
        buffer.append(" ").append(statement.getColumnTypes().get(column).toDatabaseDataType(database).toSql());
        AutoIncrementConstraint autoIncrementConstraint = null;
        for (AutoIncrementConstraint currentAutoIncrementConstraint : statement.getAutoIncrementConstraints()) {
            if (column.equals(currentAutoIncrementConstraint.getColumnName())) {
                autoIncrementConstraint = currentAutoIncrementConstraint;
                break;
            }
        }
        boolean isAutoIncrementColumn = autoIncrementConstraint != null;
        boolean isPrimaryKeyColumn = statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().contains(column);
        isPrimaryKeyAutoIncrement = isPrimaryKeyAutoIncrement || isPrimaryKeyColumn && isAutoIncrementColumn;
        if (isPrimaryKeyColumn) {
            primaryKeyColumns.add(column);
        }
        if (statement.getDefaultValue(column) != null) {
            Object defaultValue = statement.getDefaultValue(column);
            buffer.append(" DEFAULT ");
            buffer.append(statement.getColumnTypes().get(column).objectToSql(defaultValue, database));
        }
        if (isAutoIncrementColumn) {
            // TODO: check if database supports auto increment on non primary key column
            if (database.supportsAutoIncrement()) {
                String autoIncrementClause = database.getAutoIncrementClause(autoIncrementConstraint.getStartWith(), autoIncrementConstraint.getIncrementBy());
                if (autoIncrementClause.length() > 0) {
                    buffer.append(" ").append(autoIncrementClause);
                }
            } else {
                LogFactory.getLogger().warning(database.getShortName() + " does not support autoincrement columns as requested for " + (database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())));
            }
        }
        if (statement.getNotNullColumns().contains(column)) {
            buffer.append(" NOT NULL");
        }
        if (columnIterator.hasNext()) {
            buffer.append(", ");
        }
    }
    buffer.append(",");
    // Fix according to: https://liquibase.jira.com/browse/CORE-1775
    if (isSinglePrimaryKeyColumn && isPrimaryKeyAutoIncrement) {
        if (statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().size() > 0) {
            buffer.append(" PRIMARY KEY (");
            buffer.append(StringUtils.join(primaryKeyColumns, ", "));
            buffer.append(")");
            // Setting up table space for PK's index if it exist
            buffer.append(",");
        }
    }
    for (ForeignKeyConstraint fkConstraint : statement.getForeignKeyConstraints()) {
        String referencesString = fkConstraint.getReferences();
        if (!referencesString.contains(".") && database.getDefaultSchemaName() != null) {
            referencesString = database.getDefaultSchemaName() + "." + referencesString;
        }
        buffer.append(" FOREIGN KEY (").append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), fkConstraint.getColumn())).append(") REFERENCES ").append(referencesString);
        if (fkConstraint.isDeleteCascade()) {
            buffer.append(" ON DELETE CASCADE");
        }
        buffer.append(" CONSTRAINT ");
        buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
        if (fkConstraint.isInitiallyDeferred()) {
            buffer.append(" INITIALLY DEFERRED");
        }
        if (fkConstraint.isDeferrable()) {
            buffer.append(" DEFERRABLE");
        }
        buffer.append(",");
    }
    for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
        if (uniqueConstraint.getConstraintName() != null && !constraintNameAfterUnique(database)) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
        }
        buffer.append(" UNIQUE (");
        buffer.append(database.escapeColumnNameList(StringUtils.join(uniqueConstraint.getColumns(), ", ")));
        buffer.append(")");
        if (uniqueConstraint.getConstraintName() != null && constraintNameAfterUnique(database)) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
        }
        buffer.append(",");
    }
    String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";
    if (statement.getTablespace() != null && database.supportsTablespaces()) {
        sql += " IN " + statement.getTablespace();
    }
    return new Sql[] { new UnparsedSql(sql, new Table().setName(statement.getTableName()).setSchema(new Schema(statement.getCatalogName(), statement.getSchemaName()))) };
}
Also used : AutoIncrementConstraint(liquibase.statement.AutoIncrementConstraint) Table(liquibase.structure.core.Table) UnparsedSql(liquibase.sql.UnparsedSql) ForeignKeyConstraint(liquibase.statement.ForeignKeyConstraint) Schema(liquibase.structure.core.Schema) UniqueConstraint(liquibase.statement.UniqueConstraint) LinkedList(java.util.LinkedList) Sql(liquibase.sql.Sql) UnparsedSql(liquibase.sql.UnparsedSql)

Aggregations

LinkedList (java.util.LinkedList)2 Sql (liquibase.sql.Sql)2 UnparsedSql (liquibase.sql.UnparsedSql)2 AutoIncrementConstraint (liquibase.statement.AutoIncrementConstraint)2 ForeignKeyConstraint (liquibase.statement.ForeignKeyConstraint)2 UniqueConstraint (liquibase.statement.UniqueConstraint)2 BigInteger (java.math.BigInteger)1 ArrayList (java.util.ArrayList)1 DatabaseDataType (liquibase.datatype.DatabaseDataType)1 SequenceNextValueFunction (liquibase.statement.SequenceNextValueFunction)1 CreateTableStatement (liquibase.statement.core.CreateTableStatement)1 Schema (liquibase.structure.core.Schema)1 Table (liquibase.structure.core.Table)1