use of liquibase.executor.Executor in project liquibase by liquibase.
the class RollbackVisitor method visit.
@Override
public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database, Set<ChangeSetFilterResult> filterResults) throws LiquibaseException {
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
if (!(executor instanceof LoggingExecutor)) {
Scope.getCurrentScope().getUI().sendMessage("Rolling Back Changeset: " + changeSet);
}
sendRollbackWillRunEvent(changeSet, databaseChangeLog, database);
try {
changeSet.rollback(this.database, this.execListener);
} catch (Exception e) {
fireRollbackFailed(changeSet, databaseChangeLog, database, e);
throw e;
}
this.database.removeRanStatus(changeSet);
sendRollbackEvent(changeSet, databaseChangeLog, database);
this.database.commit();
checkForEmptyRollbackFile(changeSet);
}
use of liquibase.executor.Executor 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.executor.Executor in project liquibase by liquibase.
the class AbstractIntegrationTest method testRerunDiffChangeLogAltSchema.
@Test
public void testRerunDiffChangeLogAltSchema() throws Exception {
assumeNotNull(this.getDatabase());
if (database.getShortName().equalsIgnoreCase("mssql")) {
// not possible on MSSQL.
return;
}
if (!database.supportsSchemas()) {
return;
}
Liquibase liquibase = createLiquibase(includedChangeLog);
database.setDefaultSchemaName("lbschem2");
clearDatabase();
LockService lockService = LockServiceFactory.getInstance().getLockService(database);
lockService.forceReleaseLock();
liquibase.update(includedChangeLog);
DatabaseSnapshot originalSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
CompareControl compareControl = new CompareControl(new CompareControl.SchemaComparison[] { new CompareControl.SchemaComparison(CatalogAndSchema.DEFAULT, new CatalogAndSchema("lbcat2", null)) }, originalSnapshot.getSnapshotControl().getTypesToInclude());
DiffResult diffResult = DiffGeneratorFactory.getInstance().compare(database, null, compareControl);
File tempFile = File.createTempFile("liquibase-test", ".xml");
FileOutputStream output = new FileOutputStream(tempFile);
try {
new DiffToChangeLog(diffResult, new DiffOutputControl()).print(new PrintStream(output));
output.flush();
} finally {
output.close();
}
liquibase = createLiquibase(tempFile.getName());
clearDatabase();
// run again to test changelog testing logic
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
try {
executor.execute(new DropTableStatement("lbcat2", null, database.getDatabaseChangeLogTableName(), false));
} catch (DatabaseException e) {
// ok
}
try {
executor.execute(new DropTableStatement("lbcat2", null, database.getDatabaseChangeLogLockTableName(), false));
} catch (DatabaseException e) {
// ok
}
database.commit();
DatabaseConnection connection = new JdbcConnection(testSystem.getConnection());
database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
database.setDefaultSchemaName("lbschem2");
liquibase = createLiquibase(tempFile.getName());
try {
liquibase.update(this.contexts);
} catch (ValidationFailedException e) {
e.printDescriptiveError(System.out);
throw e;
}
tempFile.deleteOnExit();
DatabaseSnapshot finalSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
CompareControl finalCompareControl = new CompareControl();
finalCompareControl.addSuppressedField(Column.class, "autoIncrementInformation");
DiffResult finalDiffResult = DiffGeneratorFactory.getInstance().compare(originalSnapshot, finalSnapshot, finalCompareControl);
new DiffToReport(finalDiffResult, System.out).print();
assertTrue("running the same change log two times against an alternative schema should produce " + "equal snapshots.", finalDiffResult.areEqual());
}
use of liquibase.executor.Executor 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;
}
use of liquibase.executor.Executor in project liquibase by liquibase.
the class ChangeSet method rollback.
public void rollback(Database database, ChangeExecListener listener) throws RollbackFailedException {
Executor originalExecutor = setupCustomExecutorIfNecessary(database);
try {
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
executor.comment("Rolling Back ChangeSet: " + toString());
database.setObjectQuotingStrategy(objectQuotingStrategy);
// set auto-commit based on runInTransaction if database supports DDL in transactions
if (database.supportsDDLInTransaction()) {
database.setAutoCommit(!runInTransaction);
}
if (hasCustomRollbackChanges()) {
final List<SqlStatement> statements = new LinkedList<>();
for (Change change : rollback.getChanges()) {
if (((change instanceof DbmsTargetedChange)) && !DatabaseList.definitionMatches(((DbmsTargetedChange) change).getDbms(), database, true)) {
continue;
}
if (listener != null) {
listener.willRun(change, this, changeLog, database);
}
ValidationErrors errors = change.validate(database);
if (errors.hasErrors()) {
throw new RollbackFailedException("Rollback statement failed validation: " + errors.toString());
}
//
SqlStatement[] changeStatements = change.generateStatements(database);
if (changeStatements != null) {
statements.addAll(Arrays.asList(changeStatements));
}
if (listener != null) {
listener.ran(change, this, changeLog, database);
}
}
if (!statements.isEmpty()) {
database.executeRollbackStatements(statements.toArray(new SqlStatement[] {}), sqlVisitors);
}
} else {
List<Change> changes = getChanges();
for (int i = changes.size() - 1; i >= 0; i--) {
Change change = changes.get(i);
database.executeRollbackStatements(change, sqlVisitors);
}
}
if (runInTransaction) {
database.commit();
}
Scope.getCurrentScope().getLog(getClass()).fine("ChangeSet " + toString() + " has been successfully rolled back.");
} catch (Exception e) {
try {
database.rollback();
} catch (DatabaseException e1) {
// ok
}
throw new RollbackFailedException(e);
} finally {
// restore auto-commit to false if this ChangeSet was not run in a transaction,
// but only if the database supports DDL in transactions
Scope.getCurrentScope().getSingleton(ExecutorService.class).setExecutor("jdbc", database, originalExecutor);
if (!runInTransaction && database.supportsDDLInTransaction()) {
try {
database.setAutoCommit(false);
} catch (DatabaseException e) {
Scope.getCurrentScope().getLog(getClass()).warning("Could not resetInternalState autocommit", e);
}
}
}
}
Aggregations