Search in sources :

Example 1 with Db2zDatabase

use of liquibase.database.core.Db2zDatabase in project liquibase by liquibase.

the class UnexpectedColumnChangeGenerator method fixUnexpected.

@Override
public Change[] fixUnexpected(DatabaseObject unexpectedObject, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) {
    Column column = (Column) unexpectedObject;
    if (BooleanUtil.isTrue(column.getComputed()) || BooleanUtil.isTrue(column.getDescending())) {
        // not really a column to drop, probably part of an index or something
        return null;
    }
    if (column.getRelation() instanceof View) {
        return null;
    }
    if (column.getRelation().getSnapshotId() == null) {
        // not an actual table, maybe an alias, maybe in a different schema. Don't fix it.
        return null;
    }
    if (comparisonDatabase instanceof Db2zDatabase) {
        // Db2 zOS column drop is handled by table change
        return null;
    }
    DropColumnChange change = new DropColumnChange();
    change.setTableName(column.getRelation().getName());
    if (control.getIncludeCatalog()) {
        change.setCatalogName(column.getRelation().getSchema().getCatalogName());
    }
    if (control.getIncludeSchema()) {
        change.setSchemaName(column.getRelation().getSchema().getName());
    }
    change.setColumnName(column.getName());
    return new Change[] { change };
}
Also used : DropColumnChange(liquibase.change.core.DropColumnChange) Db2zDatabase(liquibase.database.core.Db2zDatabase) DropColumnChange(liquibase.change.core.DropColumnChange) Change(liquibase.change.Change)

Example 2 with Db2zDatabase

use of liquibase.database.core.Db2zDatabase in project liquibase by liquibase.

the class InsertOrUpdateGeneratorDB2 method generateSql.

@Override
public Sql[] generateSql(InsertOrUpdateStatement insertOrUpdateStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    Sql[] sqls = super.generateSql(insertOrUpdateStatement, database, sqlGeneratorChain);
    if (database instanceof Db2zDatabase) {
        List<Sql> list = new ArrayList<>(Arrays.asList(sqls));
        list.add(new UnparsedSql("CALL " + DB2_Z_INSERT_OR_UPDATE_PROCEDURE + "()"));
        list.add(new UnparsedSql("DROP PROCEDURE " + DB2_Z_INSERT_OR_UPDATE_PROCEDURE));
        sqls = list.toArray(new Sql[list.size()]);
    }
    return sqls;
}
Also used : Db2zDatabase(liquibase.database.core.Db2zDatabase) UnparsedSql(liquibase.sql.UnparsedSql) ArrayList(java.util.ArrayList) UnparsedSql(liquibase.sql.UnparsedSql) Sql(liquibase.sql.Sql)

Example 3 with Db2zDatabase

use of liquibase.database.core.Db2zDatabase in project liquibase by liquibase.

the class CreateTableGenerator method generateSql.

@Override
public Sql[] generateSql(CreateTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    List<Sql> additionalSql = new ArrayList<>();
    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();
    BigInteger mysqlTableOptionStartWith = null;
    /* We have reached the point after "CREATE TABLE ... (" and will now iterate through the column list. */
    while (columnIterator.hasNext()) {
        String column = columnIterator.next();
        DatabaseDataType columnType = null;
        if (statement.getColumnTypes().get(column) != null) {
            columnType = statement.getColumnTypes().get(column).toDatabaseDataType(database);
        }
        if (columnType == null) {
            buffer.append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), column, false));
        } else {
            buffer.append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), column, !statement.isComputed(column)));
            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 ((database instanceof SQLiteDatabase) && isSinglePrimaryKeyColumn && isPrimaryKeyColumn && isAutoIncrementColumn) {
            String pkName = StringUtil.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 != null && !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) || (database instanceof PostgresDatabase)) && statement.getDefaultValue(column).toString().startsWith("GENERATED ALWAYS ")) {
                buffer.append(" ");
            } else if (database instanceof Db2zDatabase && statement.getDefaultValue(column).toString().contains("CURRENT TIMESTAMP") || statement.getDefaultValue(column).toString().contains("IDENTITY GENERATED BY DEFAULT")) {
                buffer.append(" ");
            } else {
                buffer.append(" DEFAULT ");
            }
            if (defaultValue instanceof DatabaseFunction) {
                buffer.append(database.generateDatabaseFunctionValue((DatabaseFunction) defaultValue));
            } else if (database instanceof Db2zDatabase) {
                if (statement.getDefaultValue(column).toString().contains("CURRENT TIMESTAMP")) {
                    buffer.append("");
                }
                if (statement.getDefaultValue(column).toString().contains("IDENTITY GENERATED BY DEFAULT")) {
                    buffer.append("GENERATED BY DEFAULT AS IDENTITY");
                }
                if (statement.getDefaultValue(column).toString().contains("CURRENT USER")) {
                    buffer.append("SESSION_USER ");
                }
                if (statement.getDefaultValue(column).toString().contains("CURRENT SQLID")) {
                    buffer.append("CURRENT SQLID ");
                }
            } else {
                buffer.append(statement.getColumnTypes().get(column).objectToSql(defaultValue, database));
            }
        }
        if (isAutoIncrementColumn) {
            if (database instanceof PostgresDatabase && buffer.toString().toLowerCase().endsWith("serial")) {
            // don't add more info
            } else if (database.supportsAutoIncrement()) {
                // TODO: check if database supports auto increment on non primary key column
                String autoIncrementClause = database.getAutoIncrementClause(autoIncrementConstraint.getStartWith(), autoIncrementConstraint.getIncrementBy(), autoIncrementConstraint.getGenerationType(), autoIncrementConstraint.getDefaultOnNull());
                if (!"".equals(autoIncrementClause)) {
                    buffer.append(" ").append(autoIncrementClause);
                }
                if (autoIncrementConstraint.getStartWith() != null) {
                    if (database instanceof PostgresDatabase) {
                        int majorVersion = 9;
                        try {
                            majorVersion = database.getDatabaseMajorVersion();
                        } catch (DatabaseException e) {
                        // ignore
                        }
                        if (majorVersion < 10) {
                            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 {
                Scope.getCurrentScope().getLog(getClass()).warning(database.getShortName() + " does not support autoincrement columns as requested for " + (database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())));
            }
        }
        // Do we have a NOT NULL constraint for this column?
        if (statement.getNotNullColumns().get(column) != null) {
            if (!database.supportsNotNullConstraintNames()) {
                buffer.append(" NOT NULL");
            } else {
                /* Determine if the NOT NULL constraint has a name. */
                NotNullConstraint nnConstraintForThisColumn = statement.getNotNullColumns().get(column);
                String nncName = StringUtil.trimToNull(nnConstraintForThisColumn.getConstraintName());
                if (nncName == null) {
                    buffer.append(" NOT NULL");
                } else {
                    buffer.append(" CONSTRAINT ");
                    buffer.append(database.escapeConstraintName(nncName));
                    buffer.append(" NOT NULL");
                }
                if (!nnConstraintForThisColumn.shouldValidateNullable()) {
                    if (database instanceof OracleDatabase) {
                        buffer.append(" ENABLE NOVALIDATE ");
                    }
                }
            }
        // does the DB support constraint names?
        } else {
            if (columnType != null && ((database instanceof SybaseDatabase) || (database instanceof SybaseASADatabase) || (database instanceof MySQLDatabase) || ((database instanceof MSSQLDatabase) && columnType.toString().toLowerCase().contains("timestamp")))) {
                buffer.append(" NULL");
            }
        // Do we need to specify NULL explicitly?
        }
        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)) {
        if ((statement.getPrimaryKeyConstraint() != null) && !statement.getPrimaryKeyConstraint().getColumns().isEmpty()) {
            if (database.supportsPrimaryKeyNames()) {
                String pkName = StringUtil.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(StringUtil.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(!statement.getPrimaryKeyConstraint().shouldValidatePrimaryKey() ? " ENABLE NOVALIDATE " : "");
            if (database.supportsInitiallyDeferrableColumns()) {
                if (statement.getPrimaryKeyConstraint().isInitiallyDeferred()) {
                    buffer.append(" INITIALLY DEFERRED");
                }
                if (statement.getPrimaryKeyConstraint().isDeferrable()) {
                    buffer.append(" DEFERRABLE");
                }
            }
            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");
        }
        if (database instanceof OracleDatabase) {
            buffer.append(!fkConstraint.shouldValidateForeignKey() ? " ENABLE NOVALIDATE " : "");
        }
        buffer.append(",");
    }
    /*
         * In the current syntax, UNIQUE constraints can only be set per column on table creation.
         * To alleviate this problem we combine the columns of unique constraints that have the same name.
         */
    LinkedHashMap<String, UniqueConstraint> namedUniqueConstraints = new LinkedHashMap<>();
    List<UniqueConstraint> unnamedUniqueConstraints = new LinkedList<>();
    for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
        if (uniqueConstraint.getConstraintName() == null) {
            // Only combine uniqueConstraints that have a name.
            unnamedUniqueConstraints.add(uniqueConstraint);
        } else {
            String constraintName = uniqueConstraint.getConstraintName();
            UniqueConstraint existingConstraint = namedUniqueConstraints.get(constraintName);
            if (existingConstraint != null) {
                if (uniqueConstraint.shouldValidateUnique()) {
                    // if validateUnique = true on only one column, make sure it is true
                    existingConstraint.setValidateUnique(true);
                }
                existingConstraint.getColumns().addAll(uniqueConstraint.getColumns());
            } else {
                // if we haven't seen the constraint before put it in the map.
                namedUniqueConstraints.put(constraintName, uniqueConstraint);
            }
        }
    }
    unnamedUniqueConstraints.addAll(namedUniqueConstraints.values());
    for (UniqueConstraint uniqueConstraint : unnamedUniqueConstraints) {
        if (uniqueConstraint.getConstraintName() != null) {
            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
        }
        buffer.append(" UNIQUE (");
        buffer.append(database.escapeColumnNameList(StringUtil.join(uniqueConstraint.getColumns(), ", ")));
        buffer.append(")");
        if (database instanceof OracleDatabase) {
            buffer.append(!uniqueConstraint.shouldValidateUnique() ? " ENABLE NOVALIDATE " : "");
        }
        buffer.append(",");
    }
    /*
         * Here, the list of columns and constraints in the form
         * ( column1, ..., columnN, constraint1, ..., constraintN,
         * ends. We cannot leave an expression like ", )", so we remove the last comma.
         */
    String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";
    if ((database instanceof MySQLDatabase) && (mysqlTableOptionStartWith != null)) {
        Scope.getCurrentScope().getLog(getClass()).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 AbstractDb2Database) || (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 : DatabaseFunction(liquibase.statement.DatabaseFunction) AbstractDb2Database(liquibase.database.core.AbstractDb2Database) ForeignKeyConstraint(liquibase.statement.ForeignKeyConstraint) Schema(liquibase.structure.core.Schema) UniqueConstraint(liquibase.statement.UniqueConstraint) InformixDatabase(liquibase.database.core.InformixDatabase) DatabaseDataType(liquibase.datatype.DatabaseDataType) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) NotNullConstraint(liquibase.statement.NotNullConstraint) AutoIncrementConstraint(liquibase.statement.AutoIncrementConstraint) UnparsedSql(liquibase.sql.UnparsedSql) MySQLDatabase(liquibase.database.core.MySQLDatabase) Sequence(liquibase.structure.core.Sequence) ForeignKey(liquibase.structure.core.ForeignKey) Sql(liquibase.sql.Sql) UnparsedSql(liquibase.sql.UnparsedSql) OracleDatabase(liquibase.database.core.OracleDatabase) SybaseASADatabase(liquibase.database.core.SybaseASADatabase) PostgresDatabase(liquibase.database.core.PostgresDatabase) SybaseDatabase(liquibase.database.core.SybaseDatabase) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) Db2zDatabase(liquibase.database.core.Db2zDatabase) BigInteger(java.math.BigInteger) DatabaseException(liquibase.exception.DatabaseException)

Example 4 with Db2zDatabase

use of liquibase.database.core.Db2zDatabase in project liquibase by liquibase.

the class AddLookupTableChange method generateStatements.

@Override
public SqlStatement[] generateStatements(Database database) {
    List<SqlStatement> statements = new ArrayList<>();
    String newTableCatalogName = getNewTableCatalogName();
    String newTableSchemaName = getNewTableSchemaName();
    String existingTableCatalogName = getExistingTableCatalogName();
    String existingTableSchemaName = getExistingTableSchemaName();
    SqlStatement[] createTablesSQL = { new RawSqlStatement("CREATE TABLE " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " AS SELECT DISTINCT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " AS " + database.escapeObjectName(getNewColumnName(), Column.class) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + " WHERE " + database.escapeObjectName(getExistingColumnName(), Column.class) + " IS NOT NULL") };
    if (database instanceof MSSQLDatabase) {
        createTablesSQL = new SqlStatement[] { new RawSqlStatement("SELECT DISTINCT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " AS " + database.escapeObjectName(getNewColumnName(), Column.class) + " INTO " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + " WHERE " + database.escapeObjectName(getExistingColumnName(), Column.class) + " IS NOT NULL") };
    } else if (database instanceof SybaseASADatabase) {
        createTablesSQL = new SqlStatement[] { new RawSqlStatement("SELECT DISTINCT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " AS " + database.escapeObjectName(getNewColumnName(), Column.class) + " INTO " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + " WHERE " + database.escapeObjectName(getExistingColumnName(), Column.class) + " IS NOT NULL") };
    } else if (database instanceof Db2zDatabase) {
        CreateTableStatement tableStatement = new CreateTableStatement(newTableCatalogName, newTableSchemaName, getNewTableName());
        if (getNewColumnName() != null) {
            tableStatement.addColumn(getNewColumnName(), DataTypeFactory.getInstance().fromDescription(getNewColumnDataType(), database));
            tableStatement.addColumnConstraint(new NotNullConstraint(getNewColumnName()));
        }
        createTablesSQL = new SqlStatement[] { tableStatement, new RawSqlStatement("INSERT INTO " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " SELECT DISTINCT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + " WHERE " + database.escapeObjectName(getExistingColumnName(), Column.class) + " IS NOT NULL") };
    } else if (database instanceof DB2Database) {
        createTablesSQL = new SqlStatement[] { new RawSqlStatement("CREATE TABLE " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " AS (SELECT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " AS " + database.escapeObjectName(getNewColumnName(), Column.class) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + ") WITH NO DATA"), new RawSqlStatement("INSERT INTO " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " SELECT DISTINCT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + " WHERE " + database.escapeObjectName(getExistingColumnName(), Column.class) + " IS NOT NULL") };
    } else if (database instanceof InformixDatabase) {
        createTablesSQL = new SqlStatement[] { new RawSqlStatement("CREATE TABLE " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " ( " + database.escapeObjectName(getNewColumnName(), Column.class) + " " + getNewColumnDataType() + " )"), new RawSqlStatement("INSERT INTO " + database.escapeTableName(newTableCatalogName, newTableSchemaName, getNewTableName()) + " ( " + database.escapeObjectName(getNewColumnName(), Column.class) + " ) SELECT DISTINCT " + database.escapeObjectName(getExistingColumnName(), Column.class) + " FROM " + database.escapeTableName(existingTableCatalogName, existingTableSchemaName, getExistingTableName()) + " WHERE " + database.escapeObjectName(getExistingColumnName(), Column.class) + " IS NOT NULL") };
    }
    statements.addAll(Arrays.asList(createTablesSQL));
    if (!(database instanceof OracleDatabase) && !(database instanceof Db2zDatabase)) {
        AddNotNullConstraintChange addNotNullChange = new AddNotNullConstraintChange();
        addNotNullChange.setSchemaName(newTableSchemaName);
        addNotNullChange.setTableName(getNewTableName());
        addNotNullChange.setColumnName(getNewColumnName());
        addNotNullChange.setColumnDataType(getNewColumnDataType());
        statements.addAll(Arrays.asList(addNotNullChange.generateStatements(database)));
    }
    if (database instanceof DB2Database) {
        statements.add(new ReorganizeTableStatement(newTableCatalogName, newTableSchemaName, getNewTableName()));
    }
    AddPrimaryKeyChange addPKChange = new AddPrimaryKeyChange();
    addPKChange.setSchemaName(newTableSchemaName);
    addPKChange.setTableName(getNewTableName());
    addPKChange.setColumnNames(getNewColumnName());
    statements.addAll(Arrays.asList(addPKChange.generateStatements(database)));
    if (database instanceof DB2Database) {
        statements.add(new ReorganizeTableStatement(newTableCatalogName, newTableSchemaName, getNewTableName()));
    }
    AddForeignKeyConstraintChange addFKChange = new AddForeignKeyConstraintChange();
    addFKChange.setBaseTableSchemaName(existingTableSchemaName);
    addFKChange.setBaseTableName(getExistingTableName());
    addFKChange.setBaseColumnNames(getExistingColumnName());
    addFKChange.setReferencedTableSchemaName(newTableSchemaName);
    addFKChange.setReferencedTableName(getNewTableName());
    addFKChange.setReferencedColumnNames(getNewColumnName());
    addFKChange.setConstraintName(getFinalConstraintName());
    statements.addAll(Arrays.asList(addFKChange.generateStatements(database)));
    return statements.toArray(new SqlStatement[statements.size()]);
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) DB2Database(liquibase.database.core.DB2Database) ReorganizeTableStatement(liquibase.statement.core.ReorganizeTableStatement) CreateTableStatement(liquibase.statement.core.CreateTableStatement) ArrayList(java.util.ArrayList) SybaseASADatabase(liquibase.database.core.SybaseASADatabase) OracleDatabase(liquibase.database.core.OracleDatabase) RawSqlStatement(liquibase.statement.core.RawSqlStatement) SqlStatement(liquibase.statement.SqlStatement) InformixDatabase(liquibase.database.core.InformixDatabase) Column(liquibase.structure.core.Column) Db2zDatabase(liquibase.database.core.Db2zDatabase) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) NotNullConstraint(liquibase.statement.NotNullConstraint)

Example 5 with Db2zDatabase

use of liquibase.database.core.Db2zDatabase in project liquibase by liquibase.

the class ForeignKeySnapshotGenerator method snapshotObject.

@Override
protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException {
    Database database = snapshot.getDatabase();
    List<CachedRow> importedKeyMetadataResultSet;
    try {
        Table fkTable = ((ForeignKey) example).getForeignKeyTable();
        String searchCatalog = ((AbstractJdbcDatabase) database).getJdbcCatalogName(fkTable.getSchema());
        String searchSchema = ((AbstractJdbcDatabase) database).getJdbcSchemaName(fkTable.getSchema());
        String searchTableName = database.correctObjectName(fkTable.getName(), Table.class);
        importedKeyMetadataResultSet = ((JdbcDatabaseSnapshot) snapshot).getMetaDataFromCache().getForeignKeys(searchCatalog, searchSchema, searchTableName, example.getName());
        ForeignKey foreignKey = null;
        for (CachedRow row : importedKeyMetadataResultSet) {
            String fk_name = cleanNameFromDatabase(row.getString("FK_NAME"), database);
            if (snapshot.getDatabase().isCaseSensitive()) {
                if (!fk_name.equals(example.getName())) {
                    continue;
                } else if (!fk_name.equalsIgnoreCase(example.getName())) {
                    continue;
                }
            }
            if (foreignKey == null) {
                foreignKey = new ForeignKey();
            }
            foreignKey.setName(fk_name);
            String fkTableCatalog = cleanNameFromDatabase(row.getString(METADATA_FKTABLE_CAT), database);
            String fkTableSchema = cleanNameFromDatabase(row.getString(METADATA_FKTABLE_SCHEM), database);
            String fkTableName = cleanNameFromDatabase(row.getString(METADATA_FKTABLE_NAME), database);
            Table foreignKeyTable = new Table().setName(fkTableName);
            foreignKeyTable.setSchema(new Schema(new Catalog(fkTableCatalog), fkTableSchema));
            foreignKey.setForeignKeyTable(foreignKeyTable);
            Column fkColumn = new Column(cleanNameFromDatabase(row.getString(METADATA_FKCOLUMN_NAME), database)).setRelation(foreignKeyTable);
            boolean alreadyAdded = false;
            for (Column existing : foreignKey.getForeignKeyColumns()) {
                if (DatabaseObjectComparatorFactory.getInstance().isSameObject(existing, fkColumn, snapshot.getSchemaComparisons(), database)) {
                    // already added. One is probably an alias
                    alreadyAdded = true;
                }
            }
            if (alreadyAdded) {
                break;
            }
            CatalogAndSchema pkTableSchema = ((AbstractJdbcDatabase) database).getSchemaFromJdbcInfo(row.getString(METADATA_PKTABLE_CAT), row.getString(METADATA_PKTABLE_SCHEM));
            Table tempPkTable = (Table) new Table().setName(row.getString(METADATA_PKTABLE_NAME)).setSchema(new Schema(pkTableSchema.getCatalogName(), pkTableSchema.getSchemaName()));
            foreignKey.setPrimaryKeyTable(tempPkTable);
            Column pkColumn = new Column(cleanNameFromDatabase(row.getString(METADATA_PKCOLUMN_NAME), database)).setRelation(tempPkTable);
            foreignKey.addForeignKeyColumn(fkColumn);
            foreignKey.addPrimaryKeyColumn(pkColumn);
            // DB2 on z/OS doesn't support ON UPDATE
            if (!(database instanceof Db2zDatabase)) {
                ForeignKeyConstraintType updateRule = convertToForeignKeyConstraintType(row.getInt(METADATA_UPDATE_RULE), database);
                foreignKey.setUpdateRule(updateRule);
            }
            ForeignKeyConstraintType deleteRule = convertToForeignKeyConstraintType(row.getInt(METADATA_DELETE_RULE), database);
            foreignKey.setDeleteRule(deleteRule);
            short deferrability = row.getShort(METADATA_DEFERRABILITY);
            // it should be set to DatabaseMetaData.importedKeyNotDeferrable(7)
            if ((deferrability == 0) || (deferrability == DatabaseMetaData.importedKeyNotDeferrable)) {
                foreignKey.setDeferrable(false);
                foreignKey.setInitiallyDeferred(false);
            } else if (deferrability == DatabaseMetaData.importedKeyInitiallyDeferred) {
                foreignKey.setDeferrable(true);
                foreignKey.setInitiallyDeferred(true);
            } else if (deferrability == DatabaseMetaData.importedKeyInitiallyImmediate) {
                foreignKey.setDeferrable(true);
                foreignKey.setInitiallyDeferred(false);
            } else {
                throw new RuntimeException("Unknown deferrability result: " + deferrability);
            }
            setValidateOptionIfAvailable(database, foreignKey, row);
            Index exampleIndex = new Index().setRelation(foreignKey.getForeignKeyTable());
            exampleIndex.getColumns().addAll(foreignKey.getForeignKeyColumns());
            exampleIndex.addAssociatedWith(Index.MARK_FOREIGN_KEY);
            foreignKey.setBackingIndex(exampleIndex);
        }
        if (snapshot.get(ForeignKey.class).contains(foreignKey)) {
            return null;
        }
        return foreignKey;
    } catch (Exception e) {
        throw new DatabaseException(e);
    }
}
Also used : CachedRow(liquibase.snapshot.CachedRow) CatalogAndSchema(liquibase.CatalogAndSchema) CatalogAndSchema(liquibase.CatalogAndSchema) AbstractJdbcDatabase(liquibase.database.AbstractJdbcDatabase) InvalidExampleException(liquibase.snapshot.InvalidExampleException) DatabaseException(liquibase.exception.DatabaseException) SQLException(java.sql.SQLException) Db2zDatabase(liquibase.database.core.Db2zDatabase) DB2Database(liquibase.database.core.DB2Database) Db2zDatabase(liquibase.database.core.Db2zDatabase) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) OracleDatabase(liquibase.database.core.OracleDatabase) Database(liquibase.database.Database) MariaDBDatabase(liquibase.database.core.MariaDBDatabase) MySQLDatabase(liquibase.database.core.MySQLDatabase) AbstractJdbcDatabase(liquibase.database.AbstractJdbcDatabase) JdbcDatabaseSnapshot(liquibase.snapshot.JdbcDatabaseSnapshot) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

Db2zDatabase (liquibase.database.core.Db2zDatabase)6 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)3 OracleDatabase (liquibase.database.core.OracleDatabase)3 Sql (liquibase.sql.Sql)3 ArrayList (java.util.ArrayList)2 Change (liquibase.change.Change)2 Database (liquibase.database.Database)2 DB2Database (liquibase.database.core.DB2Database)2 InformixDatabase (liquibase.database.core.InformixDatabase)2 MySQLDatabase (liquibase.database.core.MySQLDatabase)2 SybaseASADatabase (liquibase.database.core.SybaseASADatabase)2 DatabaseException (liquibase.exception.DatabaseException)2 UnparsedSql (liquibase.sql.UnparsedSql)2 NotNullConstraint (liquibase.statement.NotNullConstraint)2 SqlStatement (liquibase.statement.SqlStatement)2 IOException (java.io.IOException)1 BigInteger (java.math.BigInteger)1 SQLException (java.sql.SQLException)1 CatalogAndSchema (liquibase.CatalogAndSchema)1 ChangeFactory (liquibase.change.ChangeFactory)1