killbill-memoizeit
Changes
bin/db-helper 28(+26 -2)
util/pom.xml 24(+24 -0)
util/src/main/assembly/migrator.xml 28(+28 -0)
Details
bin/db-helper 28(+26 -2)
diff --git a/bin/db-helper b/bin/db-helper
index c642b1c..7b9c051 100755
--- a/bin/db-helper
+++ b/bin/db-helper
@@ -60,7 +60,7 @@ eval set -- "${ARGS}"
function usage() {
echo -n "./db_helper"
- echo -n " -a|--action <create|clean|dump>"
+ echo -n " -a|--action <create|clean|dump|migrate|dryRunMigrate|repair|info>"
echo -n " --driver <mysql|postgres> (default = mysql)"
echo -n " -h|--host host (default = localhost)"
echo -n " --port port"
@@ -159,6 +159,20 @@ function cleanup() {
rm -f "/tmp/*.$$"
}
+function flyway() {
+ flyway_bin=util/target/killbill-flyway.jar
+ if [ ! -f "$flyway_bin" ]; then
+ echo "File $flyway_bin does not exists - build util first"
+ usage
+ fi
+
+ locations=
+ for migration_dir in `find */src/main/resources -type d -name migration`; do
+ locations="${locations}filesystem:$migration_dir,"
+ done
+
+ java -jar $flyway_bin -locations=$locations -user=$USER -password=$PWD -url=$URL ${@}
+}
while true; do
case "$1" in
@@ -178,7 +192,7 @@ done
if [ -z $ACTION ]; then
- echo "Need to specify an action <CREATE|CLEAN|DUMP>"
+ echo "Need to specify an action"
usage
fi
@@ -195,6 +209,12 @@ fi
if [ $DRIVER == "postgres" ] && [ -z $PORT ]; then
PORT=$PORT_POSTGRES
fi
+if [ $DRIVER == "mysql" ] && [ -z $URL ]; then
+ URL=jdbc:mysql://$HOST:$PORT/$DATABASE
+fi
+if [ $DRIVER == "postgres" ] && [ -z $URL ]; then
+ URL=jdbc:postgresql://$HOST:$PORT/$DATABASE
+fi
if [ $ACTION == "dump" ]; then
@@ -233,4 +253,8 @@ if [ $ACTION == "clean" ]; then
fi
fi
+if [ $ACTION == "migrate" ] || [ $ACTION == "dryRunMigrate" ] || [ $ACTION == "repair" ] || [ $ACTION == "info" ]; then
+ flyway $ACTION
+fi
+
cleanup
util/pom.xml 24(+24 -0)
diff --git a/util/pom.xml b/util/pom.xml
index 0b7370e..04d9e7b 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -259,6 +259,30 @@
<build>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>assemble-migrator</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <finalName>killbill</finalName>
+ <archive>
+ <manifest>
+ <mainClass>org.killbill.billing.util.migration.Migrator</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <descriptor>src/main/assembly/migrator.xml</descriptor>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
util/src/main/assembly/migrator.xml 28(+28 -0)
diff --git a/util/src/main/assembly/migrator.xml b/util/src/main/assembly/migrator.xml
new file mode 100644
index 0000000..0e7eefe
--- /dev/null
+++ b/util/src/main/assembly/migrator.xml
@@ -0,0 +1,28 @@
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>flyway</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/</outputDirectory>
+ <useProjectArtifact>true</useProjectArtifact>
+ <unpack>true</unpack>
+ <scope>test</scope>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}/test-classes</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>**/*.class</include>
+ </includes>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/util/src/test/java/org/flywaydb/core/FlywayWithDryRun.java b/util/src/test/java/org/flywaydb/core/FlywayWithDryRun.java
index a8ae016..0cf27a2 100644
--- a/util/src/test/java/org/flywaydb/core/FlywayWithDryRun.java
+++ b/util/src/test/java/org/flywaydb/core/FlywayWithDryRun.java
@@ -54,7 +54,6 @@ public class FlywayWithDryRun extends Flyway {
final FlywayCallback[] flywayCallbacks) {
final Table metaDataDBTable = schemas[0].getTable(getTable());
- @SuppressWarnings("deprecation")
final DbMigrateWithDryRun dbMigrate = new DbMigrateWithDryRun(sqlStatements,
placeholderReplacer,
getEncoding(),
@@ -67,7 +66,7 @@ public class FlywayWithDryRun extends Flyway {
migrationResolver,
getTarget(),
isIgnoreFutureMigrations(),
- isIgnoreFailedFutureMigration(),
+ false,
isOutOfOrder(),
flywayCallbacks);
return dbMigrate.dryRunMigrate();
diff --git a/util/src/test/java/org/killbill/billing/util/migration/Migrator.java b/util/src/test/java/org/killbill/billing/util/migration/Migrator.java
index db378c8..0b5b6e8 100644
--- a/util/src/test/java/org/killbill/billing/util/migration/Migrator.java
+++ b/util/src/test/java/org/killbill/billing/util/migration/Migrator.java
@@ -17,34 +17,524 @@
package org.killbill.billing.util.migration;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.Properties;
import org.flywaydb.core.FlywayWithDryRun;
+import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.internal.dbsupport.SqlStatement;
+import org.flywaydb.core.internal.info.MigrationInfoDumper;
+import org.flywaydb.core.internal.util.ClassUtils;
+import org.flywaydb.core.internal.util.FileCopyUtils;
+import org.flywaydb.core.internal.util.StringUtils;
+import org.flywaydb.core.internal.util.VersionPrinter;
+import org.flywaydb.core.internal.util.logging.Log;
+import org.flywaydb.core.internal.util.logging.LogFactory;
+import org.flywaydb.core.internal.util.logging.console.ConsoleLog.Level;
+import org.flywaydb.core.internal.util.logging.console.ConsoleLogCreator;
+import org.flywaydb.core.internal.util.scanner.classpath.ClassPathResource;
+// Copied over from org.flywaydb.commandline.Main (not easily extensible unfortunately) to support dry-run
public class Migrator {
+ /**
+ * The property name for the directory containing a list of jars to load on the classpath.
+ */
+ private static final String PROPERTY_JAR_DIRS = "flyway.jarDirs";
+ private static Log LOG;
+
+ /**
+ * Initializes the logging.
+ *
+ * @param level The minimum level to log at.
+ */
+ private static void initLogging(final Level level) {
+ LogFactory.setLogCreator(new ConsoleLogCreator(level));
+ LOG = LogFactory.getLog(Migrator.class);
+ }
+
+ /**
+ * Main method.
+ *
+ * @param args The command-line arguments.
+ */
public static void main(final String[] args) {
- final List<SqlStatement> sqlStatements = new LinkedList<SqlStatement>();
+ final Level logLevel = getLogLevel(args);
+ initLogging(logLevel);
+
+ try {
+ if (isPrintVersionAndExit(args)) {
+ printVersion();
+ System.exit(0);
+ }
+
+ final List<String> operations = determineOperations(args);
+ if (operations.isEmpty()) {
+ printUsage();
+ return;
+ }
+
+ final Properties properties = new Properties();
+ initializeDefaults(properties);
+ loadConfiguration(properties, args);
+ overrideConfiguration(properties, args);
+ dumpConfiguration(properties);
+
+ loadJdbcDrivers();
+ loadJavaMigrationsFromJarDirs(properties);
+
+ final List<SqlStatement> sqlStatements = new LinkedList<SqlStatement>();
+ final FlywayWithDryRun flyway = new FlywayWithDryRun(sqlStatements);
+ filterProperties(properties);
+ flyway.configure(properties);
+
+ for (final String operation : operations) {
+ executeOperation(flyway, operation, sqlStatements);
+ }
+ } catch (final Exception e) {
+ if (logLevel == Level.DEBUG) {
+ LOG.error("Unexpected error", e);
+ } else {
+ if (e instanceof FlywayException) {
+ LOG.error(e.getMessage());
+ } else {
+ LOG.error(e.toString());
+ }
+ }
+ System.exit(1);
+ }
+ }
+
+ private static boolean isPrintVersionAndExit(final String[] args) {
+ for (final String arg : args) {
+ if ("-v".equals(arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Executes this operation on this Flyway instance.
+ *
+ * @param flyway The Flyway instance.
+ * @param operation The operation to execute.
+ * @param sqlStatements The current list of all pending migrations.
+ */
+ private static void executeOperation(final FlywayWithDryRun flyway, final String operation, final Iterable<SqlStatement> sqlStatements) {
+ if ("clean".equals(operation)) {
+ flyway.clean();
+ } else if ("baseline".equals(operation)) {
+ flyway.baseline();
+ } else if ("migrate".equals(operation)) {
+ flyway.migrate();
+ } else if ("dryRunMigrate".equals(operation)) {
+ flyway.dryRunMigrate();
+
+ final StringBuilder stringBuilder = new StringBuilder("BEGIN;\n");
+ for (final SqlStatement sqlStatement : sqlStatements) {
+ stringBuilder.append(sqlStatement.getSql())
+ .append(";\n");
+ }
+ stringBuilder.append("COMMIT;");
+ LOG.info("\n" + stringBuilder.toString());
+ } else if ("validate".equals(operation)) {
+ flyway.validate();
+ } else if ("info".equals(operation)) {
+ LOG.info("\n" + MigrationInfoDumper.dumpToAsciiTable(flyway.info().all()));
+ } else if ("repair".equals(operation)) {
+ flyway.repair();
+ } else {
+ LOG.error("Invalid operation: " + operation);
+ printUsage();
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Checks the desired log level.
+ *
+ * @param args The command-line arguments.
+ * @return The desired log level.
+ */
+ private static Level getLogLevel(final String[] args) {
+ for (final String arg : args) {
+ if ("-X".equals(arg)) {
+ return Level.DEBUG;
+ }
+ if ("-q".equals(arg)) {
+ return Level.WARN;
+ }
+ }
+ return Level.INFO;
+ }
- final FlywayWithDryRun flyway = new FlywayWithDryRun(sqlStatements);
- flyway.configure(System.getProperties());
+ /**
+ * Initializes the properties with the default configuration for the command-line tool.
+ *
+ * @param properties The properties object to initialize.
+ */
+ private static void initializeDefaults(final Properties properties) {
+ properties.put("flyway.locations", "filesystem:" + new File(getInstallationDir(), "sql").getAbsolutePath());
+ properties.put(PROPERTY_JAR_DIRS, new File(getInstallationDir(), "jars").getAbsolutePath());
+ }
+
+ /**
+ * Filters there properties to remove the Flyway Commandline-specific ones.
+ *
+ * @param properties The properties to filter.
+ */
+ private static void filterProperties(final Properties properties) {
+ properties.remove(PROPERTY_JAR_DIRS);
+ properties.remove("flyway.configFile");
+ properties.remove("flyway.configFileEncoding");
+ }
- flyway.dryRunMigrate();
- // Flush logs
- System.out.flush();
+ /**
+ * Prints the version number on the console.
+ *
+ * @throws IOException when the version could not be read.
+ */
+ private static void printVersion() throws IOException {
+ final String version = new ClassPathResource("org/flywaydb/core/internal/version.txt", VersionPrinter.class.getClassLoader()).loadAsString("UTF-8");
+ LOG.info("Flyway " + version + " for Kill Bill");
- if (sqlStatements.isEmpty()) {
+ LOG.debug("Java " + System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")");
+ LOG.debug(System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch") + "\n");
+ }
+
+ /**
+ * Prints the usage instructions on the console.
+ */
+ private static void printUsage() {
+ LOG.info("Usage");
+ LOG.info("=====");
+ LOG.info("");
+ LOG.info("flyway [options] command");
+ LOG.info("");
+ LOG.info("By default, the configuration will be read from conf/flyway.conf.");
+ LOG.info("Options passed from the command-line override the configuration.");
+ LOG.info("");
+ LOG.info("Commands");
+ LOG.info("--------");
+ LOG.info("migrate : Migrates the database");
+ LOG.info("dryRunMigrate : Migrates the database (dry-run)");
+ LOG.info("clean : Drops all objects in the configured schemas");
+ LOG.info("info : Prints the information about applied, current and pending migrations");
+ LOG.info("validate : Validates the applied migrations against the ones on the classpath");
+ LOG.info("baseline : Baselines an existing database at the baselineVersion");
+ LOG.info("repair : Repairs the metadata table");
+ LOG.info("");
+ LOG.info("Options (Format: -key=value)");
+ LOG.info("-------");
+ LOG.info("driver : Fully qualified classname of the jdbc driver");
+ LOG.info("url : Jdbc url to use to connect to the database");
+ LOG.info("user : User to use to connect to the database");
+ LOG.info("password : Password to use to connect to the database");
+ LOG.info("schemas : Comma-separated list of the schemas managed by Flyway");
+ LOG.info("table : Name of Flyway's metadata table");
+ LOG.info("locations : Classpath locations to scan recursively for migrations");
+ LOG.info("resolvers : Comma-separated list of custom MigrationResolvers");
+ LOG.info("skipDefaultResolvers : Skips default resolvers (jdbc, sql and Spring-jdbc)");
+ LOG.info("sqlMigrationPrefix : File name prefix for sql migrations");
+ LOG.info("repeatableSqlMigrationPrefix : File name prefix for repeatable sql migrations");
+ LOG.info("sqlMigrationSeparator : File name separator for sql migrations");
+ LOG.info("sqlMigrationSuffix : File name suffix for sql migrations");
+ LOG.info("encoding : Encoding of sql migrations");
+ LOG.info("placeholderReplacement : Whether placeholders should be replaced");
+ LOG.info("placeholders : Placeholders to replace in sql migrations");
+ LOG.info("placeholderPrefix : Prefix of every placeholder");
+ LOG.info("placeholderSuffix : Suffix of every placeholder");
+ LOG.info("target : Target version up to which Flyway should use migrations");
+ LOG.info("outOfOrder : Allows migrations to be run \"out of order\"");
+ LOG.info("callbacks : Comma-separated list of FlywayCallback classes");
+ LOG.info("skipDefaultCallbacks : Skips default callbacks (sql)");
+ LOG.info("validateOnMigrate : Validate when running migrate");
+ LOG.info("ignoreFutureMigrations : Allow future migrations when validating");
+ LOG.info("cleanOnValidationError : Automatically clean on a validation error");
+ LOG.info("cleanDisabled : Whether to disable clean");
+ LOG.info("baselineVersion : Version to tag schema with when executing baseline");
+ LOG.info("baselineDescription : Description to tag schema with when executing baseline");
+ LOG.info("baselineOnMigrate : Baseline on migrate against uninitialized non-empty schema");
+ LOG.info("configFile : Config file to use (default: conf/flyway.properties)");
+ LOG.info("configFileEncoding : Encoding of the config file (default: UTF-8)");
+ LOG.info("jarDirs : Dirs for Jdbc drivers & Java migrations (default: jars)");
+ LOG.info("");
+ LOG.info("Add -X to print debug output");
+ LOG.info("Add -q to suppress all output, except for errors and warnings");
+ LOG.info("Add -v to print the Flyway version and exit");
+ LOG.info("");
+ LOG.info("Example");
+ LOG.info("-------");
+ LOG.info("flyway -user=myuser -password=s3cr3t -url=jdbc:h2:mem -placeholders.abc=def migrate");
+ LOG.info("");
+ LOG.info("More info at https://flywaydb.org/documentation/commandline");
+ }
+
+ /**
+ * Loads all the driver jars contained in the drivers folder. (For Jdbc drivers)
+ *
+ * @throws IOException When the jars could not be loaded.
+ */
+ private static void loadJdbcDrivers() throws IOException {
+ final File driversDir = new File(getInstallationDir(), "drivers");
+ final File[] files = driversDir.listFiles(new FilenameFilter() {
+ public boolean accept(final File dir, final String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ // see javadoc of listFiles(): null if given path is not a real directory
+ if (files == null) {
return;
}
- final StringBuilder stringBuffer = new StringBuilder("BEGIN;\n");
- for (final SqlStatement sqlStatement : sqlStatements) {
- stringBuffer.append(sqlStatement.getSql())
- .append(";\n");
+ for (final File file : files) {
+ addJarOrDirectoryToClasspath(file.getPath());
+ }
+ }
+
+ /**
+ * Loads all the jars contained in the jars folder. (For Java Migrations)
+ * This will also indirectly load custom driver jars.
+ *
+ * @param properties The configured properties.
+ * @throws IOException When the jars could not be loaded.
+ */
+ private static void loadJavaMigrationsFromJarDirs(final Properties properties) throws IOException {
+ String jarDirs = properties.getProperty(PROPERTY_JAR_DIRS);
+ if (!StringUtils.hasLength(jarDirs)) {
+ return;
+ }
+
+ jarDirs = jarDirs.replace(File.pathSeparator, ",");
+ final String[] dirs = StringUtils.tokenizeToStringArray(jarDirs, ",");
+
+ for (final String dirName : dirs) {
+ final File dir = new File(dirName);
+ final File[] files = dir.listFiles(new FilenameFilter() {
+ public boolean accept(final File dir, final String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ // see javadoc of listFiles(): null if given path is not a real directory
+ if (files == null) {
+ continue;
+ }
+
+ for (final File file : files) {
+ addJarOrDirectoryToClasspath(file.getPath());
+ }
+ }
+ }
+
+ /**
+ * Adds a jar or a directory with this name to the classpath.
+ *
+ * @param name The name of the jar or directory to add.
+ * @throws IOException when the jar or directory could not be found.
+ */
+ private static void addJarOrDirectoryToClasspath(final String name) throws IOException {
+ LOG.debug("Adding location to classpath: " + name);
+
+ try {
+ final URL url = new File(name).toURI().toURL();
+ final URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
+ final Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
+ method.setAccessible(true);
+ method.invoke(sysloader, url);
+ } catch (final Exception e) {
+ throw new FlywayException("Unable to load " + name, e);
+ }
+ }
+
+ /**
+ * Loads the configuration from the various possible locations.
+ *
+ * @param properties The properties object to load to configuration into.
+ * @param args The command-line arguments passed in.
+ */
+ private static void loadConfiguration(final Properties properties, final String[] args) {
+ final String encoding = determineConfigurationFileEncoding(args);
+
+ loadConfigurationFile(properties, getInstallationDir() + "/conf/flyway.conf", encoding, false);
+ loadConfigurationFile(properties, System.getProperty("user.home") + "/flyway.conf", encoding, false);
+ loadConfigurationFile(properties, "flyway.conf", encoding, false);
+
+ final String configFile = determineConfigurationFileArgument(args);
+ if (configFile != null) {
+ loadConfigurationFile(properties, configFile, encoding, true);
+ }
+ }
+
+ /**
+ * Loads the configuration from the configuration file. If a configuration file is specified using the -configfile
+ * argument it will be used, otherwise the default config file (conf/flyway.properties) will be loaded.
+ *
+ * @param properties The properties object to load to configuration into.
+ * @param file The configuration file to load.
+ * @param encoding The encoding of the configuration file.
+ * @param failIfMissing Whether to fail if the file is missing.
+ * @return Whether the file was loaded successfully.
+ * @throws FlywayException when the configuration file could not be loaded.
+ */
+ private static boolean loadConfigurationFile(final Properties properties, final String file, final String encoding, final boolean failIfMissing) throws FlywayException {
+ final File configFile = new File(file);
+ final String errorMessage = "Unable to load config file: " + configFile.getAbsolutePath();
+
+ if (!configFile.isFile() || !configFile.canRead()) {
+ if (!failIfMissing) {
+ LOG.debug(errorMessage);
+ return false;
+ }
+ throw new FlywayException(errorMessage);
+ }
+
+ LOG.debug("Loading config file: " + configFile.getAbsolutePath());
+ try {
+ final String contents = FileCopyUtils.copyToString(new InputStreamReader(new FileInputStream(configFile), encoding));
+ properties.load(new StringReader(contents.replace("\\", "\\\\")));
+ return true;
+ } catch (final IOException e) {
+ throw new FlywayException(errorMessage, e);
+ }
+ }
+
+ /**
+ * Dumps the configuration to the console when debug output is activated.
+ *
+ * @param properties The configured properties.
+ */
+ private static void dumpConfiguration(final Properties properties) {
+ LOG.debug("Using configuration:");
+ for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
+ String value = entry.getValue().toString();
+ value = "flyway.password".equals(entry.getKey()) ? StringUtils.trimOrPad("", value.length(), '*') : value;
+ LOG.debug(entry.getKey() + " -> " + value);
+ }
+ }
+
+ /**
+ * Determines the file to use for loading the configuration.
+ *
+ * @param args The command-line arguments passed in.
+ * @return The path of the configuration file on disk.
+ */
+ private static String determineConfigurationFileArgument(final String[] args) {
+ for (final String arg : args) {
+ if (isPropertyArgument(arg) && "configFile".equals(getArgumentProperty(arg))) {
+ return getArgumentValue(arg);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @return The installation directory of the Flyway Command-line tool.
+ */
+ @SuppressWarnings("ConstantConditions")
+ private static String getInstallationDir() {
+ final String path = ClassUtils.getLocationOnDisk(Migrator.class);
+ return new File(path).getParentFile().getParentFile().getAbsolutePath();
+ }
+
+ /**
+ * Determines the encoding to use for loading the configuration.
+ *
+ * @param args The command-line arguments passed in.
+ * @return The encoding. (default: UTF-8)
+ */
+ private static String determineConfigurationFileEncoding(final String[] args) {
+ for (final String arg : args) {
+ if (isPropertyArgument(arg) && "configFileEncoding".equals(getArgumentProperty(arg))) {
+ return getArgumentValue(arg);
+ }
+ }
+
+ return "UTF-8";
+ }
+
+ /**
+ * Overrides the configuration from the config file with the properties passed in directly from the command-line.
+ *
+ * @param properties The properties to override.
+ * @param args The command-line arguments that were passed in.
+ */
+ private static void overrideConfiguration(final Properties properties, final String[] args) {
+ for (final String arg : args) {
+ if (isPropertyArgument(arg)) {
+ properties.put("flyway." + getArgumentProperty(arg), getArgumentValue(arg));
+ }
}
- stringBuffer.append("COMMIT;");
- System.out.println(stringBuffer.toString());
+ }
+
+ /**
+ * Checks whether this command-line argument tries to set a property.
+ *
+ * @param arg The command-line argument to check.
+ * @return {@code true} if it does, {@code false} if not.
+ */
+ private static boolean isPropertyArgument(final String arg) {
+ return arg.startsWith("-") && arg.contains("=");
+ }
+
+ /**
+ * Retrieves the property this command-line argument tries to assign.
+ *
+ * @param arg The command-line argument to check, typically in the form -key=value.
+ * @return The property.
+ */
+ private static String getArgumentProperty(final String arg) {
+ final int index = arg.indexOf("=");
+
+ return arg.substring(1, index);
+ }
+
+ /**
+ * Retrieves the value this command-line argument tries to assign.
+ *
+ * @param arg The command-line argument to check, typically in the form -key=value.
+ * @return The value or an empty string if no value is assigned.
+ */
+ private static String getArgumentValue(final String arg) {
+ final int index = arg.indexOf("=");
+
+ if ((index < 0) || (index == arg.length())) {
+ return "";
+ }
+
+ return arg.substring(index + 1);
+ }
+
+ /**
+ * Determine the operations Flyway should execute.
+ *
+ * @param args The command-line arguments passed in.
+ * @return The operations. An empty list if none.
+ */
+ private static List<String> determineOperations(final String[] args) {
+ final List<String> operations = new ArrayList<String>();
+
+ for (final String arg : args) {
+ if (!arg.startsWith("-")) {
+ operations.add(arg);
+ }
+ }
+
+ return operations;
}
}