Skip to content

Commit

Permalink
Merge pull request #1708 from liquibase/LB-1249-hooks
Browse files Browse the repository at this point in the history
Command Framework : Hooks Edition
  • Loading branch information
nvoxland committed May 6, 2021
2 parents 8e92ac7 + 4dd9279 commit 7fcfa09
Show file tree
Hide file tree
Showing 209 changed files with 12,650 additions and 2,406 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -12,6 +12,7 @@ release.properties
/out
/bin
**/liquibase.integrationtest.local.properties
**/liquibase.test.local.properties
derby.log
.idea
*.iml
Expand Down
11 changes: 7 additions & 4 deletions base.pom.xml
Expand Up @@ -70,6 +70,9 @@
<sonar.organization>liquibase-core</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.moduleKey>${artifactId}</sonar.moduleKey>
<groovy.version>2.4.17</groovy.version>
<dependency.spock.version>1.3-groovy-2.4</dependency.spock.version>
<junit.version>4.12</junit.version>

<gpg.passphrase>${ENV.GPG_PASSPHRASE}</gpg.passphrase>
</properties>
Expand All @@ -86,7 +89,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>

Expand Down Expand Up @@ -115,9 +118,9 @@
<dependency> <!-- use a specific Groovy version rather than the one specified by spock-core -->
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.17</version>
<type>pom</type>
<version>${groovy.version}</version>
<scope>test</scope>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
Expand All @@ -129,7 +132,7 @@
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.3-groovy-2.4</version>
<version>${dependency.spock.version}</version>
<scope>test</scope>
</dependency>

Expand Down
@@ -1,9 +1,22 @@
package liquibase.integration.commandline;

import liquibase.Scope;
import liquibase.command.CommandArgumentDefinition;
import liquibase.command.CommandFactory;
import liquibase.command.CommandScope;
import liquibase.configuration.ConfigurationDefinition;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.database.Database;
import liquibase.exception.CommandExecutionException;
import liquibase.exception.DatabaseException;
import liquibase.util.StringUtil;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;

public class NewMain {
Expand All @@ -14,5 +27,53 @@ public static void main(String[] args) {
for (ConfigurationDefinition def : definitions) {
System.out.println("See " + def.getKey() + " = " + def.getCurrentValue() + " -- " + def.getDescription());
}

Map<String, String> passedArgs = new HashMap<>();
passedArgs.put("url", "jdbc:mysql://127.0.0.1:33062/lbcat");
passedArgs.put("username", "lbuser");
passedArgs.put("password", "LiquibasePass1");

passedArgs.put("output", "/tmp/out.txt");


try {
CommandScope commandScope = new CommandScope("history");

for (CommandArgumentDefinition<Database> argument : commandScope.getCommand().getArguments(Database.class)) {
String prefix = argument.getName().replaceFirst("[dD]atabase", "");

Database database = createDatabase(passedArgs.get(prefixArg(prefix, "url")), passedArgs.get(prefixArg(prefix, "username")), passedArgs.get(prefixArg(prefix, "password")));

commandScope.addArgumentValue(argument, database);
}

FileOutputStream outputStream = null;
if (passedArgs.containsKey("output")) {
outputStream = new FileOutputStream(passedArgs.get("output"));
commandScope.setOutput(outputStream);
}

commandScope.execute();

if (outputStream != null) {
outputStream.close();
}

} catch (Exception e) {
e.printStackTrace();
}

}

private static Database createDatabase(String url, String username, String password) throws DatabaseException {
return CommandLineUtils.createDatabaseObject(Scope.getCurrentScope().getResourceAccessor(), url, username, password,
null, null, null, false, false, null, null, null, null, null, null,null);
}

private static String prefixArg(String prefix, String name) {
if (prefix == null || prefix.equals("")) {
return name;
}
return prefix+ StringUtil.upperCaseFirst(name);
}
}
35 changes: 12 additions & 23 deletions liquibase-core/src/main/java/liquibase/Liquibase.java
Expand Up @@ -5,10 +5,10 @@
import liquibase.changelog.*;
import liquibase.changelog.filter.*;
import liquibase.changelog.visitor.*;
import liquibase.command.CommandExecutionException;
import liquibase.exception.CommandExecutionException;
import liquibase.command.CommandFactory;
import liquibase.command.core.DropAllCommand;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.command.CommandScope;
import liquibase.command.core.InternalDropAllCommandStep;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.DatabaseFactory;
Expand Down Expand Up @@ -245,7 +245,6 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c
//
ChangeLogIterator changeLogIterator = getStandardChangelogIterator(contexts, labelExpression, changeLog);

Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
Connection connection = getConnection(changeLog);
if (connection != null) {
updateOperation =
Expand Down Expand Up @@ -1743,8 +1742,7 @@ public ChangeSetFilterResult accepts(ChangeSet changeSet) {
resetServices();
}

flushOutputWriter(
output);
flushOutputWriter(output);
}
});
}
Expand Down Expand Up @@ -1775,24 +1773,15 @@ public final void dropAll(CatalogAndSchema... schemas) throws DatabaseException

CatalogAndSchema[] finalSchemas = schemas;
try {
runInScope(new Scope.ScopedRunner() {
@Override
public void run() throws Exception {
final CommandFactory commandFactory = Scope.getCurrentScope().getSingleton(CommandFactory.class);

DropAllCommand dropAll = (DropAllCommand) commandFactory.getCommand("dropAll");
dropAll.setDatabase(Liquibase.this.getDatabase());
dropAll.setSchemas(finalSchemas);
dropAll.setLiquibase(Liquibase.this);
dropAll.setChangeLogFile(changeLogFile);
CommandScope dropAll = new CommandScope("internalDropAll")
.addArgumentValue(InternalDropAllCommandStep.DATABASE_ARG, Liquibase.this.getDatabase())
.addArgumentValue(InternalDropAllCommandStep.SCHEMAS_ARG, finalSchemas);

try {
commandFactory.execute(dropAll);
} catch (CommandExecutionException e) {
throw new DatabaseException(e);
}
}
});
try {
dropAll.execute();
} catch (CommandExecutionException e) {
throw new DatabaseException(e);
}
} catch (LiquibaseException e) {
if (e instanceof DatabaseException) {
throw (DatabaseException) e;
Expand Down
2 changes: 2 additions & 0 deletions liquibase-core/src/main/java/liquibase/Scope.java
Expand Up @@ -20,6 +20,8 @@
import liquibase.util.SmartMap;
import liquibase.util.StringUtil;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.nio.charset.Charset;
import java.util.*;
Expand Down
@@ -0,0 +1,119 @@
package liquibase.command;

import liquibase.Scope;
import liquibase.configuration.ConfiguredValue;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.exception.CommandExecutionException;
import liquibase.integration.IntegrationConfiguration;
import liquibase.util.StringUtil;

import java.util.*;
import java.util.logging.Level;

/**
* Convenience base class for {@link CommandStep}s that simply wrap calls to {@link liquibase.integration.commandline.Main}
*
* @deprecated
*/
public abstract class AbstractCliWrapperCommandStep extends AbstractCommandStep {

protected String[] createArgs(CommandScope commandScope) throws CommandExecutionException {
return createArgs(commandScope, new ArrayList<String>());
}

protected String[] createArgs(CommandScope commandScope, List<String> rhsArgs) throws CommandExecutionException {
List<String> argsList = new ArrayList<>();
Map<String, CommandArgumentDefinition<?>> arguments = commandScope.getCommand().getArguments();
arguments.entrySet().forEach( arg -> {
if (rhsArgs.contains(arg.getKey())) {
return;
}
String argValue = (commandScope.getArgumentValue(arg.getValue()) != null ? commandScope.getArgumentValue(arg.getValue()).toString() : null);
if (argValue != null) {
argsList.add("--" + arg.getKey() + "=" + commandScope.getArgumentValue(arg.getValue()).toString());
}
});


final Level logLevel = IntegrationConfiguration.LOG_LEVEL.getCurrentValue();
if (logLevel != null) {
argsList.add("--logLevel=" + logLevel);
}

String classpath = IntegrationConfiguration.CLASSPATH.getCurrentValue();
if (classpath != null) {
argsList.add("--classpath=" + classpath);
}

argsList.add(commandScope.getCommand().getName()[0]);
if (! rhsArgs.isEmpty()) {
arguments.entrySet().forEach(arg -> {
if (!rhsArgs.contains(arg.getKey())) {
return;
}
String argValue = (commandScope.getArgumentValue(arg.getValue()) != null ? commandScope.getArgumentValue(arg.getValue()).toString() : null);
if (argValue != null) {
argsList.add("--" + arg.getKey() + "=" + commandScope.getArgumentValue(arg.getValue()).toString());
}
});
}
String[] args = new String[argsList.size()];
argsList.toArray(args);
return args;
}

protected String[] createParametersFromArgs(String[] args, String ... params) {
List<String> argsList = new ArrayList(Arrays.asList(args));
List<String> toRemove = new ArrayList<>();
List<String> matchingArgs = new ArrayList<>();
for (String arg : argsList) {
for (String paramName : params) {
if (arg.startsWith(paramName) || arg.startsWith("--" + paramName)) {
String trimmed = arg.trim();
if (trimmed.charAt(trimmed.length()-1) == '=') {
trimmed = trimmed.replaceAll("=","");
}
if (paramName.startsWith("--")) {
matchingArgs.add(trimmed);
} else {
String[] parts = trimmed.split("=");
if (parts.length > 1) {
matchingArgs.add(parts[1]);
} else {
matchingArgs.add(trimmed);
}
}
toRemove.add(arg);
}
}
}

//
// Special handling for command parameters
//
if (matchingArgs.size() > 0) {
argsList.removeAll(toRemove);
argsList.remove(Collections.singleton(null));
args = new String[argsList.size() + matchingArgs.size()];
for (int i=0; i < argsList.size(); i++) {
args[i] = argsList.get(i);
}

int l = args.length - matchingArgs.size();
for (String matchingArg : matchingArgs) {
args[l] = matchingArg;
l++;
}
}
return args;
}

protected void addStatusMessage(CommandResultsBuilder resultsBuilder, int statusCode) {
if (statusCode == 0) {
resultsBuilder.addResult("statusMessage", "Successfully executed " + getName()[0]);
}
else {
resultsBuilder.addResult("statusMessage", "Unsuccessfully executed " + getName()[0]);
}
}
}
Expand Up @@ -3,6 +3,9 @@
import java.util.SortedSet;
import java.util.TreeSet;

/**
* @deprecated Implement commands with {@link liquibase.command.CommandStep} and call them with {@link liquibase.command.CommandFactory#getCommandDefinition(String...)}.
*/
public abstract class AbstractCommand<T extends CommandResult> implements LiquibaseCommand<T> {

@Override
Expand Down
@@ -0,0 +1,41 @@
package liquibase.command;

import liquibase.exception.CommandValidationException;
import liquibase.util.StringUtil;

import java.util.Arrays;

/**
* Convenience base class for {@link CommandStep} implementations.
*/
public abstract class AbstractCommandStep implements CommandStep {

/**
* @return {@link #ORDER_DEFAULT} if the command scope's name matches {@link #getName()}. Otherwise {@link #ORDER_NOT_APPLICABLE}
*/
@Override
public int getOrder(CommandDefinition commandDefinition) {
final String[] thisCommandName = getName();

if ((thisCommandName != null) && StringUtil.join(Arrays.asList(thisCommandName), " ").equalsIgnoreCase(StringUtil.join(Arrays.asList(commandDefinition.getName()), " "))) {
return ORDER_DEFAULT;
} else {
return ORDER_NOT_APPLICABLE;
}
}

/**
* Default implementation does no validation.
*/
@Override
public void validate(CommandScope commandScope) throws CommandValidationException {
}

/**
* Default implementation makes no changes
*/
@Override
public void adjustCommandDefinition(CommandDefinition commandDefinition) {

}
}

This file was deleted.

Expand Up @@ -2,6 +2,9 @@

import java.util.Objects;

/**
* @deprecated Used by the old {@link LiquibaseCommand} style of command setup.
*/
public class CommandArgument implements Comparable {

private String name;
Expand Down

0 comments on commit 7fcfa09

Please sign in to comment.