liquibase.executor.ExecutorService Java Examples

The following examples show how to use liquibase.executor.ExecutorService. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: QuarkusJpaUpdaterProvider.java    From keycloak with Apache License 2.0 6 votes vote down vote up
private void outputChangeLogTableCreationScript(Liquibase liquibase, final Writer exportWriter) throws DatabaseException {
    Database database = liquibase.getDatabase();

    Executor oldTemplate = ExecutorService.getInstance().getExecutor(database);
    LoggingExecutor executor = new LoggingExecutor(ExecutorService.getInstance().getExecutor(database), exportWriter, database);
    ExecutorService.getInstance().setExecutor(database, executor);

    executor.comment("*********************************************************************");
    executor.comment("* Keycloak database creation script - apply this script to empty DB *");
    executor.comment("*********************************************************************" + StreamUtil.getLineSeparator());

    executor.execute(new CreateDatabaseChangeLogTableStatement());
    // DatabaseChangeLogLockTable is created before this code is executed and recreated if it does not exist automatically
    // in org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService.init() called indirectly from
    // KeycloakApplication constructor (search for waitForLock() call). Hence it is not included in the creation script.

    executor.comment("*********************************************************************" + StreamUtil.getLineSeparator());

    ExecutorService.getInstance().setExecutor(database, oldTemplate);
}
 
Example #2
Source File: CustomLockService.java    From keycloak with Apache License 2.0 6 votes vote down vote up
private Set<Integer> currentIdsInDatabaseChangeLogLockTable() throws DatabaseException {
    try {
        Executor executor = ExecutorService.getInstance().getExecutor(database);
        String idColumnName = database.escapeColumnName(database.getLiquibaseCatalogName(),
                database.getLiquibaseSchemaName(),
                database.getDatabaseChangeLogLockTableName(),
                "ID");
        String lockTableName = database.escapeTableName(database.getLiquibaseCatalogName(),
                database.getLiquibaseSchemaName(),
                database.getDatabaseChangeLogLockTableName());
        SqlStatement sqlStatement = new RawSqlStatement("SELECT " + idColumnName + " FROM " + lockTableName);
        List<Map<String, ?>> rows = executor.queryForList(sqlStatement);
        Set<Integer> ids = rows.stream().map(columnMap -> ((Number) columnMap.get("ID")).intValue()).collect(Collectors.toSet());
        database.commit();
        return ids;
    } catch (UnexpectedLiquibaseException ulie) {
        // It can happen with MariaDB Galera 10.1 that UnexpectedLiquibaseException is rethrown due the DB lock.
        // It is sufficient to just rollback transaction and retry in that case.
        if (ulie.getCause() != null && ulie.getCause() instanceof DatabaseException) {
            throw (DatabaseException) ulie.getCause();
        } else {
            throw ulie;
        }
    }
}
 
Example #3
Source File: AbstractPerconaChangeTest.java    From liquibase-percona with Apache License 2.0 6 votes vote down vote up
@BeforeEach
public void setup() {
    System.setProperty(Configuration.LIQUIBASE_PASSWORD, "root");

    database = new MySQLDatabase();
    database.setLiquibaseSchemaName("testdb");
    DatabaseConnection conn = new MockDatabaseConnection("jdbc:mysql://user@localhost:3306/testdb",
            "user@localhost");
    database.setConnection(conn);
    JdbcExecutor executor = new JdbcExecutor();
    executor.setDatabase(database);
    ExecutorService.getInstance().setExecutor(database, executor);

    PTOnlineSchemaChangeStatement.available = true;
    PTOnlineSchemaChangeStatement.perconaToolkitVersion = null;
    System.setProperty(Configuration.FAIL_IF_NO_PT, "false");
    System.setProperty(Configuration.NO_ALTER_SQL_DRY_MODE, "false");
    System.setProperty(Configuration.SKIP_CHANGES, "");

    PerconaForeignKeyService.getInstance().disable();

    setupChange(change);
}
 
Example #4
Source File: AbstractJdbcDatabase.java    From jweb-cms with GNU Affero General Public License v3.0 6 votes vote down vote up
/**
 * Overwrite this method to get the default schema name for the connection.
 * If you only need to change the statement that obtains the current schema then override
 *
 * @see AbstractJdbcDatabase#getConnectionSchemaNameCallStatement()
 */
protected String getConnectionSchemaName() {
    if (connection == null) {
        return null;
    }
    if (connection instanceof OfflineConnection) {
        return ((OfflineConnection) connection).getSchema();
    }

    try {
        SqlStatement currentSchemaStatement = getConnectionSchemaNameCallStatement();
        return ExecutorService.getInstance().getExecutor(this).
            queryForObject(currentSchemaStatement, String.class);
    } catch (Exception e) {
        LogService.getLog(getClass()).info(LogType.LOG, "Error getting default schema", e);
    }
    return null;
}
 
Example #5
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 6 votes vote down vote up
@Override
    public void tag(final String tagString) throws DatabaseException {
        Database database = getDatabase();
        Executor executor = ExecutorService.getInstance().getExecutor(database);
        try {
            int totalRows = ExecutorService.getInstance().getExecutor(database).queryForInt(new SelectFromDatabaseChangeLogStatement(new ColumnConfig().setName("COUNT(*)", true)));
            if (totalRows == 0) {
                ChangeSet emptyChangeSet = new ChangeSet(String.valueOf(new Date().getTime()), "liquibase", false, false, "liquibase-internal", null, null, getDatabase().getObjectQuotingStrategy(), null);
                this.setExecType(emptyChangeSet, ChangeSet.ExecType.EXECUTED);
            }

//            Timestamp lastExecutedDate = (Timestamp) this.getExecutor().queryForObject(createChangeToTagSQL(), Timestamp.class);
            executor.execute(new TagDatabaseStatement(tagString));
            getDatabase().commit();

            if (this.ranChangeSetList != null) {
                ranChangeSetList.get(ranChangeSetList.size() - 1).setTag(tagString);
            }
        } catch (Exception e) {
            throw new DatabaseException(e);
        }
    }
 
Example #6
Source File: LiquibaseJpaUpdaterProvider.java    From keycloak with Apache License 2.0 6 votes vote down vote up
private void outputChangeLogTableCreationScript(Liquibase liquibase, final Writer exportWriter) throws DatabaseException {
    Database database = liquibase.getDatabase();

    Executor oldTemplate = ExecutorService.getInstance().getExecutor(database);
    LoggingExecutor executor = new LoggingExecutor(ExecutorService.getInstance().getExecutor(database), exportWriter, database);
    ExecutorService.getInstance().setExecutor(database, executor);

    executor.comment("*********************************************************************");
    executor.comment("* Keycloak database creation script - apply this script to empty DB *");
    executor.comment("*********************************************************************" + StreamUtil.getLineSeparator());

    executor.execute(new CreateDatabaseChangeLogTableStatement());
    // DatabaseChangeLogLockTable is created before this code is executed and recreated if it does not exist automatically
    // in org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService.init() called indirectly from
    // KeycloakApplication constructor (search for waitForLock() call). Hence it is not included in the creation script.

    executor.comment("*********************************************************************" + StreamUtil.getLineSeparator());

    ExecutorService.getInstance().setExecutor(database, oldTemplate);
}
 
Example #7
Source File: AbstractJdbcDatabase.java    From jweb-cms with GNU Affero General Public License v3.0 6 votes vote down vote up
@Override
public void execute(final SqlStatement[] statements, final List<SqlVisitor> sqlVisitors) throws LiquibaseException {
    for (SqlStatement statement : statements) {
        if (statement.skipOnUnsupported() && !SqlGeneratorFactory.getInstance().supports(statement, this)) {
            continue;
        }
        LogService.getLog(getClass()).debug(LogType.LOG, "Executing Statement: " + statement);
        try {
            ExecutorService.getInstance().getExecutor(this).execute(statement, sqlVisitors);
        } catch (DatabaseException e) {
            if (statement.continueOnError()) {
                LogService.getLog(getClass()).severe(LogType.LOG, "Error executing statement '" + statement.toString() + "', but continuing", e);
            } else {
                throw e;
            }
        }
    }
}
 
Example #8
Source File: AbstractJdbcDatabase.java    From jweb-cms with GNU Affero General Public License v3.0 6 votes vote down vote up
@Override
public void close() throws DatabaseException {
    ExecutorService.getInstance().clearExecutor(this);
    DatabaseConnection connection = getConnection();
    if (connection != null) {
        if (previousAutoCommit != null) {
            try {
                connection.setAutoCommit(previousAutoCommit);
            } catch (DatabaseException e) {
                LogService.getLog(getClass()).warning(LogType.LOG, "Failed to restore the auto commit to " + previousAutoCommit);

                throw e;
            }
        }
        connection.close();
    }
}
 
Example #9
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 5 votes vote down vote up
@Override
protected void replaceChecksum(ChangeSet changeSet) throws DatabaseException {
    ExecutorService.getInstance().getExecutor(getDatabase()).execute(new UpdateChangeSetChecksumStatement(changeSet));

    getDatabase().commit();
    reset();
}
 
Example #10
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 5 votes vote down vote up
@Override
public void setExecType(ChangeSet changeSet, ChangeSet.ExecType execType) throws DatabaseException {
    Database database = getDatabase();

    ExecutorService.getInstance().getExecutor(database).execute(new MarkChangeSetRanStatement(changeSet, execType));
    getDatabase().commit();
    if (this.ranChangeSetList != null) {
        this.ranChangeSetList.add(new RanChangeSet(changeSet, execType, null, null));
    }

}
 
Example #11
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 5 votes vote down vote up
@Override
public void removeFromHistory(final ChangeSet changeSet) throws DatabaseException {
    Database database = getDatabase();
    ExecutorService.getInstance().getExecutor(database).execute(new RemoveChangeSetRanStatusStatement(changeSet));
    getDatabase().commit();

    if (this.ranChangeSetList != null) {
        this.ranChangeSetList.remove(new RanChangeSet(changeSet));
    }
}
 
Example #12
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 5 votes vote down vote up
@Override
public int getNextSequenceValue() throws LiquibaseException {
    if (lastChangeSetSequenceValue == null) {
        if (getDatabase().getConnection() == null) {
            lastChangeSetSequenceValue = 0;
        } else {
            lastChangeSetSequenceValue = ExecutorService.getInstance().getExecutor(getDatabase()).queryForInt(new GetNextChangeSetSequenceValueStatement());
        }
    }

    return ++lastChangeSetSequenceValue;
}
 
Example #13
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 5 votes vote down vote up
@Override
public void clearAllCheckSums() throws LiquibaseException {
    Database database = getDatabase();
    UpdateStatement updateStatement = new UpdateStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName());
    updateStatement.addNewColumnValue("MD5SUM", null);
    ExecutorService.getInstance().getExecutor(database).execute(updateStatement);
    database.commit();
}
 
Example #14
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 5 votes vote down vote up
@Override
public void destroy() throws DatabaseException {
    Database database = getDatabase();
    try {
        if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(database.getDatabaseChangeLogTableName()).setSchema(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName()), database)) {
            ExecutorService.getInstance().getExecutor(database).execute(new DropTableStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName(), false));
        }
        reset();
    } catch (InvalidExampleException e) {
        throw new UnexpectedLiquibaseException(e);
    }
}
 
Example #15
Source File: PerconaChangeUtil.java    From liquibase-percona with Apache License 2.0 5 votes vote down vote up
/**
 * Determines whether *SQL (updateSQL/rollbackSQL) is executed or whether
 * the statements should be executed directly.
 * @param database the database
 * @return <code>true</code> if dry-run is enabled and the statements should *not* be executed.
 */
public static boolean isDryRun(Database database) {
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    if (executor instanceof LoggingExecutor) {
        return true;
    }
    return false;
}
 
Example #16
Source File: AbstractJdbcDatabase.java    From jweb-cms with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public String getViewDefinition(CatalogAndSchema schema, final String viewName) throws DatabaseException {
    schema = schema.customize(this);
    String definition = ExecutorService.getInstance().getExecutor(this).queryForObject(new GetViewDefinitionStatement(schema.getCatalogName(), schema.getSchemaName(), viewName), String.class);
    if (definition == null) {
        return null;
    }
    return CREATE_VIEW_AS_PATTERN.matcher(definition).replaceFirst("");
}
 
Example #17
Source File: PostgresPlusDatabase.java    From keycloak with Apache License 2.0 5 votes vote down vote up
@Override
protected String getConnectionSchemaName() {
    try {
        String currentSchema = ExecutorService.getInstance().getExecutor(this)
                .queryForObject(new RawSqlStatement("select current_schema"), String.class);
        return currentSchema;

    } catch (Exception e) {
        throw new RuntimeException("Failed to get current schema", e);
    }
}
 
Example #18
Source File: QuarkusJpaUpdaterProvider.java    From keycloak with Apache License 2.0 4 votes vote down vote up
protected void updateChangeSet(Liquibase liquibase, Writer exportWriter) throws LiquibaseException  {
    String changelog = liquibase.getChangeLogFile();
    Database database = liquibase.getDatabase();
    Table changelogTable = SnapshotGeneratorFactory.getInstance().getDatabaseChangeLogTable(new SnapshotControl(database, false, Table.class, Column.class), database);

    if (changelogTable != null) {
        boolean hasDeploymentIdColumn = changelogTable.getColumn(DEPLOYMENT_ID_COLUMN) != null;

        // create DEPLOYMENT_ID column if it doesn't exist
        if (!hasDeploymentIdColumn) {
            ChangeLogHistoryService changelogHistoryService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database);
            changelogHistoryService.generateDeploymentId();
            String deploymentId = changelogHistoryService.getDeploymentId();

            logger.debugv("Adding missing column {0}={1} to {2} table", DEPLOYMENT_ID_COLUMN, deploymentId,changelogTable.getName());

            List<SqlStatement> statementsToExecute = new ArrayList<>();
            statementsToExecute.add(new AddColumnStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(),
                    changelogTable.getName(), DEPLOYMENT_ID_COLUMN, "VARCHAR(10)", null));
            statementsToExecute.add(new UpdateStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), changelogTable.getName())
                    .addNewColumnValue(DEPLOYMENT_ID_COLUMN, deploymentId));
            statementsToExecute.add(new SetNullableStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(),
                    changelogTable.getName(), DEPLOYMENT_ID_COLUMN, "VARCHAR(10)", false));

            ExecutorService executorService = ExecutorService.getInstance();
            Executor executor = executorService.getExecutor(liquibase.getDatabase());

            for (SqlStatement sql : statementsToExecute) {
                executor.execute(sql);
                database.commit();
            }
        }
    }

    List<ChangeSet> changeSets = getLiquibaseUnrunChangeSets(liquibase);
    if (!changeSets.isEmpty()) {
        List<RanChangeSet> ranChangeSets = liquibase.getDatabase().getRanChangeSetList();
        if (ranChangeSets.isEmpty()) {
            logger.infov("Initializing database schema. Using changelog {0}", changelog);
        } else {
            if (logger.isDebugEnabled()) {
                logger.debugv("Updating database from {0} to {1}. Using changelog {2}", ranChangeSets.get(ranChangeSets.size() - 1).getId(), changeSets.get(changeSets.size() - 1).getId(), changelog);
            } else {
                logger.infov("Updating database. Using changelog {0}", changelog);
            }
        }

        if (exportWriter != null) {
            if (ranChangeSets.isEmpty()) {
                outputChangeLogTableCreationScript(liquibase, exportWriter);
            }
            liquibase.update((Contexts) null, new LabelExpression(), exportWriter, false);
        } else {
            liquibase.update((Contexts) null);
        }

        logger.debugv("Completed database update for changelog {0}", changelog);
    } else {
        logger.debugv("Database is up to date for changelog {0}", changelog);
    }

    // Needs to restart liquibase services to clear ChangeLogHistoryServiceFactory.getInstance().
    // See https://issues.jboss.org/browse/KEYCLOAK-3769 for discussion relevant to why reset needs to be here
    resetLiquibaseServices(liquibase);
}
 
Example #19
Source File: LiquibaseJpaUpdaterProvider.java    From keycloak with Apache License 2.0 4 votes vote down vote up
protected void updateChangeSet(Liquibase liquibase, Connection connection, Writer exportWriter) throws LiquibaseException, SQLException {
    String changelog = liquibase.getChangeLogFile();
    Database database = liquibase.getDatabase();
    Table changelogTable = SnapshotGeneratorFactory.getInstance().getDatabaseChangeLogTable(new SnapshotControl(database, false, Table.class, Column.class), database);

    if (changelogTable != null) {
        boolean hasDeploymentIdColumn = changelogTable.getColumn(DEPLOYMENT_ID_COLUMN) != null;

        // create DEPLOYMENT_ID column if it doesn't exist
        if (!hasDeploymentIdColumn) {
            ChangeLogHistoryService changelogHistoryService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database);
            changelogHistoryService.generateDeploymentId();
            String deploymentId = changelogHistoryService.getDeploymentId();

            logger.debugv("Adding missing column {0}={1} to {2} table", DEPLOYMENT_ID_COLUMN, deploymentId,changelogTable.getName());

            List<SqlStatement> statementsToExecute = new ArrayList<>();
            statementsToExecute.add(new AddColumnStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(),
                    changelogTable.getName(), DEPLOYMENT_ID_COLUMN, "VARCHAR(10)", null));
            statementsToExecute.add(new UpdateStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), changelogTable.getName())
                    .addNewColumnValue(DEPLOYMENT_ID_COLUMN, deploymentId));
            statementsToExecute.add(new SetNullableStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(),
                    changelogTable.getName(), DEPLOYMENT_ID_COLUMN, "VARCHAR(10)", false));

            ExecutorService executorService = ExecutorService.getInstance();
            Executor executor = executorService.getExecutor(liquibase.getDatabase());

            for (SqlStatement sql : statementsToExecute) {
                executor.execute(sql);
                database.commit();
            }
        }
    }

    List<ChangeSet> changeSets = getLiquibaseUnrunChangeSets(liquibase);
    if (!changeSets.isEmpty()) {
        List<RanChangeSet> ranChangeSets = liquibase.getDatabase().getRanChangeSetList();
        if (ranChangeSets.isEmpty()) {
            logger.infov("Initializing database schema. Using changelog {0}", changelog);
        } else {
            if (logger.isDebugEnabled()) {
                logger.debugv("Updating database from {0} to {1}. Using changelog {2}", ranChangeSets.get(ranChangeSets.size() - 1).getId(), changeSets.get(changeSets.size() - 1).getId(), changelog);
            } else {
                logger.infov("Updating database. Using changelog {0}", changelog);
            }
        }

        if (exportWriter != null) {
            if (ranChangeSets.isEmpty()) {
                outputChangeLogTableCreationScript(liquibase, exportWriter);
            }
            liquibase.update((Contexts) null, new LabelExpression(), exportWriter, false);
        } else {
            liquibase.update((Contexts) null);
        }

        logger.debugv("Completed database update for changelog {0}", changelog);
    } else {
        logger.debugv("Database is up to date for changelog {0}", changelog);
    }

    // Needs to restart liquibase services to clear ChangeLogHistoryServiceFactory.getInstance().
    // See https://issues.jboss.org/browse/KEYCLOAK-3769 for discussion relevant to why reset needs to be here
    resetLiquibaseServices(liquibase);
}
 
Example #20
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 4 votes vote down vote up
@Override
public boolean tagExists(final String tag) throws DatabaseException {
    int count = ExecutorService.getInstance().getExecutor(getDatabase()).queryForInt(new SelectFromDatabaseChangeLogStatement(new SelectFromDatabaseChangeLogStatement.ByTag(tag), new ColumnConfig().setName("COUNT(*)", true)));
    return count > 0;
}
 
Example #21
Source File: MSSQLDatabase.java    From liquibase-mssql with Apache License 2.0 4 votes vote down vote up
@Override
public void dropDatabaseObjects(CatalogAndSchema schemaToDrop) throws LiquibaseException {
    super.dropDatabaseObjects(schemaToDrop);
    ExecutorService.getInstance().getExecutor(this).execute(new DropStoredProcedureStatement(this.getLiquibaseCatalogName(), this.getLiquibaseSchemaName()));
}
 
Example #22
Source File: AbstractPerconaChangeTest.java    From liquibase-percona with Apache License 2.0 4 votes vote down vote up
protected void enableLogging() {
    ExecutorService.getInstance().setExecutor(database, new LoggingExecutor(null, new StringWriter(), database));
}
 
Example #23
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 4 votes vote down vote up
private List<Map<String, ?>> queryDatabaseChangeLogTable(Database database) throws DatabaseException {
    SelectFromDatabaseChangeLogStatement select = new SelectFromDatabaseChangeLogStatement(new ColumnConfig().setName("*").setComputed(true)).setOrderBy("DATEEXECUTED ASC", "ORDEREXECUTED ASC");
    return ExecutorService.getInstance().getExecutor(database).queryForList(select);
}
 
Example #24
Source File: HiveStandardChangeLogHistoryService.java    From liquibase-impala with Apache License 2.0 4 votes vote down vote up
@Override
public void init() throws DatabaseException {
    if (serviceInitialized) {
        return;
    }
    Database database = getDatabase();
    Executor executor = ExecutorService.getInstance().getExecutor(database);

    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<SqlStatement>();

    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 hasOrderExecuted = changeLogTable.getColumn("ORDEREXECUTED") != null;
        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, null));
        }
        if (!hasTag) {
            executor.comment("Adding missing databasechangelog.tag column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "TAG", charTypeName, null));
        }
        if (!hasComments) {
            executor.comment("Adding missing databasechangelog.comments column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "COMMENTS", charTypeName, null));
        }
        if (!hasLiquibase) {
            executor.comment("Adding missing databasechangelog.liquibase column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName, null));
        }
        if (!hasOrderExecuted) {
            executor.comment("Adding missing databasechangelog.orderexecuted column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", null));
        }
        if (!hasExecTypeColumn) {
            executor.comment("Adding missing databasechangelog.exectype column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName, null));
        }

        if (!hasContexts) {
            executor.comment("Adding missing databasechangelog.contexts column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName, null));
        }

        if (!hasLabels) {
            executor.comment("Adding missing databasechangelog.labels column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName, null));
        }

        if (!hasDeploymentIdColumn) {
            executor.comment("Adding missing databasechangelog.deployment_id column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DEPLOYMENT_ID", charTypeName, null));
        }
    } else {
        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);
        LOG.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 {
            LOG.info("Cannot run " + sql.getClass().getSimpleName() + " on " + getDatabase().getShortName() + " when checking databasechangelog table");
        }
    }
    serviceInitialized = true;
}
 
Example #25
Source File: AbstractJdbcDatabase.java    From jweb-cms with GNU Affero General Public License v3.0 4 votes vote down vote up
@Override
public void dropDatabaseObjects(final CatalogAndSchema schemaToDrop) throws LiquibaseException {
    ObjectQuotingStrategy currentStrategy = this.getObjectQuotingStrategy();
    this.setObjectQuotingStrategy(ObjectQuotingStrategy.QUOTE_ALL_OBJECTS);
    try {
        DatabaseSnapshot snapshot;
        try {
            final SnapshotControl snapshotControl = new SnapshotControl(this);
            final Set<Class<? extends DatabaseObject>> typesToInclude = snapshotControl.getTypesToInclude();

            //We do not need to remove indexes and primary/unique keys explicitly. They should be removed
            //as part of tables.
            typesToInclude.remove(Index.class);
            typesToInclude.remove(PrimaryKey.class);
            typesToInclude.remove(UniqueConstraint.class);

            if (supportsForeignKeyDisable()) {
                //We do not remove ForeignKey because they will be disabled and removed as parts of tables.
                typesToInclude.remove(ForeignKey.class);
            }

            final long createSnapshotStarted = System.currentTimeMillis();
            snapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(schemaToDrop, this, snapshotControl);
            LogService.getLog(getClass()).debug(LogType.LOG, String.format("Database snapshot generated in %d ms. Snapshot includes: %s", System.currentTimeMillis() - createSnapshotStarted, typesToInclude));
        } catch (LiquibaseException e) {
            throw new UnexpectedLiquibaseException(e);
        }

        final long changeSetStarted = System.currentTimeMillis();
        CompareControl compareControl = new CompareControl(
            new CompareControl.SchemaComparison[]{
                new CompareControl.SchemaComparison(
                    CatalogAndSchema.DEFAULT,
                    schemaToDrop)},
            snapshot.getSnapshotControl().getTypesToInclude());
        DiffResult diffResult = DiffGeneratorFactory.getInstance().compare(
            new EmptyDatabaseSnapshot(this),
            snapshot,
            compareControl);

        List<ChangeSet> changeSets = new DiffToChangeLog(diffResult, new DiffOutputControl(true, true, false, null).addIncludedSchema(schemaToDrop)).generateChangeSets();
        LogService.getLog(getClass()).debug(LogType.LOG, String.format("ChangeSet to Remove Database Objects generated in %d ms.", System.currentTimeMillis() - changeSetStarted));

        boolean previousAutoCommit = this.getAutoCommitMode();
        this.commit(); //clear out currently executed statements
        this.setAutoCommit(false); //some DDL doesn't work in autocommit mode
        final boolean reEnableFK = supportsForeignKeyDisable() && disableForeignKeyChecks();
        try {
            for (ChangeSet changeSet : changeSets) {
                changeSet.setFailOnError(false);
                for (Change change : changeSet.getChanges()) {
                    if (change instanceof DropTableChange) {
                        ((DropTableChange) change).setCascadeConstraints(true);
                    }
                    SqlStatement[] sqlStatements = change.generateStatements(this);
                    for (SqlStatement statement : sqlStatements) {
                        ExecutorService.getInstance().getExecutor(this).execute(statement);
                    }

                }
                this.commit();
            }
        } finally {
            if (reEnableFK) {
                enableForeignKeyChecks();
            }
        }

        ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this).destroy();
        LockServiceFactory.getInstance().getLockService(this).destroy();

        this.setAutoCommit(previousAutoCommit);
        LogService.getLog(getClass()).info(LogType.LOG, String.format("Successfully deleted all supported object types in schema %s.", schemaToDrop.toString()));
    } finally {
        this.setObjectQuotingStrategy(currentStrategy);
        this.commit();
    }
}