Search in sources :

Example 21 with LoggingExecutor

use of liquibase.executor.LoggingExecutor 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);
                }
            }
        }
    }
}
Also used : DB2Database(liquibase.database.core.DB2Database) LockException(liquibase.exception.LockException) SQLException(java.sql.SQLException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) InvalidExampleException(liquibase.snapshot.InvalidExampleException) DatabaseException(liquibase.exception.DatabaseException) LiquibaseException(liquibase.exception.LiquibaseException) Executor(liquibase.executor.Executor) LoggingExecutor(liquibase.executor.LoggingExecutor) LoggingExecutor(liquibase.executor.LoggingExecutor) DerbyDatabase(liquibase.database.core.DerbyDatabase) ExecutorService(liquibase.executor.ExecutorService) DatabaseObject(liquibase.structure.DatabaseObject)

Example 22 with LoggingExecutor

use of liquibase.executor.LoggingExecutor in project liquibase by liquibase.

the class ChangeSet method setupCustomExecutorIfNecessary.

// 
// Get the custom Executor ready if necessary
// We do not do anything if we have a LoggingExecutor.
// 
private Executor setupCustomExecutorIfNecessary(Database database) {
    Executor originalExecutor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
    if (getRunWith() == null || originalExecutor instanceof LoggingExecutor) {
        return originalExecutor;
    }
    String executorName = ChangeSet.lookupExecutor(getRunWith());
    Executor customExecutor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(executorName, database);
    Scope.getCurrentScope().getSingleton(ExecutorService.class).setExecutor("jdbc", database, customExecutor);
    List<Change> changes = getChanges();
    for (Change change : changes) {
        if (!(change instanceof AbstractChange)) {
            continue;
        }
        final ResourceAccessor resourceAccessor = ((AbstractChange) change).getResourceAccessor();
        if (resourceAccessor != null) {
            customExecutor.setResourceAccessor(resourceAccessor);
            break;
        }
    }
    return originalExecutor;
}
Also used : ResourceAccessor(liquibase.resource.ResourceAccessor) Executor(liquibase.executor.Executor) LoggingExecutor(liquibase.executor.LoggingExecutor) LoggingExecutor(liquibase.executor.LoggingExecutor) ExecutorService(liquibase.executor.ExecutorService) EmptyChange(liquibase.change.core.EmptyChange) RawSQLChange(liquibase.change.core.RawSQLChange)

Example 23 with LoggingExecutor

use of liquibase.executor.LoggingExecutor in project keycloak by keycloak.

the class CustomCreateIndexChange method generateStatements.

@Override
public SqlStatement[] generateStatements(Database database) {
    // This check is for manual migration
    if (Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database) instanceof LoggingExecutor)
        return super.generateStatements(database);
    Object indexCreationThreshold = ((AbstractJdbcDatabase) database).get(DefaultLiquibaseConnectionProvider.INDEX_CREATION_THRESHOLD_PARAM);
    if (indexCreationThreshold instanceof Integer) {
        this.indexCreationThreshold = (Integer) indexCreationThreshold;
        if (this.indexCreationThreshold <= 0)
            return super.generateStatements(database);
    } else {
        return super.generateStatements(database);
    }
    try {
        // To check that the table already exists or not on which the index will be created.
        if (!SnapshotGeneratorFactory.getInstance().has(new Table().setName(getTableName()).setSchema(new Schema(getCatalogName(), getSchemaName())), database))
            return super.generateStatements(database);
        int result = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database).queryForInt(new RawSqlStatement("SELECT COUNT(*) FROM " + getTableNameForSqlSelects(database, getTableName())));
        if (result > this.indexCreationThreshold) {
            String loggingString = createLoggingString(database);
            logger.warnv("Following index should be created: {0}", loggingString);
            getChangeSet().setComments(loggingString);
            return new SqlStatement[] {};
        }
    } catch (DatabaseException | InvalidExampleException e) {
        throw new UnexpectedLiquibaseException("Database error while index threshold validation.", e);
    }
    return super.generateStatements(database);
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) Table(liquibase.structure.core.Table) Schema(liquibase.structure.core.Schema) AbstractJdbcDatabase(liquibase.database.AbstractJdbcDatabase) SqlStatement(liquibase.statement.SqlStatement) RawSqlStatement(liquibase.statement.core.RawSqlStatement) InvalidExampleException(liquibase.snapshot.InvalidExampleException) LoggingExecutor(liquibase.executor.LoggingExecutor) DatabaseException(liquibase.exception.DatabaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException)

Example 24 with LoggingExecutor

use of liquibase.executor.LoggingExecutor in project keycloak by keycloak.

the class QuarkusJpaUpdaterProvider method outputChangeLogTableCreationScript.

private void outputChangeLogTableCreationScript(Liquibase liquibase, final Writer exportWriter) throws DatabaseException {
    Database database = liquibase.getDatabase();
    ExecutorService executorService = Scope.getCurrentScope().getSingleton(ExecutorService.class);
    Executor oldTemplate = executorService.getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database);
    LoggingExecutor loggingExecutor = new LoggingExecutor(executorService.getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database), exportWriter, database);
    executorService.setExecutor(LiquibaseConstants.JDBC_EXECUTOR, database, loggingExecutor);
    loggingExecutor.comment("*********************************************************************");
    loggingExecutor.comment("* Keycloak database creation script - apply this script to empty DB *");
    loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
    loggingExecutor.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.
    loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
    executorService.setExecutor(LiquibaseConstants.JDBC_EXECUTOR, database, oldTemplate);
}
Also used : CreateDatabaseChangeLogTableStatement(liquibase.statement.core.CreateDatabaseChangeLogTableStatement) Executor(liquibase.executor.Executor) LoggingExecutor(liquibase.executor.LoggingExecutor) LoggingExecutor(liquibase.executor.LoggingExecutor) Database(liquibase.database.Database) ExecutorService(liquibase.executor.ExecutorService)

Aggregations

LoggingExecutor (liquibase.executor.LoggingExecutor)24 Executor (liquibase.executor.Executor)21 ExecutorService (liquibase.executor.ExecutorService)16 LiquibaseException (liquibase.exception.LiquibaseException)11 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)9 Database (liquibase.database.Database)3 MigrationFailedException (liquibase.exception.MigrationFailedException)3 InvalidExampleException (liquibase.snapshot.InvalidExampleException)3 SqlStatement (liquibase.statement.SqlStatement)3 ChangeSet (liquibase.changelog.ChangeSet)2 DatabaseException (liquibase.exception.DatabaseException)2 LockService (liquibase.lockservice.LockService)2 CreateDatabaseChangeLogTableStatement (liquibase.statement.core.CreateDatabaseChangeLogTableStatement)2 RawSqlStatement (liquibase.statement.core.RawSqlStatement)2 File (java.io.File)1 IOException (java.io.IOException)1 StringWriter (java.io.StringWriter)1 SQLException (java.sql.SQLException)1 Date (java.util.Date)1 TimeoutException (java.util.concurrent.TimeoutException)1