Search in sources :

Example 11 with DB2Database

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

the class StandardLockService method init.

@Override
public void init() throws DatabaseException {
    boolean createdTable = false;
    Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
    int maxIterations = 10;
    if (executor instanceof LoggingExecutor) {
        // can't / don't have to re-check
        if (hasDatabaseChangeLogLockTable()) {
            maxIterations = 0;
        } else {
            maxIterations = 1;
        }
    }
    for (int i = 0; i < maxIterations; i++) {
        try {
            if (!hasDatabaseChangeLogLockTable(true)) {
                executor.comment("Create Database Lock Table");
                executor.execute(new CreateDatabaseChangeLogLockTableStatement());
                database.commit();
                Scope.getCurrentScope().getLog(getClass()).fine("Created database lock table with name: " + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()));
                this.hasDatabaseChangeLogLockTable = true;
                createdTable = true;
                hasDatabaseChangeLogLockTable = true;
            }
            if (!isDatabaseChangeLogLockTableInitialized(createdTable, true)) {
                executor.comment("Initialize Database Lock Table");
                executor.execute(new InitializeDatabaseChangeLogLockTableStatement());
                database.commit();
            }
            if (executor.updatesDatabase() && (database instanceof DerbyDatabase) && ((DerbyDatabase) database).supportsBooleanDataType() || database.getClass().isAssignableFrom(DB2Database.class) && ((DB2Database) database).supportsBooleanDataType()) {
                // check if the changelog table is of an old smallint vs. boolean format
                String lockTable = database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName());
                Object obj = executor.queryForObject(new RawSqlStatement("SELECT MIN(locked) AS test FROM " + lockTable + " FETCH FIRST ROW ONLY"), Object.class);
                if (!(obj instanceof Boolean)) {
                    // wrong type, need to recreate table
                    executor.execute(new DropTableStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName(), false));
                    executor.execute(new CreateDatabaseChangeLogLockTableStatement());
                    executor.execute(new InitializeDatabaseChangeLogLockTableStatement());
                }
            }
        } catch (Exception e) {
            if (i == maxIterations - 1) {
                throw e;
            } else {
                Scope.getCurrentScope().getLog(getClass()).fine("Failed to create or initialize the lock table, trying again, iteration " + (i + 1) + " of " + maxIterations, e);
                // If another node already created the table, then we need to rollback this current transaction,
                // otherwise servers like Postgres will not allow continued use of the same connection, failing with
                // a message like "current transaction is aborted, commands ignored until end of transaction block"
                database.rollback();
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException ex) {
                    Scope.getCurrentScope().getLog(getClass()).warning("Lock table retry loop thread sleep interrupted", ex);
                }
            }
        }
    }
}
Also used : DB2Database(liquibase.database.core.DB2Database) LockException(liquibase.exception.LockException) SQLException(java.sql.SQLException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) InvalidExampleException(liquibase.snapshot.InvalidExampleException) DatabaseException(liquibase.exception.DatabaseException) LiquibaseException(liquibase.exception.LiquibaseException) Executor(liquibase.executor.Executor) LoggingExecutor(liquibase.executor.LoggingExecutor) LoggingExecutor(liquibase.executor.LoggingExecutor) DerbyDatabase(liquibase.database.core.DerbyDatabase) ExecutorService(liquibase.executor.ExecutorService) DatabaseObject(liquibase.structure.DatabaseObject)

Example 12 with DB2Database

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

the class StandardChangeLogHistoryService method init.

public void init() throws DatabaseException {
    if (serviceInitialized) {
        return;
    }
    Database database = getDatabase();
    Table changeLogTable = null;
    try {
        changeLogTable = SnapshotGeneratorFactory.getInstance().getDatabaseChangeLogTable(new SnapshotControl(database, false, Table.class, Column.class), database);
    } catch (LiquibaseException e) {
        throw new UnexpectedLiquibaseException(e);
    }
    List<SqlStatement> statementsToExecute = new ArrayList<>();
    boolean changeLogCreateAttempted = false;
    Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
    if (changeLogTable != null) {
        boolean hasDescription = changeLogTable.getColumn("DESCRIPTION") != null;
        boolean hasComments = changeLogTable.getColumn("COMMENTS") != null;
        boolean hasTag = changeLogTable.getColumn("TAG") != null;
        boolean hasLiquibase = changeLogTable.getColumn("LIQUIBASE") != null;
        boolean hasContexts = changeLogTable.getColumn("CONTEXTS") != null;
        boolean hasLabels = changeLogTable.getColumn("LABELS") != null;
        boolean liquibaseColumnNotRightSize = false;
        if (!(this.getDatabase() instanceof SQLiteDatabase)) {
            DataType type = changeLogTable.getColumn("LIQUIBASE").getType();
            if (type.getTypeName().toLowerCase().startsWith("varchar")) {
                Integer columnSize = type.getColumnSize();
                liquibaseColumnNotRightSize = (columnSize != null) && (columnSize < 20);
            } else {
                liquibaseColumnNotRightSize = false;
            }
        }
        boolean hasOrderExecuted = changeLogTable.getColumn("ORDEREXECUTED") != null;
        boolean checksumNotRightSize = false;
        if (!(this.getDatabase() instanceof SQLiteDatabase)) {
            DataType type = changeLogTable.getColumn("MD5SUM").getType();
            if (type.getTypeName().toLowerCase().startsWith("varchar") || type.getTypeName().toLowerCase().startsWith("character varying")) {
                Integer columnSize = type.getColumnSize();
                checksumNotRightSize = (columnSize != null) && (columnSize < 35);
            } else {
                liquibaseColumnNotRightSize = false;
            }
        }
        boolean hasExecTypeColumn = changeLogTable.getColumn("EXECTYPE") != null;
        String charTypeName = getCharTypeName();
        boolean hasDeploymentIdColumn = changeLogTable.getColumn("DEPLOYMENT_ID") != null;
        if (!hasDescription) {
            executor.comment("Adding missing databasechangelog.description column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DESCRIPTION", charTypeName + "(255)", null));
        }
        if (!hasTag) {
            executor.comment("Adding missing databasechangelog.tag column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "TAG", charTypeName + "(255)", null));
        }
        if (!hasComments) {
            executor.comment("Adding missing databasechangelog.comments column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "COMMENTS", charTypeName + "(255)", null));
        }
        if (!hasLiquibase) {
            executor.comment("Adding missing databasechangelog.liquibase column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName + "(20)", null));
        }
        if (!hasOrderExecuted) {
            executor.comment("Adding missing databasechangelog.orderexecuted column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", null));
            statementsToExecute.add(new UpdateStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()).addNewColumnValue("ORDEREXECUTED", -1));
            statementsToExecute.add(new SetNullableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", false));
        }
        if (checksumNotRightSize) {
            executor.comment("Modifying size of databasechangelog.md5sum column");
            statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "MD5SUM", charTypeName + "(35)"));
        }
        if (liquibaseColumnNotRightSize) {
            executor.comment("Modifying size of databasechangelog.liquibase column");
            statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName + "(20)"));
        }
        if (!hasExecTypeColumn) {
            executor.comment("Adding missing databasechangelog.exectype column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName + "(10)", null));
            statementsToExecute.add(new UpdateStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()).addNewColumnValue("EXECTYPE", "EXECUTED"));
            statementsToExecute.add(new SetNullableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName + "(10)", false));
        }
        if (hasContexts) {
            Integer columnSize = changeLogTable.getColumn("CONTEXTS").getType().getColumnSize();
            if ((columnSize != null) && (columnSize < Integer.parseInt(getContextsSize()))) {
                executor.comment("Modifying size of databasechangelog.contexts column");
                statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName + "(" + getContextsSize() + ")"));
            }
        } else {
            executor.comment("Adding missing databasechangelog.contexts column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName + "(" + getContextsSize() + ")", null));
        }
        if (hasLabels) {
            Integer columnSize = changeLogTable.getColumn("LABELS").getType().getColumnSize();
            if ((columnSize != null) && (columnSize < Integer.parseInt(getLabelsSize()))) {
                executor.comment("Modifying size of databasechangelog.labels column");
                statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName + "(" + getLabelsSize() + ")"));
            }
        } else {
            executor.comment("Adding missing databasechangelog.labels column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName + "(" + getLabelsSize() + ")", null));
        }
        if (!hasDeploymentIdColumn) {
            executor.comment("Adding missing databasechangelog.deployment_id column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DEPLOYMENT_ID", "VARCHAR(10)", null));
            if (database instanceof DB2Database) {
                statementsToExecute.add(new ReorganizeTableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()));
            }
        }
        List<Map<String, ?>> md5sumRS = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database).queryForList(new SelectFromDatabaseChangeLogStatement(new SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum(), new ColumnConfig().setName("MD5SUM")).setLimit(1));
        if (!md5sumRS.isEmpty()) {
            String md5sum = md5sumRS.get(0).get("MD5SUM").toString();
            if (!md5sum.startsWith(CheckSum.getCurrentVersion() + ":")) {
                executor.comment("DatabaseChangeLog checksums are an incompatible version.  Setting them to null " + "so they will be updated on next database update");
                databaseChecksumsCompatible = false;
                UpdateStatement updateStatement = new UpdateStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()).addNewColumnValue("MD5SUM", null);
                statementsToExecute.add(updateStatement);
            }
        }
    } else if (!changeLogCreateAttempted) {
        executor.comment("Create Database Change Log Table");
        SqlStatement createTableStatement = new CreateDatabaseChangeLogTableStatement();
        if (!canCreateChangeLogTable()) {
            throw new DatabaseException("Cannot create " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " table for your getDatabase()" + ".\n\n" + "Please construct it manually using the following SQL as a base and re-run Liquibase:\n\n" + createTableStatement);
        }
        // If there is no table in the database for recording change history create one.
        statementsToExecute.add(createTableStatement);
        Scope.getCurrentScope().getLog(getClass()).info("Creating database history table with name: " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()));
    }
    for (SqlStatement sql : statementsToExecute) {
        if (SqlGeneratorFactory.getInstance().supports(sql, database)) {
            executor.execute(sql);
            getDatabase().commit();
        } else {
            Scope.getCurrentScope().getLog(getClass()).info("Cannot run " + sql.getClass().getSimpleName() + " on" + " " + getDatabase().getShortName() + " when checking databasechangelog table");
        }
    }
    serviceInitialized = true;
}
Also used : DB2Database(liquibase.database.core.DB2Database) ColumnConfig(liquibase.change.ColumnConfig) SqlStatement(liquibase.statement.SqlStatement) Executor(liquibase.executor.Executor) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DB2Database(liquibase.database.core.DB2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Database(liquibase.database.Database) DataType(liquibase.structure.core.DataType) SnapshotControl(liquibase.snapshot.SnapshotControl) Table(liquibase.structure.core.Table) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) ExecutorService(liquibase.executor.ExecutorService) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) LiquibaseException(liquibase.exception.LiquibaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

DB2Database (liquibase.database.core.DB2Database)12 SqlStatement (liquibase.statement.SqlStatement)9 ReorganizeTableStatement (liquibase.statement.core.ReorganizeTableStatement)8 ArrayList (java.util.ArrayList)6 SQLiteDatabase (liquibase.database.core.SQLiteDatabase)5 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)3 DatabaseException (liquibase.exception.DatabaseException)3 Executor (liquibase.executor.Executor)3 DropColumnStatement (liquibase.statement.core.DropColumnStatement)3 SQLException (java.sql.SQLException)2 OracleDatabase (liquibase.database.core.OracleDatabase)2 LiquibaseException (liquibase.exception.LiquibaseException)2 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)2 ExecutorService (liquibase.executor.ExecutorService)2 RawSqlStatement (liquibase.statement.core.RawSqlStatement)2 Column (liquibase.structure.core.Column)2 ColumnConfig (liquibase.change.ColumnConfig)1 AddColumnChange (liquibase.change.core.AddColumnChange)1 Database (liquibase.database.Database)1 Db2zDatabase (liquibase.database.core.Db2zDatabase)1