Java源码示例:liquibase.executor.ExecutorService

示例1
/**
 * 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;
}
 
示例2
@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();
    }
}
 
示例3
@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;
            }
        }
    }
}
 
示例4
@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);
        }
    }
 
示例5
@BeforeEach
public void setup() {
    System.setProperty(Configuration.LIQUIBASE_PASSWORD, "root");

    database = new MySQLDatabase();
    database.setLiquibaseSchemaName("testdb");
    DatabaseConnection conn = new MockDatabaseConnection("jdbc:mysql://[email protected]:3306/testdb",
            "[email protected]");
    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);
}
 
示例6
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;
        }
    }
}
 
示例7
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);
}
 
示例8
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);
}
 
示例9
@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("");
}
 
示例10
@Override
protected void replaceChecksum(ChangeSet changeSet) throws DatabaseException {
    ExecutorService.getInstance().getExecutor(getDatabase()).execute(new UpdateChangeSetChecksumStatement(changeSet));

    getDatabase().commit();
    reset();
}
 
示例11
@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));
    }

}
 
示例12
@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));
    }
}
 
示例13
@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;
}
 
示例14
@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();
}
 
示例15
@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);
    }
}
 
示例16
/**
 * 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;
}
 
示例17
@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);
    }
}
 
示例18
@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();
    }
}
 
示例19
@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;
}
 
示例20
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);
}
 
示例21
@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;
}
 
示例22
protected void enableLogging() {
    ExecutorService.getInstance().setExecutor(database, new LoggingExecutor(null, new StringWriter(), database));
}
 
示例23
@Override
public void dropDatabaseObjects(CatalogAndSchema schemaToDrop) throws LiquibaseException {
    super.dropDatabaseObjects(schemaToDrop);
    ExecutorService.getInstance().getExecutor(this).execute(new DropStoredProcedureStatement(this.getLiquibaseCatalogName(), this.getLiquibaseSchemaName()));
}
 
示例24
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);
}
 
示例25
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);
}