Skip to content

Commit

Permalink
CORE-2322 Add API for future rollback from tag SQL, Add support for u…
Browse files Browse the repository at this point in the history
…pdate

to tag, update to tag SQL, future rollback from tag SQL to command line
interface. Add support for update to tag and future rollback from tag SQL
to Spring integration. Update Ant and Maven integration to use simplified
method signature.
  • Loading branch information
mches committed Apr 8, 2015
1 parent 150efdd commit aeb275f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 18 deletions.
42 changes: 36 additions & 6 deletions liquibase-core/src/main/java/liquibase/Liquibase.java
Expand Up @@ -848,15 +848,23 @@ public void markNextChangeSetRan(Contexts contexts, LabelExpression labelExpress
}
}

public void futureRollbackSQL(String contexts, Writer output) throws LiquibaseException {
futureRollbackSQL(null, contexts, output);
public void futureRollbackSQL(Writer output) throws LiquibaseException {
futureRollbackSQL(null, null, new Contexts(), new LabelExpression(), output);
}

public void futureRollbackSQL(Integer count, String contexts, Writer output) throws LiquibaseException {
futureRollbackSQL(count, new Contexts(contexts), new LabelExpression(), output);
public void futureRollbackSQL(Contexts contexts, LabelExpression labelExpression, Writer output) throws LiquibaseException {
futureRollbackSQL(null, null, contexts, labelExpression, output);
}

public void futureRollbackSQL(Integer count, Contexts contexts, LabelExpression labelExpression, Writer output) throws LiquibaseException {
futureRollbackSQL(count, null, contexts, labelExpression, output);
}

public void futureRollbackSQL(String tag, Contexts contexts, LabelExpression labelExpression, Writer output) throws LiquibaseException {
futureRollbackSQL(null, tag, contexts, labelExpression, output);
}

protected void futureRollbackSQL(Integer count, String tag, Contexts contexts, LabelExpression labelExpression, Writer output) throws LiquibaseException {
changeLogParameters.setContexts(contexts);
changeLogParameters.setLabels(labelExpression);

Expand All @@ -875,13 +883,13 @@ public void futureRollbackSQL(Integer count, Contexts contexts, LabelExpression
changeLog.validate(database, contexts, labelExpression);

ChangeLogIterator logIterator;
if (count == null) {
if (count == null && tag == null) {
logIterator = new ChangeLogIterator(changeLog,
new NotRanChangeSetFilter(database.getRanChangeSetList()),
new ContextChangeSetFilter(contexts),
new LabelChangeSetFilter(labelExpression),
new DbmsChangeSetFilter(database));
} else {
} else if (count != null) {
ChangeLogIterator forwardIterator = new ChangeLogIterator(changeLog,
new NotRanChangeSetFilter(database.getRanChangeSetList()),
new ContextChangeSetFilter(contexts),
Expand All @@ -902,6 +910,28 @@ public ChangeSetFilterResult accepts(ChangeSet changeSet) {
return new ChangeSetFilterResult(listVisitor.getSeenChangeSets().contains(changeSet), null, null);
}
});
} else {
List<RanChangeSet> ranChangeSetList = database.getRanChangeSetList();
ChangeLogIterator forwardIterator = new ChangeLogIterator(changeLog,
new NotRanChangeSetFilter(ranChangeSetList),
new ContextChangeSetFilter(contexts),
new LabelChangeSetFilter(labelExpression),
new DbmsChangeSetFilter(database),
new UpToTagChangeSetFilter(tag, ranChangeSetList));
final ListVisitor listVisitor = new ListVisitor();
forwardIterator.run(listVisitor, new RuntimeEnvironment(database, contexts, labelExpression));

logIterator = new ChangeLogIterator(changeLog,
new NotRanChangeSetFilter(ranChangeSetList),
new ContextChangeSetFilter(contexts),
new LabelChangeSetFilter(labelExpression),
new DbmsChangeSetFilter(database),
new ChangeSetFilter() {
@Override
public ChangeSetFilterResult accepts(ChangeSet changeSet) {
return new ChangeSetFilterResult(listVisitor.getSeenChangeSets().contains(changeSet), null, null);
}
});
}

logIterator.run(new RollbackVisitor(database, changeExecListener), new RuntimeEnvironment(database, contexts, labelExpression));
Expand Down
@@ -1,7 +1,6 @@
package liquibase.integration.ant;

import liquibase.Contexts;
import liquibase.LabelExpression;
import liquibase.Liquibase;
import liquibase.exception.LiquibaseException;
import org.apache.tools.ant.BuildException;
Expand All @@ -13,7 +12,7 @@ public class DatabaseRollbackFutureTask extends AbstractChangeLogBasedTask {
public void executeWithLiquibaseClassloader() throws BuildException {
Liquibase liquibase = getLiquibase();
try {
liquibase.futureRollbackSQL(null, new Contexts(getContexts()), getLabels(), getOutputFileWriter());
liquibase.futureRollbackSQL(new Contexts(getContexts()), getLabels(), getOutputFileWriter());
} catch (LiquibaseException e) {
throw new BuildException("Unable to generate future rollback SQL. " + e.toString(), e);
} catch (IOException e) {
Expand Down
Expand Up @@ -269,6 +269,8 @@ protected List<String> checkSetup() {
private void checkForUnexpectedCommandParameter(List<String> messages) {
if ("updateCount".equalsIgnoreCase(command)
|| "updateCountSQL".equalsIgnoreCase(command)
|| "updateToTag".equalsIgnoreCase(command)
|| "updateToTagSQL".equalsIgnoreCase(command)
|| "calculateCheckSum".equalsIgnoreCase(command)
|| "dbDoc".equalsIgnoreCase(command)
|| "tag".equalsIgnoreCase(command)
Expand Down Expand Up @@ -356,6 +358,8 @@ private boolean isCommand(String arg) {
|| "updateSQL".equalsIgnoreCase(arg)
|| "updateCount".equalsIgnoreCase(arg)
|| "updateCountSQL".equalsIgnoreCase(arg)
|| "updateToTag".equalsIgnoreCase(arg)
|| "updateToTagSQL".equalsIgnoreCase(arg)
|| "rollback".equalsIgnoreCase(arg)
|| "rollbackToDate".equalsIgnoreCase(arg)
|| "rollbackCount".equalsIgnoreCase(arg)
Expand All @@ -364,6 +368,7 @@ private boolean isCommand(String arg) {
|| "rollbackCountSQL".equalsIgnoreCase(arg)
|| "futureRollbackSQL".equalsIgnoreCase(arg)
|| "futureRollbackCountSQL".equalsIgnoreCase(arg)
|| "futureRollbackToTagSQL".equalsIgnoreCase(arg)
|| "updateTestingRollback".equalsIgnoreCase(arg)
|| "tag".equalsIgnoreCase(arg)
|| "tagExists".equalsIgnoreCase(arg)
Expand Down Expand Up @@ -477,6 +482,9 @@ protected void printHelp(PrintStream stream) {
stream.println(" updateCount <num> Applies next NUM changes to the database");
stream.println(" updateCountSQL <num> Writes SQL to apply next NUM changes");
stream.println(" to the database");
stream.println(" updateToTag <tag> Updates the database to the specified tag");
stream.println(" updateToTagSQL <tag> Writes (to standard out) the SQL to update the");
stream.println(" database to the specified tag");
stream.println(" rollback <tag> Rolls back the database to the the state is was");
stream.println(" when the tag was applied");
stream.println(" rollbackSQL <tag> Writes SQL to roll back the database to that");
Expand All @@ -499,6 +507,10 @@ protected void printHelp(PrintStream stream) {
stream.println(" futureRollbackSQL <value> Writes SQL to roll back the database to the ");
stream.println(" current state after <value> changes in the ");
stream.println(" changeslog have been applied");
stream.println(" futureRollbackFromTagSQL <tag> Writes (to standard out) the SQL to roll back");
stream.println(" the database to its current state after the");
stream.println(" changes up to the specified tag have been");
stream.println(" applied");
stream.println(" updateTestingRollback Updates database, then rolls back changes before");
stream.println(" updating again. Useful for testing");
stream.println(" rollback support");
Expand Down Expand Up @@ -1077,6 +1089,18 @@ protected void doMigration() throws Exception {
liquibase.update(Integer.parseInt(commandParams.iterator().next()), new Contexts(contexts), new LabelExpression(labels));
} else if ("updateCountSQL".equalsIgnoreCase(command)) {
liquibase.update(Integer.parseInt(commandParams.iterator().next()), new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("updateToTag".equalsIgnoreCase(command)) {
if (commandParams == null || commandParams.size() == 0) {
throw new CommandLineParsingException("updateToTag requires a tag");
}

liquibase.update(commandParams.iterator().next(), new Contexts(contexts), new LabelExpression(labels));
} else if ("updateToTagSQL".equalsIgnoreCase(command)) {
if (commandParams == null || commandParams.size() == 0) {
throw new CommandLineParsingException("updateToTagSQL requires a tag");
}

liquibase.update(commandParams.iterator().next(), new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("updateSQL".equalsIgnoreCase(command)) {
liquibase.update(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("rollback".equalsIgnoreCase(command)) {
Expand Down Expand Up @@ -1104,18 +1128,24 @@ protected void doMigration() throws Exception {
liquibase.rollback(new ISODateFormat().parse(getCommandArgument()), getCommandParam("rollbackScript", null), new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("rollbackCountSQL".equalsIgnoreCase(command)) {
if (getCommandArgument() == null) {
throw new CommandLineParsingException("rollbackCountSQL requires a rollback tag");
throw new CommandLineParsingException("rollbackCountSQL requires a rollback count");
}

liquibase.rollback(Integer.parseInt(getCommandArgument()), getCommandParam("rollbackScript", null), new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("futureRollbackSQL".equalsIgnoreCase(command)) {
liquibase.futureRollbackSQL(null, new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
liquibase.futureRollbackSQL(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("futureRollbackCountSQL".equalsIgnoreCase(command)) {
if (getCommandArgument() == null) {
throw new CommandLineParsingException("futureRollbackCountSQL requires a rollback count");
}

liquibase.futureRollbackSQL(Integer.parseInt(getCommandArgument()), new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("futureRollbackFromTagSQL".equalsIgnoreCase(command)) {
if (getCommandArgument() == null) {
throw new CommandLineParsingException("futureRollbackFromTagSQL requires a tag");
}

liquibase.futureRollbackSQL(getCommandArgument(), new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
} else if ("updateTestingRollback".equalsIgnoreCase(command)) {
liquibase.updateTestingRollback(new Contexts(contexts), new LabelExpression(labels));
} else {
Expand Down
Expand Up @@ -13,9 +13,7 @@
import liquibase.exception.LiquibaseException;
import liquibase.logging.LogFactory;
import liquibase.logging.Logger;
import liquibase.resource.AbstractResourceAccessor;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.ResourceAccessor;
import liquibase.util.StringUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
Expand Down Expand Up @@ -147,6 +145,8 @@ public ClassLoader toClassLoader() {

protected String labels;

protected String tag;

protected Map<String, String> parameters;

protected String defaultSchema;
Expand Down Expand Up @@ -284,6 +284,14 @@ public void setLabels(String labels) {
this.labels = labels;
}

public String getTag() {
return tag;
}

public void setTag(String tag) {
this.tag = tag;
}

public String getDefaultSchema() {
return defaultSchema;
}
Expand Down Expand Up @@ -334,7 +342,11 @@ private void generateRollbackFile(Liquibase liquibase) throws LiquibaseException
FileWriter output = null;
try {
output = new FileWriter(rollbackFile);
liquibase.futureRollbackSQL(null, new Contexts(getContexts()), new LabelExpression(getLabels()), output);
if (tag != null) {
liquibase.futureRollbackSQL(tag, new Contexts(getContexts()), new LabelExpression(getLabels()), output);
} else {
liquibase.futureRollbackSQL(new Contexts(getContexts()), new LabelExpression(getLabels()), output);
}
} catch (IOException e) {
throw new LiquibaseException("Unable to generate rollback file.", e);
} finally {
Expand All @@ -349,9 +361,13 @@ private void generateRollbackFile(Liquibase liquibase) throws LiquibaseException
}
}

protected void performUpdate(Liquibase liquibase) throws LiquibaseException {
liquibase.update(new Contexts(getContexts()), new LabelExpression(getLabels()));
}
protected void performUpdate(Liquibase liquibase) throws LiquibaseException {
if (tag != null) {
liquibase.update(tag, new Contexts(getContexts()), new LabelExpression(getLabels()));
} else {
liquibase.update(new Contexts(getContexts()), new LabelExpression(getLabels()));
}
}

protected Liquibase createLiquibase(Connection c) throws LiquibaseException {
Liquibase liquibase = new Liquibase(getChangeLog(), createResourceOpener(), createDatabase(c));
Expand Down
Expand Up @@ -396,7 +396,7 @@ public void testRollbackableChangeLogScriptOnFutureDatabase() throws Exception {
clearDatabase(liquibase);

liquibase = createLiquibase(rollbackChangeLog);
liquibase.futureRollbackSQL(this.contexts, writer);
liquibase.futureRollbackSQL(new Contexts(this.contexts), new LabelExpression(), writer);

// System.out.println("Rollback SQL for future "+driverName+"\n\n"+writer.toString());
}
Expand Down
Expand Up @@ -91,7 +91,7 @@ protected void cleanup(Database db) {

@Override
protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseException {
liquibase.futureRollbackSQL(null, new Contexts(contexts), new LabelExpression(labels), outputWriter);
liquibase.futureRollbackSQL(new Contexts(contexts), new LabelExpression(labels), outputWriter);
}

@Override
Expand Down

0 comments on commit aeb275f

Please sign in to comment.