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