-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
RollbackVisitor.java
100 lines (87 loc) · 3.68 KB
/
RollbackVisitor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package liquibase.changelog.visitor;
import liquibase.Scope;
import liquibase.change.Change;
import liquibase.change.core.SQLFileChange;
import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import liquibase.changelog.RollbackContainer;
import liquibase.changelog.filter.ChangeSetFilterResult;
import liquibase.database.Database;
import liquibase.exception.LiquibaseException;
import liquibase.exception.MigrationFailedException;
import liquibase.executor.Executor;
import liquibase.executor.ExecutorService;
import liquibase.executor.LoggingExecutor;
import liquibase.logging.LogService;
import java.util.List;
import java.util.Set;
public class RollbackVisitor implements ChangeSetVisitor {
private Database database;
private ChangeExecListener execListener;
/**
* @deprecated - please use the constructor with ChangeExecListener, which can be null.
*/
@Deprecated
public RollbackVisitor(Database database) {
this.database = database;
}
public RollbackVisitor(Database database, ChangeExecListener listener) {
this(database);
this.execListener = listener;
}
@Override
public Direction getDirection() {
return ChangeSetVisitor.Direction.REVERSE;
}
@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);
}
protected void fireRollbackFailed(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database, Exception e) {
if (execListener != null) {
execListener.rollbackFailed(changeSet, databaseChangeLog, database, e);
}
}
private void checkForEmptyRollbackFile(ChangeSet changeSet) {
RollbackContainer container = changeSet.getRollback();
List<Change> changes = container.getChanges();
if (changes.isEmpty()) {
return;
}
for (Change change : changes) {
if (! (change instanceof SQLFileChange)) {
continue;
}
String sql = ((SQLFileChange)change).getSql();
if (sql.length() == 0) {
Scope.getCurrentScope().getLog(getClass()).info("\nNo rollback logic defined in empty rollback script. Changesets have been removed from\n" +
"the DATABASECHANGELOG table but no other logic was performed.");
}
}
}
private void sendRollbackWillRunEvent(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database) {
if (execListener != null) {
execListener.willRollback(changeSet, databaseChangeLog, database);
}
}
private void sendRollbackEvent(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database) {
if (execListener != null) {
execListener.rolledBack(changeSet, databaseChangeLog, database);
}
}
}