use of liquibase.statement.core.InitializeDatabaseChangeLogLockTableStatement in project keycloak by keycloak.
the class CustomLockService method init.
@Override
public void init() throws DatabaseException {
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database);
if (!hasDatabaseChangeLogLockTable()) {
try {
if (log.isTraceEnabled()) {
log.trace("Create Database Lock Table");
}
executor.execute(new CreateDatabaseChangeLogLockTableStatement());
database.commit();
} catch (DatabaseException de) {
log.warn("Failed to create lock table. Maybe other transaction created in the meantime. Retrying...");
if (log.isTraceEnabled()) {
// Log details at trace level
log.trace(de.getMessage(), de);
}
database.rollback();
throw new LockRetryException(de);
}
log.debugf("Created database lock table with name: %s", database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()));
try {
Field field = Reflections.findDeclaredField(StandardLockService.class, "hasDatabaseChangeLogLockTable");
Reflections.setAccessible(field);
field.set(CustomLockService.this, true);
} catch (IllegalAccessException iae) {
throw new RuntimeException(iae);
}
}
try {
Set<Integer> currentIds = currentIdsInDatabaseChangeLogLockTable();
if (!currentIds.containsAll(Arrays.asList(DBLockProvider.Namespace.values()))) {
if (log.isTraceEnabled()) {
log.tracef("Initialize Database Lock Table, current locks %s", currentIds);
}
executor.execute(new CustomInitializeDatabaseChangeLogLockTableStatement(currentIds));
database.commit();
log.debug("Initialized record in the database lock table");
}
} catch (DatabaseException de) {
log.warn("Failed to insert first record to the lock table. Maybe other transaction inserted in the meantime. Retrying...");
if (log.isTraceEnabled()) {
// Log details at trace level
log.trace(de.getMessage(), de);
}
database.rollback();
throw new LockRetryException(de);
}
// Keycloak doesn't support Derby, but keep it for sure...
if (executor.updatesDatabase() && database instanceof DerbyDatabase && ((DerbyDatabase) 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());
}
}
}
Aggregations