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);
}