From 85df01f63af6f8b1438252bf4e6c8dbc9ea4b123 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Wed, 5 Feb 2020 08:25:02 -0600 Subject: [PATCH 01/17] WIP --- .../liquibase/i18n/liquibase-core.properties | 1 + .../LiquibaseRollbackOneUpdateMojo.java | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java diff --git a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties index 841a66405bf..929a57d1f87 100644 --- a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties +++ b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties @@ -31,6 +31,7 @@ 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. id.author.path.required=You must specify the change set ID, author, and path +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' diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java new file mode 100644 index 00000000000..8013e3a951f --- /dev/null +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java @@ -0,0 +1,106 @@ +// Version: $Id: $ +// Copyright: Copyright(c) 2007 Trace Financial Limited +package org.liquibase.maven.plugins; + +import liquibase.Liquibase; +import liquibase.changelog.ChangeLogParameters; +import liquibase.command.AbstractSelfConfiguratingCommand; +import liquibase.command.CommandExecutionException; +import liquibase.command.CommandFactory; +import liquibase.command.LiquibaseCommand; +import liquibase.database.Database; +import liquibase.exception.LiquibaseException; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * Invokes Liquibase rollback by Deployment ID + * + * @goal rollbackOneUpdate + * + */ +public class LiquibaseRollbackOneUpdateMojo extends AbstractLiquibaseChangeLogMojo { + /** + * + * The Deployment ID to rollback + * + * @parameter property="liquibase.deploymentId" + * + */ + protected String deploymentId; + + /** + * + * Required flag for RollbackOneChangeSet + * + * @parameter property="liquibase.force" + * + */ + protected String force; + + /** + * + * The path to a rollback script + * + * @parameter property="liquibase.rollbackScript" + * + */ + protected String rollbackScript; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + commandName = "rollbackOneChangeSet"; + super.execute(); + } + + @Override + protected void printSettings(String indent) { + super.printSettings(indent); + getLog().info(indent + "Rollback script: " + rollbackScript); + } + + @Override + protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseException { + // + // Check the Pro license + // + if (! hasProLicense()) { + throw new LiquibaseException("The command 'rollbackOneUpdate' requires a Liquibase Pro License, available at http://liquibase.org."); + } + Database database = liquibase.getDatabase(); + LiquibaseCommand liquibaseCommand = (CommandFactory.getInstance().getCommand("rollbackOneUpdate")); + AbstractSelfConfiguratingCommand configuratingCommand = (AbstractSelfConfiguratingCommand)liquibaseCommand; + Map argsMap = getCommandArgsObjectMap(liquibase); + ChangeLogParameters clp = new ChangeLogParameters(database); + argsMap.put("changeLogParameters", clp); + if (force == null || (force != null && ! Boolean.parseBoolean(force))) { + throw new LiquibaseException("Invalid value for --force. You must specify 'liquibase.force=true' to use rollbackOneUpdate."); + } + argsMap.put("force", Boolean.TRUE); + argsMap.put("liquibase", liquibase); + configuratingCommand.configure(argsMap); + try { + liquibaseCommand.execute(); + } + catch (CommandExecutionException cee) { + throw new LiquibaseException("Error executing rollbackOneUpdate", cee); + } + } + + private Map getCommandArgsObjectMap(Liquibase liquibase) throws LiquibaseException { + Database database = liquibase.getDatabase(); + Map argsMap = new HashMap(); + argsMap.put("deploymentId", this.deploymentId); + argsMap.put("force", this.force); + argsMap.put("rollbackScript", this.rollbackScript); + argsMap.put("database", database); + argsMap.put("changeLog", liquibase.getDatabaseChangeLog()); + argsMap.put("resourceAccessor", liquibase.getResourceAccessor()); + return argsMap; + } + +} From 7094d4e329d74d45733d7dd9a9409c68d4d9d22d Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Wed, 5 Feb 2020 18:15:11 -0600 Subject: [PATCH 02/17] Happy path rollback for an update (deployment ID) working for DAT-3917 --- .../liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java index 8013e3a951f..4017c6401ee 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java @@ -53,7 +53,7 @@ public class LiquibaseRollbackOneUpdateMojo extends AbstractLiquibaseChangeLogMo @Override public void execute() throws MojoExecutionException, MojoFailureException { - commandName = "rollbackOneChangeSet"; + commandName = "rollbackOneUpdate"; super.execute(); } From 0085ca2be6c2fbe702d3563419a249a747f1f172 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Tue, 11 Feb 2020 13:15:50 -0600 Subject: [PATCH 03/17] Implementation of targeted update rollback DAT-3917 --- .../liquibase/i18n/liquibase-core.properties | 2 + .../LiquibaseRollbackOneChangeSetSQL.java | 6 - .../LiquibaseRollbackOneUpdateSQL.java | 148 ++++++++++++++++++ 3 files changed, 150 insertions(+), 6 deletions(-) create mode 100644 liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java diff --git a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties index 929a57d1f87..b511018eebb 100644 --- a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties +++ b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties @@ -31,6 +31,8 @@ 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. 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. diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java index b0c8c69d9b4..9e3f3239ef2 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java @@ -138,8 +138,6 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti catch (IOException ioe) { LogService.getLog(getClass()).info(LogType.LOG, String.format("Unable to close output file")); } - finally { - } } } @@ -169,11 +167,7 @@ private Writer createOutputWriter() throws IOException { private Map getCommandArgsObjectMap(Liquibase liquibase) throws LiquibaseException { Database database = liquibase.getDatabase(); Map argsMap = new HashMap(); - argsMap.put("changeSetId", this.changeSetId); - argsMap.put("changeSetAuthor", this.changeSetAuthor); - argsMap.put("changeSetPath", this.changeSetPath); argsMap.put("force", true); - argsMap.put("rollbackScript", this.rollbackScript); argsMap.put("changeLogFile", this.changeLogFile); argsMap.put("database", database); argsMap.put("changeLog", liquibase.getDatabaseChangeLog()); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java new file mode 100644 index 00000000000..a58364838b4 --- /dev/null +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java @@ -0,0 +1,148 @@ +// Version: $Id: $ +// Copyright: Copyright(c) 2007 Trace Financial Limited +package org.liquibase.maven.plugins; + +import liquibase.Liquibase; +import liquibase.changelog.ChangeLogParameters; +import liquibase.command.AbstractSelfConfiguratingCommand; +import liquibase.command.CommandExecutionException; +import liquibase.command.CommandFactory; +import liquibase.command.LiquibaseCommand; +import liquibase.configuration.GlobalConfiguration; +import liquibase.configuration.LiquibaseConfiguration; +import liquibase.database.Database; +import liquibase.exception.LiquibaseException; +import liquibase.logging.LogService; +import liquibase.logging.LogType; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; +import java.util.ResourceBundle; + +import static java.util.ResourceBundle.getBundle; + +/** + * + * Invokes Liquibase rollback by Deployment ID + * + * @goal rollbackOneUpdateSQL + * + */ +public class LiquibaseRollbackOneUpdateSQL extends AbstractLiquibaseChangeLogMojo { + /** + * + * The Deployment ID to rollback + * + * @parameter property="liquibase.deploymentId" + * + */ + protected String deploymentId; + + /** + * + * Required flag for RollbackOneChangeSet + * + * @parameter property="liquibase.force" + * + */ + protected String force; + + /** + * + * Specifies the path to the generated SQL output file. + * + * @parameter property="liquibase.outputFile" + * + */ + protected String outputFile; + + private static ResourceBundle coreBundle = getBundle("liquibase/i18n/liquibase-core"); + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + commandName = "rollbackOneUpdate"; + super.execute(); + } + + @Override + protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseException { + // + // Check the Pro license + // + if (! hasProLicense()) { + throw new LiquibaseException("The command 'rollbackOneUpdateSQL' requires a Liquibase Pro License, available at http://liquibase.org."); + } + Database database = liquibase.getDatabase(); + LiquibaseCommand liquibaseCommand = (CommandFactory.getInstance().getCommand("rollbackOneUpdate")); + AbstractSelfConfiguratingCommand configuratingCommand = (AbstractSelfConfiguratingCommand)liquibaseCommand; + Map argsMap = getCommandArgsObjectMap(liquibase); + Writer outputWriter = null; + try { + outputWriter = createOutputWriter(); + argsMap.put("outputWriter", outputWriter); + } + catch (IOException ioe) { + throw new LiquibaseException("Error executing rollbackOneChangeSetSQL. Unable to create output writer.", ioe); + } + ChangeLogParameters clp = new ChangeLogParameters(database); + argsMap.put("changeLogParameters", clp); + if (force == null || (force != null && ! Boolean.parseBoolean(force))) { + throw new LiquibaseException("Invalid value for --force. You must specify 'liquibase.force=true' to use rollbackOneUpdate."); + } + argsMap.put("force", Boolean.TRUE); + argsMap.put("liquibase", liquibase); + configuratingCommand.configure(argsMap); + try { + liquibaseCommand.execute(); + } + catch (CommandExecutionException cee) { + throw new LiquibaseException("Error executing rollbackOneUpdate", cee); + } + finally { + try { + outputWriter.flush(); + outputWriter.close(); + } + catch (IOException ioe) { + LogService.getLog(getClass()).info(LogType.LOG, String.format("Unable to close output file")); + } + } + } + + private Writer createOutputWriter() throws IOException { + String charsetName = LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class) + .getOutputEncoding(); + + return new OutputStreamWriter(getOutputStream(), charsetName); + } + private OutputStream getOutputStream() throws IOException { + if (outputFile == null) { + return System.out; + } + FileOutputStream fileOut; + try { + fileOut = new FileOutputStream(outputFile, false); + } catch (IOException e) { + LogService.getLog(getClass()).severe(LogType.LOG, String.format( + coreBundle.getString("could.not.create.output.file"), + outputFile)); + throw e; + } + return fileOut; + } + + private Map getCommandArgsObjectMap(Liquibase liquibase) throws LiquibaseException { + Database database = liquibase.getDatabase(); + Map argsMap = new HashMap(); + argsMap.put("deploymentId", this.deploymentId); + argsMap.put("force", this.force); + argsMap.put("database", database); + argsMap.put("changeLog", liquibase.getDatabaseChangeLog()); + argsMap.put("resourceAccessor", liquibase.getResourceAccessor()); + return argsMap; + } + +} From a6c5b764699cfab0c5d89327d1293e6ba394ab51 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Thu, 13 Feb 2020 14:20:20 -0600 Subject: [PATCH 04/17] Implemented rollbackOneUpdate DAT-3916 --- .../main/java/liquibase/change/Change.java | 2 +- .../changelog/DatabaseChangeLog.java | 3 - .../integration/commandline/Main.java | 87 ++++++++++++++++--- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/change/Change.java b/liquibase-core/src/main/java/liquibase/change/Change.java index 555fa12ab72..ef4c8cdc097 100644 --- a/liquibase-core/src/main/java/liquibase/change/Change.java +++ b/liquibase-core/src/main/java/liquibase/change/Change.java @@ -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); diff --git a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java index f1105185cd3..969df50ae5b 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java +++ b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java @@ -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; @@ -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; diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 317caca36b4..2af777e56e1 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -44,7 +44,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; @@ -136,6 +135,7 @@ public class Main { protected String sqlFile; protected String delimiter; protected String rollbackScript; + protected String deploymentId; private static int[] suspiciousCodePoints = {160, 225, 226, 227, 228, 229, 230, 198, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 217, 218, 219, @@ -285,7 +285,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 setupMessages = main.checkSetup(); @@ -539,7 +541,8 @@ 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) @@ -547,7 +550,8 @@ private static boolean isChangeLogRequired(String 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); } /** @@ -598,7 +602,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); } /** @@ -857,7 +863,6 @@ private void checkForUnexpectedCommandParameter(List 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) @@ -869,7 +874,6 @@ private void checkForUnexpectedCommandParameter(List 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) @@ -879,6 +883,24 @@ private void checkForUnexpectedCommandParameter(List 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)); + } + } + } } /** @@ -1275,7 +1297,10 @@ 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); throw new LiquibaseException(messageString); @@ -1513,7 +1538,7 @@ 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)) { @@ -1521,7 +1546,42 @@ protected void doMigration() throws Exception { Map argsMap = new HashMap(); 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 argsMap = new HashMap(); + 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 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 argsMap = new HashMap(); + 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(); @@ -1711,9 +1771,9 @@ protected void doMigration() throws Exception { } } - private LiquibaseCommand createLiquibaseCommand(Database database, Liquibase liquibase, Map argsMap) + private LiquibaseCommand createLiquibaseCommand(Database database, Liquibase liquibase, String commandName, Map 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)); @@ -1895,6 +1955,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"; @@ -1928,6 +1990,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"; From e82e77315a8ef02b23e24112ac80eb08f9385a8b Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Fri, 14 Feb 2020 14:46:10 -0600 Subject: [PATCH 05/17] Modifications for PR and help --- .../java/liquibase/integration/commandline/Main.java | 1 - .../plugins/LiquibaseRollbackOneChangeSetMojo.java | 5 ++--- .../plugins/LiquibaseRollbackOneChangeSetSQL.java | 8 ++++---- .../maven/plugins/LiquibaseRollbackOneUpdateMojo.java | 10 ++++++---- .../maven/plugins/LiquibaseRollbackOneUpdateSQL.java | 9 +++++---- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 2af777e56e1..875b3350807 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -135,7 +135,6 @@ public class Main { protected String sqlFile; protected String delimiter; protected String rollbackScript; - protected String deploymentId; private static int[] suspiciousCodePoints = {160, 225, 226, 227, 228, 229, 230, 198, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 217, 218, 219, diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetMojo.java index 8c10370a8b5..6dc00a2fa74 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetMojo.java @@ -1,5 +1,3 @@ -// Version: $Id: $ -// Copyright: Copyright(c) 2007 Trace Financial Limited package org.liquibase.maven.plugins; import liquibase.Liquibase; @@ -90,7 +88,8 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti // // Check the Pro license // - if (! hasProLicense()) { + boolean hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); + if (! hasProLicense) { throw new LiquibaseException("The command 'rollbackOneChangeSet' requires a Liquibase Pro License, available at http://liquibase.org."); } Database database = liquibase.getDatabase(); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java index 9e3f3239ef2..38fbcbb9ee1 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java @@ -1,5 +1,3 @@ -// Version: $Id: $ -// Copyright: Copyright(c) 2007 Trace Financial Limited package org.liquibase.maven.plugins; import liquibase.Liquibase; @@ -26,7 +24,8 @@ /** * - * A helper command that allows you to inspect the SQL Liquibase will run to revert the changeSet specified in the rollbackOneChangeSet command. It is only available for Liquibase Pro users. + * Displays the SQL which will be executed when the corresponding rollbackOneChangeSet command is + * executed. This command does not perform the actual rollback. A Liquibase Pro license key is required. * * @goal rollbackOneChangeSetSQL * @@ -105,7 +104,8 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti // // Check the Pro license // - if (! hasProLicense()) { + boolean hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); + if (! hasProLicense) { throw new LiquibaseException("The command 'rollbackOneChangeSetSQL' requires a Liquibase Pro License, available at http://liquibase.org."); } Database database = liquibase.getDatabase(); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java index 4017c6401ee..9b2b9976249 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java @@ -1,5 +1,3 @@ -// Version: $Id: $ -// Copyright: Copyright(c) 2007 Trace Financial Limited package org.liquibase.maven.plugins; import liquibase.Liquibase; @@ -18,7 +16,10 @@ /** * - * Invokes Liquibase rollback by Deployment ID + * Reverts (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. A Liquibase Pro license key is required. + * Note: A list of deploymentIds may be viewed by using the "history" command. * * @goal rollbackOneUpdate * @@ -68,7 +69,8 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti // // Check the Pro license // - if (! hasProLicense()) { + boolean hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); + if (! hasProLicense) { throw new LiquibaseException("The command 'rollbackOneUpdate' requires a Liquibase Pro License, available at http://liquibase.org."); } Database database = liquibase.getDatabase(); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java index a58364838b4..6395e0e83d6 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java @@ -1,5 +1,3 @@ -// Version: $Id: $ -// Copyright: Copyright(c) 2007 Trace Financial Limited package org.liquibase.maven.plugins; import liquibase.Liquibase; @@ -26,7 +24,9 @@ /** * - * Invokes Liquibase rollback by Deployment ID + * Displays the SQL which will be executed when the corresponding rollbackOneUpdate + * command is executed. This command does not perform the actual rollback. + * A Liquibase Pro license key is required. * * @goal rollbackOneUpdateSQL * @@ -72,7 +72,8 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti // // Check the Pro license // - if (! hasProLicense()) { + boolean hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); + if (! hasProLicense) { throw new LiquibaseException("The command 'rollbackOneUpdateSQL' requires a Liquibase Pro License, available at http://liquibase.org."); } Database database = liquibase.getDatabase(); From 05db40cae4edae5c625e809f94175e40631c3478 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Mon, 17 Feb 2020 11:54:05 -0600 Subject: [PATCH 06/17] Global help changes Fixed error messages for targeted rollbacks --- .../i18n/liquibase-commandline-helptext.xml | 6 +++++ .../liquibase/i18n/liquibase-core.properties | 2 +- .../maven/plugins/AbstractLiquibaseMojo.java | 11 -------- .../LiquibaseRollbackOneUpdateMojo.java | 27 ++++--------------- .../LiquibaseRollbackOneUpdateSQL.java | 3 ++- 5 files changed, 14 insertions(+), 35 deletions(-) diff --git a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml index 81637b9953d..69abce2cb51 100644 --- a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml +++ b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml @@ -33,6 +33,12 @@ Standard Commands: rollbackOneChangeSetSQL 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 Rolls back the database to the the state is was at the given date/time. Date Format: yyyy-MM-dd'T'HH:mm:ss diff --git a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties index b511018eebb..d052bf1e847 100644 --- a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties +++ b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-core.properties @@ -29,7 +29,7 @@ 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. diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java index 913eb4014a2..b8a14243239 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java @@ -273,8 +273,6 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { */ private File driverPropertiesFile; - private boolean hasProLicense; - /** * * Specifies your Liquibase Pro license key. @@ -286,10 +284,6 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { protected String commandName; - protected boolean hasProLicense() { - return hasProLicense; - } - protected Writer getOutputWriter(final File outputFile) throws IOException { if (outputFileEncoding==null) { getLog().info("Char encoding not set! The created file will be system dependent!"); @@ -325,11 +319,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } - // - // Check for a LiquibasePro license - // - hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); - ClassLoader artifactClassLoader = getMavenArtifactClassLoader(); ResourceAccessor fileOpener = getFileOpener(artifactClassLoader); configureFieldsAndValues(fileOpener); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java index 9b2b9976249..81eb00bcacd 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java @@ -16,10 +16,9 @@ /** * - * Reverts (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. A Liquibase Pro license key is required. - * Note: A list of deploymentIds may be viewed by using the "history" command. + * Reverts (rolls back) all non-sequential change sets related by a specific deployment ID + * that were made during a previous change to your database in a non-sequential manner. + * It is only available for Liquibase Pro users. * * @goal rollbackOneUpdate * @@ -27,7 +26,7 @@ public class LiquibaseRollbackOneUpdateMojo extends AbstractLiquibaseChangeLogMojo { /** * - * The Deployment ID to rollback + * Specifies the Deployment ID you want to rollback * * @parameter property="liquibase.deploymentId" * @@ -36,34 +35,19 @@ public class LiquibaseRollbackOneUpdateMojo extends AbstractLiquibaseChangeLogMo /** * - * Required flag for RollbackOneChangeSet + * A required flag for rollbackOneUpdate. * * @parameter property="liquibase.force" * */ protected String force; - /** - * - * The path to a rollback script - * - * @parameter property="liquibase.rollbackScript" - * - */ - protected String rollbackScript; - @Override public void execute() throws MojoExecutionException, MojoFailureException { commandName = "rollbackOneUpdate"; super.execute(); } - @Override - protected void printSettings(String indent) { - super.printSettings(indent); - getLog().info(indent + "Rollback script: " + rollbackScript); - } - @Override protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseException { // @@ -98,7 +82,6 @@ private Map getCommandArgsObjectMap(Liquibase liquibase) throws Map argsMap = new HashMap(); argsMap.put("deploymentId", this.deploymentId); argsMap.put("force", this.force); - argsMap.put("rollbackScript", this.rollbackScript); argsMap.put("database", database); argsMap.put("changeLog", liquibase.getDatabaseChangeLog()); argsMap.put("resourceAccessor", liquibase.getResourceAccessor()); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java index 6395e0e83d6..dc5c9341f15 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java @@ -34,7 +34,8 @@ public class LiquibaseRollbackOneUpdateSQL extends AbstractLiquibaseChangeLogMojo { /** * - * The Deployment ID to rollback + * Specifies the Deployment ID in the DATABASECHANGELOG table for all change sets you + * want to rollback. * * @parameter property="liquibase.deploymentId" * From 8e14e585862b36054c85615fcee9f0201874f444 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Mon, 17 Feb 2020 12:36:20 -0600 Subject: [PATCH 07/17] Doc changes --- .../plugins/AbstractLiquibaseChangeLogMojo.java | 4 ++-- .../maven/plugins/AbstractLiquibaseMojo.java | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseChangeLogMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseChangeLogMojo.java index c29d5f30858..3643a50e068 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseChangeLogMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseChangeLogMojo.java @@ -23,14 +23,14 @@ public abstract class AbstractLiquibaseChangeLogMojo extends AbstractLiquibaseMojo { /** - * Specifies the directory where Liquibase can find your change-log file. + * Specifies the directory where Liquibase can find your changelog file. * * @parameter property="liquibase.changeLogDirectory" */ protected String changeLogDirectory; /** - * Specifies the change-log file for Liquibase to use. + * Specifies the changelog file for Liquibase to use. * @parameter property="liquibase.changeLogFile" */ protected String changeLogFile; diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java index b8a14243239..94023e0c8bd 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java @@ -131,20 +131,20 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { */ protected String propertyProviderClass; /** - * Controls whether users are prompted before executing changese to a non-local database. + * Controls whether users are prompted before executing changeSet to a non-local database. * * @parameter property="liquibase.promptOnNonLocalDatabase" default-value="true" */ protected boolean promptOnNonLocalDatabase; /** - * Includes a maven project artifcat in the class loader which obtains the Liquibase property and changeLog files. + * Includes a Maven project artifact in the class loader which obtains the liquibase.properties and changelog files. * * @parameter property="liquibase.includeArtifact" default-value="true" */ protected boolean includeArtifact; /** - * Includes the maven test output directory in the class loader which obtainst he Liquibase property and changeLog files. + * Includes the Maven test output directory in the class loader which obtains the liquibase.properties and changelog files. * * @parameter property="liquibase.includeTestOutputDirectory" default-value="true" */ @@ -186,7 +186,7 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { */ protected boolean clearCheckSums; /** - * A list of system properties you want to to pass to the database. + * Specifies a list of system properties you want to to pass to the database. * * @parameter */ @@ -202,7 +202,7 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { /** * Specifies whether to skip running Liquibase. - * The use of this parameter is NOT RECOMMENDED, but can be used when needed. + * The use of this parameter is NOT RECOMMENDED but can be used when needed. * * @parameter property="liquibase.skip" default-value="false" */ @@ -253,14 +253,14 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { private Liquibase liquibase; /** - * A property-based collection of changeLog properties to apply. + * A property-based collection of changelog properties to apply. * * @parameter */ private Properties expressionVars; /** - * A map-based collection of changeLog properties to apply. + * A map-based collection of changelog properties to apply. * * @parameter */ @@ -315,7 +315,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } if (skip) { - getLog().warn("Liquibase skipped due to maven configuration"); + getLog().warn("Liquibase skipped due to Maven configuration"); return; } From c61e5f6d78c824d219c64574baed8d2a6e069aaa Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Mon, 17 Feb 2020 13:03:08 -0600 Subject: [PATCH 08/17] Re-add code for Pro license check which should not have been removed --- .../liquibase/maven/plugins/AbstractLiquibaseMojo.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java index 94023e0c8bd..6b46d54ee15 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java @@ -273,6 +273,8 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { */ private File driverPropertiesFile; + private boolean hasProLicense; + /** * * Specifies your Liquibase Pro license key. @@ -284,6 +286,9 @@ public abstract class AbstractLiquibaseMojo extends AbstractMojo { protected String commandName; + protected boolean hasProLicense() { + return hasProLicense; + } protected Writer getOutputWriter(final File outputFile) throws IOException { if (outputFileEncoding==null) { getLog().info("Char encoding not set! The created file will be system dependent!"); @@ -319,6 +324,11 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } + // + // Check for a LiquibasePro license + // + hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); + ClassLoader artifactClassLoader = getMavenArtifactClassLoader(); ResourceAccessor fileOpener = getFileOpener(artifactClassLoader); configureFieldsAndValues(fileOpener); From 6d2344a247cd03353dc1edaef442cf75a3f68bd6 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Tue, 18 Feb 2020 07:40:14 -0600 Subject: [PATCH 09/17] Do not require --force for rollbackOneUpdateSQL --- .../maven/plugins/LiquibaseRollbackOneUpdateSQL.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java index dc5c9341f15..cb0256ba363 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java @@ -91,8 +91,8 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti } ChangeLogParameters clp = new ChangeLogParameters(database); argsMap.put("changeLogParameters", clp); - if (force == null || (force != null && ! Boolean.parseBoolean(force))) { - throw new LiquibaseException("Invalid value for --force. You must specify 'liquibase.force=true' to use rollbackOneUpdate."); + if (force != null && ! Boolean.parseBoolean(force)) { + throw new LiquibaseException("Invalid value for --force. You must specify 'liquibase.force=true' to use rollbackOneUpdateSQL."); } argsMap.put("force", Boolean.TRUE); argsMap.put("liquibase", liquibase); From fdf5c947416448158a69be6f866fd43d067767e1 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Tue, 18 Feb 2020 10:05:46 -0600 Subject: [PATCH 10/17] Turn down the log level of the Pro license check --- .../src/main/java/liquibase/license/LicenseServiceUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/license/LicenseServiceUtils.java b/liquibase-core/src/main/java/liquibase/license/LicenseServiceUtils.java index b4a9737d8e4..0cf890e9fbc 100644 --- a/liquibase-core/src/main/java/liquibase/license/LicenseServiceUtils.java +++ b/liquibase-core/src/main/java/liquibase/license/LicenseServiceUtils.java @@ -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(); } From 2689b3bd9d3016ea238f6c5a601571d0e177093f Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Tue, 18 Feb 2020 11:16:42 -0600 Subject: [PATCH 11/17] Re-worked last change for non-pro commands --- .../src/main/java/org/liquibase/maven/plugins/MavenUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/MavenUtils.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/MavenUtils.java index ca28d31017b..17362fe1d71 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/MavenUtils.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/MavenUtils.java @@ -99,7 +99,9 @@ public static boolean checkProLicense(String liquibaseProLicenseKey, String comm } if (liquibaseProLicenseKey == null) { log.info(""); - log.info("The command '" + commandName + "' requires a Liquibase Pro License, available at http://liquibase.org."); + if (commandName != null) { + log.info("The command '" + commandName + "' requires a Liquibase Pro License, available at http://liquibase.org."); + } log.info(""); hasProLicense = false; } From bb590b0bbad6fd7e6a7b9f98e57c0fe5a1f25a5e Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Tue, 18 Feb 2020 11:24:54 -0600 Subject: [PATCH 12/17] Moved Pro license check to after properties are ready --- .../liquibase/maven/plugins/AbstractLiquibaseMojo.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java index 6b46d54ee15..d42f8ed7ec0 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/AbstractLiquibaseMojo.java @@ -324,15 +324,15 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } + ClassLoader artifactClassLoader = getMavenArtifactClassLoader(); + ResourceAccessor fileOpener = getFileOpener(artifactClassLoader); + configureFieldsAndValues(fileOpener); + // // Check for a LiquibasePro license // hasProLicense = MavenUtils.checkProLicense(liquibaseProLicenseKey, commandName, getLog()); - ClassLoader artifactClassLoader = getMavenArtifactClassLoader(); - ResourceAccessor fileOpener = getFileOpener(artifactClassLoader); - configureFieldsAndValues(fileOpener); - // LogService.getInstance().setDefaultLoggingLevel(logging); getLog().info(CommandLineUtils.getBanner()); From cfc4166fd0491a9cf2f907563416e9d38965e315 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Wed, 19 Feb 2020 08:02:10 -0600 Subject: [PATCH 13/17] Do not close Writer if stdout --- .../maven/plugins/LiquibaseRollbackOneChangeSetSQL.java | 9 ++++++++- .../maven/plugins/LiquibaseRollbackOneUpdateSQL.java | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java index 38fbcbb9ee1..f1558d4990b 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneChangeSetSQL.java @@ -133,7 +133,7 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti finally { try { outputWriter.flush(); - outputWriter.close(); + closeOutputWriter(outputWriter); } catch (IOException ioe) { LogService.getLog(getClass()).info(LogType.LOG, String.format("Unable to close output file")); @@ -157,6 +157,13 @@ private OutputStream getOutputStream() throws IOException { return fileOut; } + private void closeOutputWriter(Writer outputWriter) throws IOException { + if (outputFile == null) { + return; + } + outputWriter.close(); + } + private Writer createOutputWriter() throws IOException { String charsetName = LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class) .getOutputEncoding(); diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java index cb0256ba363..e2c335e18a1 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java @@ -106,7 +106,7 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti finally { try { outputWriter.flush(); - outputWriter.close(); + closeOutputWriter(outputWriter); } catch (IOException ioe) { LogService.getLog(getClass()).info(LogType.LOG, String.format("Unable to close output file")); @@ -114,6 +114,13 @@ protected void performLiquibaseTask(Liquibase liquibase) throws LiquibaseExcepti } } + private void closeOutputWriter(Writer outputWriter) throws IOException { + if (outputFile == null) { + return; + } + outputWriter.close(); + } + private Writer createOutputWriter() throws IOException { String charsetName = LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class) .getOutputEncoding(); From 56335028abc158cd37d922cf3cc825ef77f73539 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Wed, 19 Feb 2020 10:14:52 -0600 Subject: [PATCH 14/17] Use correct command name in license check message --- .../src/main/java/liquibase/integration/commandline/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 9f4ec19c250..e73f21eef30 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -1304,7 +1304,7 @@ protected void doMigration() throws Exception { 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); } } From d5d3bd5141b614d342f6c83426e335ff0d5bf326 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Thu, 20 Feb 2020 10:20:41 -0600 Subject: [PATCH 15/17] Modified global help for history command --- .../liquibase/i18n/liquibase-commandline-helptext.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml index 74923babbb7..174fd136137 100644 --- a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml +++ b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml @@ -80,9 +80,10 @@ Diff Commands Documentation Commands dbDoc 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 'Tags' the current database state for future rollback tagExists Checks whether the given tag is already existing From 8bc98d94a0a4e038811fa663cc214cdeb4ed559e Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Thu, 20 Feb 2020 12:01:06 -0600 Subject: [PATCH 16/17] Remove curly quotes from help text --- .../liquibase/i18n/liquibase-commandline-helptext.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml index 174fd136137..8110487530a 100644 --- a/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml +++ b/liquibase-core/src/main/resources/liquibase/i18n/liquibase-commandline-helptext.xml @@ -82,8 +82,8 @@ Documentation Commands based on current database and change log 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. + by default according to their update command's + "deployment_id" value. Maintenance Commands tag 'Tags' the current database state for future rollback tagExists Checks whether the given tag is already existing From ce3f63eea569351d872b5db19331b6b405775ef7 Mon Sep 17 00:00:00 2001 From: Wesley Willard Date: Thu, 20 Feb 2020 14:44:39 -0600 Subject: [PATCH 17/17] Update docs --- .../maven/plugins/LiquibaseRollbackOneUpdateMojo.java | 9 +++++---- .../maven/plugins/LiquibaseRollbackOneUpdateSQL.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java index 81eb00bcacd..7c977b060ee 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateMojo.java @@ -16,9 +16,9 @@ /** * - * Reverts (rolls back) all non-sequential change sets related by a specific deployment ID - * that were made during a previous change to your database in a non-sequential manner. - * It is only available for Liquibase Pro users. + * Rolls back all changesets from any specific update, if all changesets can be rolled back. + * By default, the last update is rolled back, but an optional deployentId parameter can target any update. + * (Liquibase Pro only). * * @goal rollbackOneUpdate * @@ -26,7 +26,8 @@ public class LiquibaseRollbackOneUpdateMojo extends AbstractLiquibaseChangeLogMojo { /** * - * Specifies the Deployment ID you want to rollback + * Specifies the update your want to rollback. A list of the updates's + * changesets grouped by their deploymentId can be found by using the history command. * * @parameter property="liquibase.deploymentId" * diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java index e2c335e18a1..7a4f9b830df 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseRollbackOneUpdateSQL.java @@ -64,7 +64,7 @@ public class LiquibaseRollbackOneUpdateSQL extends AbstractLiquibaseChangeLogMoj @Override public void execute() throws MojoExecutionException, MojoFailureException { - commandName = "rollbackOneUpdate"; + commandName = "rollbackOneUpdateSQL"; super.execute(); }