Skip to content

Commit

Permalink
Merge pull request #1000 from liquibase/DAT-3917
Browse files Browse the repository at this point in the history
DAT 3917
  • Loading branch information
nvoxland committed Feb 21, 2020
2 parents 99e5fc0 + ce3f63e commit 5003e26
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 53 deletions.
2 changes: 1 addition & 1 deletion liquibase-core/src/main/java/liquibase/change/Change.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public interface Change extends LiquibaseSerializable {


/**
* Returns true if this change be rolled back for the given database.
* Returns true if this can change be rolled back for the given database.
*/
public boolean supportsRollback(Database database);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
import liquibase.database.DatabaseList;
import liquibase.database.ObjectQuotingStrategy;
import liquibase.exception.*;
import liquibase.logging.LogFactory;
import liquibase.exception.*;
import liquibase.logging.LogService;
import liquibase.logging.LogType;
import liquibase.logging.Logger;
Expand All @@ -28,7 +26,6 @@
import liquibase.util.StringUtils;
import liquibase.util.file.FilenameUtils;

import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import liquibase.servicelocator.ServiceLocator;
import liquibase.util.ISODateFormat;
import liquibase.util.LiquibaseUtil;
import liquibase.util.StreamUtil;
import liquibase.util.StringUtils;
import liquibase.util.xml.XMLResourceBundle;
import liquibase.util.xml.XmlResourceBundleControl;
Expand Down Expand Up @@ -287,7 +286,9 @@ public static int run(String[] args) throws LiquibaseException {
log.info(LogType.USER_MESSAGE, licenseService.getLicenseInfo());
}

if (main.commandParams.contains("--help") && main.command.startsWith("rollbackOneChangeSet")) {
if (main.commandParams.contains("--help") &&
(main.command.startsWith("rollbackOneChangeSet") ||
main.command.startsWith("rollbackOneUpdate"))) {
//don't need to check setup
} else {
List<String> setupMessages = main.checkSetup();
Expand Down Expand Up @@ -541,15 +542,17 @@ private static boolean isStandardOutputRequired(String command) {
private static boolean isChangeLogRequired(String command) {
return command.toLowerCase().startsWith(COMMANDS.UPDATE)
|| (command.toLowerCase().startsWith(COMMANDS.ROLLBACK) &&
!command.equalsIgnoreCase(COMMANDS.ROLLBACK_ONE_CHANGE_SET))
(!command.equalsIgnoreCase(COMMANDS.ROLLBACK_ONE_CHANGE_SET) &&
!command.equalsIgnoreCase(COMMANDS.ROLLBACK_ONE_UPDATE)))
|| COMMANDS.CALCULATE_CHECKSUM.equalsIgnoreCase(command)
|| COMMANDS.STATUS.equalsIgnoreCase(command)
|| COMMANDS.VALIDATE.equalsIgnoreCase(command)
|| COMMANDS.CHANGELOG_SYNC.equalsIgnoreCase(command)
|| COMMANDS.CHANGELOG_SYNC_SQL.equalsIgnoreCase(command)
|| COMMANDS.GENERATE_CHANGELOG.equalsIgnoreCase(command)
|| COMMANDS.DIFF_CHANGELOG.equalsIgnoreCase(command)
|| COMMANDS.ROLLBACK_ONE_CHANGE_SET.equalsIgnoreCase(command);
|| COMMANDS.ROLLBACK_ONE_CHANGE_SET.equalsIgnoreCase(command)
|| COMMANDS.ROLLBACK_ONE_UPDATE.equalsIgnoreCase(command);
}

/**
Expand Down Expand Up @@ -601,7 +604,9 @@ private static boolean isCommand(String arg) {
|| COMMANDS.MARK_NEXT_CHANGESET_RAN.equalsIgnoreCase(arg)
|| COMMANDS.MARK_NEXT_CHANGESET_RAN_SQL.equalsIgnoreCase(arg)
|| COMMANDS.ROLLBACK_ONE_CHANGE_SET.equalsIgnoreCase(arg)
|| COMMANDS.ROLLBACK_ONE_CHANGE_SET_SQL.equalsIgnoreCase(arg);
|| COMMANDS.ROLLBACK_ONE_CHANGE_SET_SQL.equalsIgnoreCase(arg)
|| COMMANDS.ROLLBACK_ONE_UPDATE.equalsIgnoreCase(arg)
|| COMMANDS.ROLLBACK_ONE_UPDATE_SQL.equalsIgnoreCase(arg);
}

/**
Expand Down Expand Up @@ -860,7 +865,6 @@ private void checkForUnexpectedCommandParameter(List<String> messages) {
} else if (COMMANDS.ROLLBACK_ONE_CHANGE_SET.equalsIgnoreCase(command)) {
for (String cmdParm : commandParams) {
if (!cmdParm.startsWith("--" + OPTIONS.CHANGE_SET_ID)
&& !cmdParm.startsWith("--" + OPTIONS.CHANGE_SET_ID)
&& !cmdParm.startsWith("--" + OPTIONS.HELP)
&& !cmdParm.startsWith("--" + OPTIONS.FORCE)
&& !cmdParm.startsWith("--" + OPTIONS.CHANGE_SET_PATH)
Expand All @@ -872,7 +876,6 @@ private void checkForUnexpectedCommandParameter(List<String> messages) {
} else if (COMMANDS.ROLLBACK_ONE_CHANGE_SET_SQL.equalsIgnoreCase(command)) {
for (String cmdParm : commandParams) {
if (!cmdParm.startsWith("--" + OPTIONS.CHANGE_SET_ID)
&& !cmdParm.startsWith("--" + OPTIONS.CHANGE_SET_ID)
&& !cmdParm.startsWith("--" + OPTIONS.HELP)
&& !cmdParm.startsWith("--" + OPTIONS.FORCE)
&& !cmdParm.startsWith("--" + OPTIONS.CHANGE_SET_PATH)
Expand All @@ -882,6 +885,24 @@ private void checkForUnexpectedCommandParameter(List<String> messages) {
}
}
}
else if (COMMANDS.ROLLBACK_ONE_UPDATE.equalsIgnoreCase(command)) {
for (String cmdParm : commandParams) {
if (!cmdParm.startsWith("--" + OPTIONS.DEPLOYMENT_ID)
&& !cmdParm.startsWith("--" + OPTIONS.HELP)
&& !cmdParm.startsWith("--" + OPTIONS.FORCE)) {
messages.add(String.format(coreBundle.getString("unexpected.command.parameter"), cmdParm));
}
}
}
else if (COMMANDS.ROLLBACK_ONE_UPDATE_SQL.equalsIgnoreCase(command)) {
for (String cmdParm : commandParams) {
if (!cmdParm.startsWith("--" + OPTIONS.DEPLOYMENT_ID)
&& !cmdParm.startsWith("--" + OPTIONS.HELP)
&& !cmdParm.startsWith("--" + OPTIONS.FORCE)) {
messages.add(String.format(coreBundle.getString("unexpected.command.parameter"), cmdParm));
}
}
}
}

/**
Expand Down Expand Up @@ -1278,9 +1299,12 @@ protected void doMigration() throws Exception {
//
// Check for a valid license to run PRO commands
//
if (COMMANDS.ROLLBACK_ONE_CHANGE_SET.equals(command) || COMMANDS.ROLLBACK_ONE_CHANGE_SET_SQL.equals(command)) {
if (COMMANDS.ROLLBACK_ONE_CHANGE_SET.equals(command) ||
COMMANDS.ROLLBACK_ONE_CHANGE_SET_SQL.equals(command) ||
COMMANDS.ROLLBACK_ONE_UPDATE.equals(command) ||
COMMANDS.ROLLBACK_ONE_UPDATE_SQL.equals(command)){
if (!commandParams.contains("--help") && !liquibaseProLicenseValid) {
String messageString = String.format(coreBundle.getString("no.pro.license.found"), COMMANDS.ROLLBACK_ONE_CHANGE_SET);
String messageString = String.format(coreBundle.getString("no.pro.license.found"), command);
throw new LiquibaseException(messageString);
}
}
Expand Down Expand Up @@ -1516,15 +1540,50 @@ protected void doMigration() throws Exception {
if (this.commandParams.contains("--help")) {
argsMap.put("help", true);
}
LiquibaseCommand liquibaseCommand = createLiquibaseCommand(database, liquibase, argsMap);
LiquibaseCommand liquibaseCommand = createLiquibaseCommand(database, liquibase, COMMANDS.ROLLBACK_ONE_CHANGE_SET, argsMap);
liquibaseCommand.execute();
return;
} else if (COMMANDS.ROLLBACK_ONE_CHANGE_SET_SQL.equals(command)) {
Writer outputWriter = getOutputWriter();
Map<String, Object> argsMap = new HashMap<String, Object>();
argsMap.put("outputWriter", outputWriter);
argsMap.put("force", true);
LiquibaseCommand liquibaseCommand = createLiquibaseCommand(database, liquibase, argsMap);
LiquibaseCommand liquibaseCommand = createLiquibaseCommand(database, liquibase, COMMANDS.ROLLBACK_ONE_CHANGE_SET, argsMap);
liquibaseCommand.execute();
outputWriter.flush();
outputWriter.close();
return;
} else if (COMMANDS.ROLLBACK_ONE_UPDATE.equals(command)) {
Map<String, Object> argsMap = new HashMap<String, Object>();
argsMap.put("deploymentId", getCommandParam(OPTIONS.DEPLOYMENT_ID, null));
argsMap.put("changeLogFile", changeLogFile);
argsMap.put("database", database);
if (!commandParams.contains("--help")) {
argsMap.put("changeLog", liquibase.getDatabaseChangeLog());
}
argsMap.put("resourceAccessor", liquibase.getResourceAccessor());
ChangeLogParameters clp = new ChangeLogParameters(database);
for (Map.Entry<String, Object> entry : changeLogParameters.entrySet()) {
clp.set(entry.getKey(), entry.getValue());
}
argsMap.put("changeLogParameters", clp);

if (this.commandParams.contains("--force")) {
argsMap.put("force", true);
}
if (this.commandParams.contains("--help")) {
argsMap.put("help", true);
}
LiquibaseCommand liquibaseCommand = createLiquibaseCommand(database, liquibase, COMMANDS.ROLLBACK_ONE_UPDATE, argsMap);
liquibaseCommand.execute();
return;
} else if (COMMANDS.ROLLBACK_ONE_UPDATE_SQL.equals(command)) {
Writer outputWriter = getOutputWriter();
Map<String, Object> argsMap = new HashMap<String, Object>();
argsMap.put("deploymentId", getCommandParam(OPTIONS.DEPLOYMENT_ID, null));
argsMap.put("outputWriter", outputWriter);
argsMap.put("force", true);
LiquibaseCommand liquibaseCommand = createLiquibaseCommand(database, liquibase, COMMANDS.ROLLBACK_ONE_UPDATE, argsMap);
liquibaseCommand.execute();
outputWriter.flush();
outputWriter.close();
Expand Down Expand Up @@ -1719,9 +1778,9 @@ protected void doMigration() throws Exception {
}
}

private LiquibaseCommand createLiquibaseCommand(Database database, Liquibase liquibase, Map<String, Object> argsMap)
private LiquibaseCommand createLiquibaseCommand(Database database, Liquibase liquibase, String commandName, Map<String, Object> argsMap)
throws CommandLineParsingException, LiquibaseException {
LiquibaseCommand liquibaseCommand = (CommandFactory.getInstance().getCommand(COMMANDS.ROLLBACK_ONE_CHANGE_SET));
LiquibaseCommand liquibaseCommand = CommandFactory.getInstance().getCommand(commandName);
AbstractSelfConfiguratingCommand configuratingCommand = (AbstractSelfConfiguratingCommand) liquibaseCommand;
argsMap.put("changeSetId", getCommandParam(OPTIONS.CHANGE_SET_ID, null));
argsMap.put("changeSetAuthor", getCommandParam(OPTIONS.CHANGE_SET_AUTHOR, null));
Expand Down Expand Up @@ -1904,6 +1963,8 @@ private enum COMMANDS {
private static final String RELEASE_LOCKS = "releaseLocks";
private static final String ROLLBACK_ONE_CHANGE_SET = "rollbackOneChangeSet";
private static final String ROLLBACK_ONE_CHANGE_SET_SQL = "rollbackOneChangeSetSQL";
private static final String ROLLBACK_ONE_UPDATE = "rollbackOneUpdate";
private static final String ROLLBACK_ONE_UPDATE_SQL = "rollbackOneUpdateSQL";
private static final String ROLLBACK = "rollback";
private static final String ROLLBACK_COUNT = "rollbackCount";
private static final String ROLLBACK_COUNT_SQL = "rollbackCountSQL";
Expand Down Expand Up @@ -1937,6 +1998,7 @@ private enum OPTIONS {
private static final String CHANGE_SET_ID = "changeSetId";
private static final String CHANGE_SET_AUTHOR = "changeSetAuthor";
private static final String CHANGE_SET_PATH = "changeSetPath";
private static final String DEPLOYMENT_ID = "deploymentId";
private static final String OUTPUT_FILE = "outputFile";
private static final String FORCE = "force";
private static final String ROLLBACK_SCRIPT = "rollbackScript";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public static ValidationErrors checkForValidLicense(String licenseType, Change c
return new ValidationErrors();
}
if (licenseService.licenseIsValid(licenseType)) {
String message = String.format("Found valid license with subject '%s'",licenseType);
LOG.info(message);
String message = String.format("Found valid license with subject '%s' for '%s'",licenseType, change.getDescription());
LOG.debug(message);
return new ValidationErrors();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ Standard Commands:
rollbackOneChangeSetSQL <args> Writes SQL to roll back one specific changeset, without
rolling back changesets deployed before or afterwards.
(Liquibase Pro key required)
rollbackOneUpdate Rolls back all the changesets from one update, identified by "deploymentId",
if all the changesets can be rolled back. If not, a WARNING message will provide
details (Liquibase Pro key required). Note: A list of deploymentIds may be
viewed by using the "history" command.
rollbackOneUpdateSQL Displays the SQL which will be executed when the corresponding rollbackOneUpdate
command is executed, and does not perform the actual rollback (Liquibase Pro key required).
rollbackToDate <date/time> Rolls back the database to the the state is was
at the given date/time.
Date Format: yyyy-MM-dd'T'HH:mm:ss
Expand Down Expand Up @@ -74,9 +80,10 @@ Diff Commands
Documentation Commands
dbDoc <outputDirectory> Generates Javadoc-like documentation
based on current database and change log
history Writes details about what changeSets have been
applied to the database to standard out
history Displays the changesets already deployed to the
database in the specified connection url, grouped
by default according to their update command's
"deployment_id" value.
Maintenance Commands
tag <tag string> 'Tags' the current database state for future rollback
tagExists <tag string> Checks whether the given tag is already existing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ errors=Errors:
unexpected.value=Unexpected value '%s' (options must start with a '--')
cannot.specify.both=Cannot specify both '%s' and '%s'
changelogfile.already.exists=Output ChangeLogFile '%s' already exists!
force.option.required=The targeted changeset is followed by %d changesets, so unexpected outcomes may occur.\nTo review the rollback SQL, please run rollbackOneChangesetSQL. This message can be suppressed by\nadding the --force flag.
force.option.required=The targeted changeset is followed by %d changesets, so unexpected outcomes may occur.\nTo review the rollback SQL, please run '%s'. This message can be suppressed by\nadding the --force flag.
id.author.path.required=You must specify the change set ID, author, and path
no.deployment.ids.found=No deployment IDs were located. No rollbacks were performed.
no.change.sets.found.for.deployment.id=No changesets were located matching deployment ID '%s'. No rollbacks were performed.
deployment.id.required=You must specify the deployment ID.
no.pro.license.found=The command %s requires a Liquibase Pro license, available at https://download.liquibase.org/ or lbprosales@datical.com
attempt.to.delete.the.file.failed.cannot.continue=Attempt to delete the file '%s' failed. Cannot continue. Sorry.
successfully.released.database.change.log.locks=Successfully released all database change log locks for '%s'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
public abstract class AbstractLiquibaseChangeLogMojo extends AbstractLiquibaseMojo {

/**
* Specifies the directory where Liquibase can find your <i>change-log</i> file.
* Specifies the directory where Liquibase can find your <i>changelog</i> file.
*
* @parameter property="liquibase.changeLogDirectory"
*/
protected String changeLogDirectory;

/**
* Specifies the <i>change-log</i> file for Liquibase to use.
* Specifies the <i>changelog</i> file for Liquibase to use.
* @parameter property="liquibase.changeLogFile"
*/
protected String changeLogFile;
Expand Down

0 comments on commit 5003e26

Please sign in to comment.