Search in sources :

Example 1 with InitializeDatabaseChangeLogLockTableStatement

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());
        }
    }
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) CreateDatabaseChangeLogLockTableStatement(liquibase.statement.core.CreateDatabaseChangeLogLockTableStatement) InitializeDatabaseChangeLogLockTableStatement(liquibase.statement.core.InitializeDatabaseChangeLogLockTableStatement) Field(java.lang.reflect.Field) Executor(liquibase.executor.Executor) DerbyDatabase(liquibase.database.core.DerbyDatabase) ExecutorService(liquibase.executor.ExecutorService) DatabaseException(liquibase.exception.DatabaseException) DropTableStatement(liquibase.statement.core.DropTableStatement)

Aggregations

Field (java.lang.reflect.Field)1 DerbyDatabase (liquibase.database.core.DerbyDatabase)1 DatabaseException (liquibase.exception.DatabaseException)1 Executor (liquibase.executor.Executor)1 ExecutorService (liquibase.executor.ExecutorService)1 CreateDatabaseChangeLogLockTableStatement (liquibase.statement.core.CreateDatabaseChangeLogLockTableStatement)1 DropTableStatement (liquibase.statement.core.DropTableStatement)1 InitializeDatabaseChangeLogLockTableStatement (liquibase.statement.core.InitializeDatabaseChangeLogLockTableStatement)1 RawSqlStatement (liquibase.statement.core.RawSqlStatement)1