@Override public void init() throws DatabaseException { boolean createdTable = false; Executor executor = ExecutorService.getInstance().getExecutor(database); if (!hasDatabaseChangeLogLockTable()) { executor.comment("Create Database Lock Table"); executor.execute(new CreateDatabaseChangeLogLockTableStatement()); database.commit(); LogFactory.getLogger() .debug( "Created database lock table with name: " + database.escapeTableName( database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName())); this.hasDatabaseChangeLogLockTable = true; createdTable = true; } if (!isDatabaseChangeLogLockTableInitialized(createdTable)) { executor.comment("Initialize Database Lock Table"); executor.execute(new InitializeDatabaseChangeLogLockTableStatement()); database.commit(); } if (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()); } } }
public boolean isDatabaseChangeLogLockTableInitialized(final boolean tableJustCreated) throws DatabaseException { if (!isDatabaseChangeLogLockTableInitialized) { Executor executor = ExecutorService.getInstance().getExecutor(database); try { isDatabaseChangeLogLockTableInitialized = executor.queryForInt( new RawSqlStatement( "select count(*) from " + database.escapeTableName( database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()))) > 0; } catch (LiquibaseException e) { if (executor.updatesDatabase()) { throw new UnexpectedLiquibaseException(e); } else { // probably didn't actually create the table yet. isDatabaseChangeLogLockTableInitialized = !tableJustCreated; } } } return isDatabaseChangeLogLockTableInitialized; }
public void releaseLock() throws DatabaseException, LockException { Executor executor = ExecutorService.getInstance().getExecutor(database); try { if (database.hasDatabaseChangeLogLockTable()) { executor.comment("Release Database Lock"); database.rollback(); int updatedRows = executor.update(new UnlockDatabaseChangeLogStatement()); if (updatedRows != 1) { throw new LockException( "Did not update change log lock correctly.\n\n" + updatedRows + " rows were updated instead of the expected 1 row using executor " + executor.getClass().getName() + " there are " + executor.queryForInt( new RawSqlStatement( "select count(*) from " + database.getDatabaseChangeLogLockTableName())) + " rows in the table"); } database.commit(); hasChangeLogLock = false; instances.remove(this.database); database.setCanCacheLiquibaseTableInfo(false); LogFactory.getLogger().info("Successfully released change log lock"); } } finally { database.rollback(); } }
@Override public void destroy() throws DatabaseException { try { if (SnapshotGeneratorFactory.getInstance() .has( new Table() .setName(database.getDatabaseChangeLogLockTableName()) .setSchema(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName()), database)) { ExecutorService.getInstance() .getExecutor(database) .execute( new DropTableStatement( database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName(), false)); } } catch (InvalidExampleException e) { throw new UnexpectedLiquibaseException(e); } }