private void checkForMalformedCommandParameters(final List<String> messages) {
        if (commandParams.isEmpty()) {
            return;
        }

        final int CHANGESET_MINIMUM_IDENTIFIER_PARTS = 3;

        if (COMMANDS.CALCULATE_CHECKSUM.equalsIgnoreCase(command)) {
            for (final String param : commandParams) {
                if ((param != null) && !param.startsWith("-")) {
                    final String[] parts = param.split("::");
                    if (parts.length < CHANGESET_MINIMUM_IDENTIFIER_PARTS) {
                        messages.add(coreBundle.getString("changeset.identifier.must.have.form.filepath.id.author"));
                        break;
                    }
                }
            }
        } else if (COMMANDS.DIFF_CHANGELOG.equalsIgnoreCase(command) && (diffTypes != null) && diffTypes.toLowerCase
                ().contains("data")) {
            messages.add(String.format(coreBundle.getString("including.data.diffchangelog.has.no.effect"),
                    OPTIONS.DIFF_TYPES, COMMANDS.GENERATE_CHANGELOG
            ));
        }
    }

Checks for incorrectly written command line parameters and, if any problems are found,
returns the list of issues in String form.

@param messages an array of Strings to which messages for issues found will be added

Checks for incorrectly written command line parameters and if any problems are found returns the list of issues in String form .


protected void parsePropertiesFile(InputStream propertiesInputStream) throws IOException,
            CommandLineParsingException {
        Properties props = new Properties();
        props.load(propertiesInputStream);
        if (props.containsKey("strict")) {
            strict = Boolean.valueOf(props.getProperty("strict"));
        }

        for (Map.Entry entry : props.entrySet()) {
            try {
                if ("promptOnNonLocalDatabase".equals(entry.getKey())) {
                    continue;
                }
                if (((String) entry.getKey()).startsWith("parameter.")) {
                    changeLogParameters.put(((String) entry.getKey()).replaceFirst("^parameter.", ""), entry.getValue
                            ());
                } else {
                    Field field = getClass().getDeclaredField((String) entry.getKey());
                    Object currentValue = field.get(this);

                    if (currentValue == null) {
                        String value = entry.getValue().toString().trim();
                        if (field.getType().equals(Boolean.class)) {
                            field.set(this, Boolean.valueOf(value));
                        } else {
                            field.set(this, value);
                        }
                    }
                }
            } catch (NoSuchFieldException ignored) {
                if (strict) {
                    throw new CommandLineParsingException(
                            String.format(coreBundle.getString("parameter.unknown"), entry.getKey())
                    );
                } else {
                    Scope.getCurrentScope().getLog(getClass()).warning(
                            LogType.LOG, String.format(coreBundle.getString("parameter.ignored"), entry.getKey())
                    );
                }
            } catch (IllegalAccessException e) {
                throw new UnexpectedLiquibaseException(
                        String.format(coreBundle.getString("parameter.unknown"), entry.getKey())
                );
            }
        }
    }

protected void parsePropertiesFile ( InputStream propertiesInputStream ) throws IOException , CommandLineParsingException { Properties props = new Properties ( ) ; props . load ( propertiesInputStream ) ; if ( props . containsKey ( "strict" ) ) { strict = Boolean . valueOf ( props . getProperty ( "strict" ) ) ; } for ( Map . Entry entry : props . entrySet ( ) ) { try { if ( "promptOnNonLocalDatabase" . equals ( entry . getKey ( ) ) ) { continue ; } if ( ( ( String ) entry . getKey ( ) ) . startsWith ( "parameter." ) ) { changeLogParameters . put ( ( ( String ) entry . getKey ( ) ) . replaceFirst ( "^parameter." , "" ) , entry . getValue ( ) ) ; } else { Field field = getClass ( ) . getDeclaredField ( ( String ) entry . getKey ( ) ) ; Object currentValue = field . get ( this ) ; if ( currentValue == null ) { String value = entry . getValue ( ) . toString ( ) . trim ( ) ; if ( field . getType ( ) . equals ( Boolean . class ) ) { field . set ( this , Boolean . valueOf ( value ) ) ; } else { field . set ( this , value ) ; } } } } catch ( NoSuchFieldException ignored ) { if ( strict ) { throw new CommandLineParsingException ( String . format ( coreBundle . getString ( "parameter.unknown" ) , entry . getKey ( ) ) ) ; } else { Scope . getCurrentScope ( ) . getLog ( getClass ( ) ) . warning ( LogType . LOG , String . format ( coreBundle . getString ( "parameter.ignored" ) , entry . getKey ( ) ) ) ; } } catch ( IllegalAccessException e ) { throw new UnexpectedLiquibaseException ( String . format ( coreBundle . getString ( "parameter.unknown" ) , entry . getKey ( ) ) ) ; } } }

Reads various execution parameters from an InputStream and sets our internal state according to the values
found.

@param propertiesInputStream an InputStream from a Java properties file
@throws IOException                 if there is a problem reading the InputStream
@throws CommandLineParsingException if an invalid property is encountered

Reads various execution parameters from an InputStream and sets our internal state according to the values found .


protected void printHelp(List<String> errorMessages, PrintStream stream) {
        stream.println(coreBundle.getString("errors"));
        for (String message : errorMessages) {
            stream.println("  " + message);
        }
        stream.println();
    }

protected
void
printHelp
(
List
<
String
>
errorMessages
,
PrintStream
stream
)
{
stream
.
println
(
coreBundle
.
getString
(
"errors"
)
)
;
for
(
String
message
:
errorMessages
)
{
stream
.
println
(
"  "
+
message
)
;
}
stream
.
println
(
)
;
}

If any errors have been found, print the list of errors first, then print the command line help text.

@param errorMessages List of error messages
@param stream        the output stream to write the text to

If any errors have been found print the list of errors first then print the command line help text .


protected void printHelp(PrintStream stream) {
        String helpText = commandLineHelpBundle.getString("commandline-helptext");
        stream.println(helpText);
    }

protected void printHelp ( PrintStream stream ) { String helpText = commandLineHelpBundle . getString ( "commandline-helptext" ) ; stream . println ( helpText ) ; }

Print instructions on how to use this program from the command line.

@param stream the output stream to write the help text to

Print instructions on how to use this program from the command line .


protected void parseOptions(String[] paramArgs) throws CommandLineParsingException {
        String[] args = fixupArgs(paramArgs);

        boolean seenCommand = false;
        for (String arg : args) {

            if (isCommand(arg)) {
                this.command = arg;
                if (this.command.equalsIgnoreCase(COMMANDS.MIGRATE)) {
                    this.command = COMMANDS.UPDATE;
                } else if (this.command.equalsIgnoreCase(COMMANDS.MIGRATE_SQL)) {
                    this.command = COMMANDS.UPDATE_SQL;
                }
                seenCommand = true;
            } else if (seenCommand) {
                // ChangeLog parameter:
                if (arg.startsWith("-D")) {
                    String[] splitArg = splitArg(arg);

                    String attributeName = splitArg[0].replaceFirst("^-D", "");
                    String value = splitArg[1];

                    changeLogParameters.put(attributeName, value);
                } else {
                    commandParams.add(arg);
                    if (arg.startsWith("--")) {
                        parseOptionArgument(arg);
                    }
                }
            } else if (arg.startsWith("--")) {
                parseOptionArgument(arg);
            } else {
                throw new CommandLineParsingException(
                        String.format(coreBundle.getString("unexpected.value"), arg));
            }
        }

        // Now apply default values from the default property files. We waited with this until this point
        // since command line parameters might have changed the location where we will look for them.
        parseDefaultPropertyFiles();
    }

Parses the command line options. If an invalid argument is given, a CommandLineParsingException is thrown.

@param paramArgs the arguments to parse
@throws CommandLineParsingException thrown if an invalid argument is passed

Parses the command line options . If an invalid argument is given a CommandLineParsingException is thrown .


private String getCommandParam(String paramName, String defaultValue) throws CommandLineParsingException {
        for (String param : commandParams) {
            if (!param.contains("=")) {
                continue;
            }
            String[] splitArg = splitArg(param);

            String attributeName = splitArg[0];
            String value = splitArg[1];
            if (attributeName.equalsIgnoreCase(paramName)) {
                return value;
            }
        }

        return defaultValue;
    }

private String getCommandParam ( String paramName , String defaultValue ) throws CommandLineParsingException { for ( String param : commandParams ) { if ( ! param . contains ( "=" ) ) { continue ; } String [ ] splitArg = splitArg ( param ) ; String attributeName = splitArg [ 0 ] ; String value = splitArg [ 1 ] ; if ( attributeName . equalsIgnoreCase ( paramName ) ) { return value ; } } return defaultValue ; }

Returns the value for a command line parameter of the form parameterName=value, or defaultValue if that
parameter has not been specified by the user.

@param paramName    name of the parameter
@param defaultValue return value if parameter is not given
@return the user-specified value for paramName, or defaultValue
@throws CommandLineParsingException if a parameter on the command line is un-parsable

Returns the value for a command line parameter of the form parameterName = value or defaultValue if that parameter has not been specified by the user .


public static Integer readInteger(String value) {
        if (value == null) {
            return null;
        }
        return Integer.valueOf(value);
    }

public static Integer readInteger ( String value ) { if ( value == null ) { return null ; } return Integer . valueOf ( value ) ; }

Convenience method for converting a string to an Integer object
@param value string value
@return Null if the value is null, otherwise the converted integer


public boolean matches(Labels runtimeLabels) {
        if ((runtimeLabels == null) || runtimeLabels.isEmpty()) {
            return true;
        }
        if (this.labels.isEmpty()) {
            return true;
        }

        for (String expression : this.labels) {
            if (matches(expression, runtimeLabels)) {
                return true;
            }
        }
        return false;
    }

public boolean matches ( Labels runtimeLabels ) { if ( ( runtimeLabels == null ) || runtimeLabels . isEmpty ( ) ) { return true ; } if ( this . labels . isEmpty ( ) ) { return true ; } for ( String expression : this . labels ) { if ( matches ( expression , runtimeLabels ) ) { return true ; } } return false ; }

Returns true if the passed runtime labels match this label expression


public boolean has(DatabaseObject example, Database database) throws DatabaseException, InvalidExampleException {
        // @todo I have seen duplicates in types - maybe convert the List into a Set? Need to understand it more thoroughly.
        List<Class<? extends DatabaseObject>> types = new ArrayList<>(getContainerTypes(example.getClass(), database));
        types.add(example.getClass());

        /*
         * Does the query concern the DATABASECHANGELOG / DATABASECHANGELOGLOCK table? If so, we do a quick & dirty
         * SELECT COUNT(*) on that table. If that works, we count that as confirmation of existence.
         */
        // @todo Actually, there may be extreme cases (distorted table statistics etc.) where a COUNT(*) might not be so cheap. Maybe SELECT a dummy constant is the better way?
        if ((example instanceof Table) && (example.getName().equals(database.getDatabaseChangeLogTableName()) ||
            example.getName().equals(database.getDatabaseChangeLogLockTableName()))) {
            try {
                ExecutorService.getInstance().getExecutor(database).queryForInt(
                        new RawSqlStatement("SELECT COUNT(*) FROM " +
                                database.escapeObjectName(database.getLiquibaseCatalogName(),
                                        database.getLiquibaseSchemaName(), example.getName(), Table.class)));
                return true;
            } catch (DatabaseException e) {
                if (database instanceof PostgresDatabase) { // throws "current transaction is aborted" unless we roll back the connection
                    database.rollback();
                }
                return false;
            }
        }

        /*
          * If the query is about another object, try to create a snapshot of the of the object (or used the cached
          * snapshot. If that works, we count that as confirmation of existence.
          */

        SnapshotControl snapshotControl = (new SnapshotControl(database, false, types.toArray(new Class[types.size()])));
        snapshotControl.setWarnIfObjectNotFound(false);

        if (createSnapshot(example, database,snapshotControl) != null) {
            return true;
        }
        CatalogAndSchema catalogAndSchema;
        if (example.getSchema() == null) {
            catalogAndSchema = database.getDefaultSchema();
        } else {
            catalogAndSchema = example.getSchema().toCatalogAndSchema();
        }
        DatabaseSnapshot snapshot = createSnapshot(catalogAndSchema, database,
            new SnapshotControl(database, false, example.getClass()).setWarnIfObjectNotFound(false)
        );

        for (DatabaseObject obj : snapshot.get(example.getClass())) {
            if (DatabaseObjectComparatorFactory.getInstance().isSameObject(example, obj, null, database)) {
                return true;
            }
        }
        return false;
    }

Checks if a specific object is present in a database
@param example The DatabaseObject to check for existence
@param database The DBMS in which the object might exist
@return true if object existence can be confirmed, false otherweise
@throws DatabaseException If a problem occurs in the DBMS-specific code
@throws InvalidExampleException If the object cannot be checked properly, e.g. if the object name is ambiguous


public DatabaseSnapshot createSnapshot(DatabaseObject[] examples, Database database,
                                           SnapshotControl snapshotControl)
            throws DatabaseException, InvalidExampleException {
        DatabaseConnection conn = database.getConnection();
        if (conn == null) {
            return new EmptyDatabaseSnapshot(database, snapshotControl);
        }
        if (conn instanceof OfflineConnection) {
            DatabaseSnapshot snapshot = ((OfflineConnection) conn).getSnapshot(examples);
            if (snapshot == null) {
                throw new DatabaseException("No snapshotFile parameter specified for offline database");
            }
            return snapshot;
        }
        return new JdbcDatabaseSnapshot(examples, database, snapshotControl);
    }

Creates a database snapshot for a given array of DatabaseObjects

@param examples        an array of DatabaseObjects objects
@param database        the database to work on
@param snapshotControl the options/settings for snapshot generation
@return a database snapshot that includes all objects matching the specification
@throws DatabaseException       if a problem occurs during snapshotting
@throws InvalidExampleException if the given catalog/schema combinations are invalid (e.g. duplicates)


public <T extends DatabaseObject> T createSnapshot(T example, Database database) throws DatabaseException, InvalidExampleException {
        return createSnapshot(example, database, new SnapshotControl(database));
    }

public < T extends DatabaseObject > T createSnapshot ( T example , Database database ) throws DatabaseException , InvalidExampleException { return createSnapshot ( example , database , new SnapshotControl ( database ) ) ; }

Creates a DatabaseSnapshot for a single DatabaseObject.
@param example the object to snapshot
@param database the database to work on
@param <T> the type of the object (must extend DatabaseObject)
@return the snapshot of the desired object
@throws DatabaseException if a problem occurs during snapshotting
@throws InvalidExampleException if the given catalog/schema combinations are invalid (e.g. duplicates)

Creates a DatabaseSnapshot for a single DatabaseObject .


private List<DropForeignKeyConstraintChange> generateChildren(Database database) {
        // Make a new list
        List<DropForeignKeyConstraintChange> childDropChanges = new ArrayList<>();

        try {
            SnapshotControl control = new SnapshotControl(database);
            control.getTypesToInclude().add(ForeignKey.class);
            CatalogAndSchema catalogAndSchema =
                    new CatalogAndSchema(getBaseTableCatalogName(), getBaseTableSchemaName());
            catalogAndSchema = catalogAndSchema.standardize(database);
            Table target = SnapshotGeneratorFactory.getInstance().createSnapshot(
                    new Table(catalogAndSchema.getCatalogName(), catalogAndSchema.getSchemaName(),
                            database.correctObjectName(getBaseTableName(), Table.class))
                    , database);

            List<ForeignKey> results = ((target == null) ? null : target.getOutgoingForeignKeys());
            Set<String> handledConstraints = new HashSet<>();

            if ((results != null) && (!results.isEmpty())) {
                for (ForeignKey fk : results) {
                    Table baseTable = fk.getForeignKeyTable();
                    String constraintName = fk.getName();
                    if (DatabaseObjectComparatorFactory.getInstance().isSameObject(
                            baseTable,
                            target,
                            null,
                            database
                    )) {
                        if( !handledConstraints.contains(constraintName)) {
                            DropForeignKeyConstraintChange dropForeignKeyConstraintChange =
                                    new DropForeignKeyConstraintChange();

                            dropForeignKeyConstraintChange.setBaseTableSchemaName(getBaseTableSchemaName());
                            dropForeignKeyConstraintChange.setBaseTableName(baseTableName);
                            dropForeignKeyConstraintChange.setConstraintName(constraintName);

                            childDropChanges.add(dropForeignKeyConstraintChange);
                            handledConstraints.add(constraintName);
                        }
                    } else {
                        throw new UnexpectedLiquibaseException(
                                "Expected to return only foreign keys for base table name: " +
                                        getBaseTableName() + " and got results for table: " + baseTableName);
                    }
                }
            }

            return childDropChanges;

        } catch (DatabaseException | InvalidExampleException e) {
            throw new UnexpectedLiquibaseException("Failed to find foreign keys for table: " + getBaseTableName(), e);
        }
    }

Iterates through all the FOREIGN KEYs of the target table and outputs a list of DropForeignKeyConstraintChanges
for a given database type.

@param database the database type for which subchanges need to be generated
@return the list of generated DropForeignKeyConstraintChanges

Iterates through all the FOREIGN KEYs of the target table and outputs a list of DropForeignKeyConstraintChanges for a given database type .


private static void cleanDirectory(final File directory) throws IOException {
        if ( !directory.exists() ) {
            return;
        }

        if ( !directory.isDirectory() ) {
            return;
        }

        IOException exception = null;

        final File[] files = directory.listFiles();
        if (files != null) {
            for (final File file : files) {
                try {
                    cleanDirectory(file);
                    if (!file.delete()) {
                        throw new IOException("Cannot delete "+file.getAbsolutePath());
                    }
                } catch (final IOException ioe) {
                    exception = ioe;
                }
            }
        }

        if ( null != exception ) {
            throw exception;
        }
    }

private
static
void
cleanDirectory
(
final
File
directory
)
throws
IOException
{
if
(
!
directory
.
exists
(
)
)
{
return
;
}
if
(
!
directory
.
isDirectory
(
)
)
{
return
;
}
IOException
exception
=
;
final
File
[
]
files
=
directory
.
listFiles
(
)
;
if
(
files
!=
)
{
for
(
final
File
file
:
files
)
{
try
{
cleanDirectory
(
file
)
;
if
(
!
file
.
delete
(
)
)
{
throw
new
IOException
(
"Cannot delete "
+
file
.
getAbsolutePath
(
)
)
;
}
}
catch
(
final
IOException
ioe
)
{
exception
=
ioe
;
}
}
}
if
(
!=
exception
)
{
throw
exception
;
}
}


public static String[] splitSQL(String multiLineSQL, String endDelimiter) {
        return processMutliLineSQL(multiLineSQL, false, true, endDelimiter);
    }

public static String [ ] splitSQL ( String multiLineSQL , String endDelimiter ) { return processMutliLineSQL ( multiLineSQL , false , true , endDelimiter ) ; }

Splits a candidate multi-line SQL statement along ;'s and "go"'s.

Splits a candidate multi - line SQL statement along ; s and go s .


public static String pad(String value, int length) {
        value = StringUtil.trimToEmpty(value);
        if (value.length() >= length) {
            return value;
        }

        return value + StringUtil.repeat(" ", length - value.length());
    }

public
static
String
pad
(
String
value
,
int
length
)
{
value
=
StringUtil
.
trimToEmpty
(
value
)
;
if
(
value
.
length
(
)
>=
length
)
{
return
value
;
}
return
value
+
StringUtil
.
repeat
(
" "
,
length
value
.
length
(
)
)
;
}

Adds spaces to the right of the input value until the string has reached the given length. Nothing is done
if the string already has the given length or if the string is even longer.
@param value The string to pad (if necessary)
@param length the desired length
@return the input string, padded if necessary.

Adds spaces to the right of the input value until the string has reached the given length . Nothing is done if the string already has the given length or if the string is even longer .


public static String leftPad(String value, int length) {
        value = StringUtil.trimToEmpty(value);
        if (value.length() >= length) {
            return value;
        }

        return StringUtil.repeat(" ", length - value.length()) + value;
    }

public
static
String
leftPad
(
String
value
,
int
length
)
{
value
=
StringUtil
.
trimToEmpty
(
value
)
;
if
(
value
.
length
(
)
>=
length
)
{
return
value
;
}
return
StringUtil
.
repeat
(
" "
,
length
value
.
length
(
)
)
+
value
;
}

Adds spaces to the left of the input value until the string has reached the given length. Nothing is done
if the string already has the given length or if the string is even longer.
@param value The string to pad (if necessary)
@param length the desired length
@return the input string, padded if necessary.

Adds spaces to the left of the input value until the string has reached the given length . Nothing is done if the string already has the given length or if the string is even longer .


public static String randomIdentifer(int len) {
        final String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        StringBuilder sb = new StringBuilder( len );
        for (int i = 0; i < len; i++)
            sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
        return sb.toString();
    }

public static String randomIdentifer ( int len ) { final String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; StringBuilder sb = new StringBuilder ( len ) ; for ( int i = 0 ; i < len ; i ++ ) sb . append ( . charAt ( rnd . nextInt ( . length ( ) ) ) ) ; return sb . toString ( ) ; }

Produce a random identifer of the given length, consisting only of uppercase letters.
@param len desired length of the string
@return an identifier of the desired length

Produce a random identifer of the given length consisting only of uppercase letters .


public static String stripSqlCommentsAndWhitespacesFromTheEnd(String sqlString) {
        if (isEmpty(sqlString)) {
            return sqlString;
        }
        StringBuilder str = new StringBuilder(sqlString);
        boolean strModified = true;
        while (strModified) {
            strModified = false;
            // first check for last block comment
            // since line comments could be inside block comments, we want to
            // remove them first.
            String lastBlockComment = getLastBlockComment(str.toString());
            if (isNotEmpty(lastBlockComment)) {
                str.setLength(str.length() - lastBlockComment.length());
                // we just modified the end of the string,
                // do another loop to check for next block or line comments
                strModified = true;
            }
            // now check for the line comments
            String lastLineComment = getLastLineComment(str.toString());
            if (isNotEmpty(lastLineComment)) {
                str.setLength(str.length() - lastLineComment.length());
                // we just modified the end of the string,
                // do another loop to check for next block or line comments
                strModified = true;
            }
        }
        return trimRight(str.toString());
    }

Strips the comments and whitespaces from the end of given sql string.
@param sqlString
@return

Strips the comments and whitespaces from the end of given sql string .


public static String concatConsistentCase(String baseString, String addition) {
        boolean hasLowerCase = hasLowerCase(baseString);
        boolean hasUpperCase = hasUpperCase(baseString);
        if ((hasLowerCase && hasUpperCase) || (!hasLowerCase && !hasUpperCase)) { //mixed case || no letters
            return baseString + addition;
        } else if (hasLowerCase) {
            return baseString + addition.toLowerCase();
        } else {
            return baseString + addition.toUpperCase();
        }
    }

public
static
String
concatConsistentCase
(
String
baseString
,
String
addition
)
{
boolean
hasLowerCase
=
hasLowerCase
(
baseString
)
;
boolean
hasUpperCase
=
hasUpperCase
(
baseString
)
;
if
(
(
hasLowerCase
&&
hasUpperCase
)
||
(
!
hasLowerCase
&&
!
hasUpperCase
)
)
{
//mixed case || no letters
return
baseString
+
addition
;
}
else
if
(
hasLowerCase
)
{
return
baseString
+
addition
.
toLowerCase
(
)
;
}
else
{
return
baseString
+
addition
.
toUpperCase
(
)
;
}
}

Concatenates the addition string to the baseString string, adjusting the case of "addition" to match the base string.
If the string is all caps, append addition in all caps. If all lower case, append in all lower case. If baseString is mixed case, make no changes to addition.

Concatenates the addition string to the baseString string adjusting the case of addition to match the base string . If the string is all caps append addition in all caps . If all lower case append in all lower case . If baseString is mixed case make no changes to addition .


protected String[] getDatabaseCatalogNames(Database database) throws SQLException, DatabaseException {
        List<String> returnList = new ArrayList<>();

        ResultSet catalogs = null;

        try {
            if (((AbstractJdbcDatabase) database).jdbcCallsCatalogsSchemas()) {
                catalogs = ((JdbcConnection) database.getConnection()).getMetaData().getSchemas();
            } else {
                catalogs = ((JdbcConnection) database.getConnection()).getMetaData().getCatalogs();
            }
            while (catalogs.next()) {
                if (((AbstractJdbcDatabase) database).jdbcCallsCatalogsSchemas()) {
                    returnList.add(catalogs.getString("TABLE_SCHEM"));
                } else {
                    returnList.add(catalogs.getString("TABLE_CAT"));
                }
            }
        } finally {
            if (catalogs != null) {
                try {
                    catalogs.close();
                } catch (SQLException ignore) {

                }
            }

        }
        return returnList.toArray(new String[returnList.size()]);
    }

protected String [ ] getDatabaseCatalogNames ( Database database ) throws SQLException , DatabaseException { List < String > returnList = new ArrayList <> ( ) ; ResultSet catalogs = null ; try { if ( ( ( AbstractJdbcDatabase ) database ) . jdbcCallsCatalogsSchemas ( ) ) { catalogs = ( ( JdbcConnection ) database . getConnection ( ) ) . getMetaData ( ) . getSchemas ( ) ; } else { catalogs = ( ( JdbcConnection ) database . getConnection ( ) ) . getMetaData ( ) . getCatalogs ( ) ; } while ( catalogs . next ( ) ) { if ( ( ( AbstractJdbcDatabase ) database ) . jdbcCallsCatalogsSchemas ( ) ) { returnList . add ( catalogs . getString ( "TABLE_SCHEM" ) ) ; } else { returnList . add ( catalogs . getString ( "TABLE_CAT" ) ) ; } } } finally { if ( catalogs != null ) { try { catalogs . close ( ) ; } catch ( SQLException ignore ) { } } } return returnList . toArray ( new String [ returnList . size ( ) ] ) ; }

Fetches an array of Strings with the catalog names in the database.
@param database The database from which to get the schema names
@return An array of catalog name Strings (May be an empty array)
@throws SQLException propagated java.sql.SQLException
@throws DatabaseException if a different problem occurs during the DBMS-specific code

Fetches an array of Strings with the catalog names in the database .


public StringClauses append(String key, String clause) {
        Validate.notNull(StringUtil.trimToNull(key), "key must be a non-null, non-empty value");

        key = StringUtil.trimToEmpty(key).toLowerCase();
        clause = StringUtil.trimToEmpty(clause);

        if (clauses.containsKey(key)) {
            throw new IllegalArgumentException("Cannot add clause with key '" + key + "' because it is already defined");
        }
        clauses.put(key, clause.trim());
        return this;
    }

Adds a new clause at the end of the list with the given key.

Adds a new clause at the end of the list with the given key .


public StringClauses append(String key, StringClauses subclauses) {
        Validate.notNull(StringUtil.trimToNull(key), "key must be a non-null, non-empty value");

        key = StringUtil.trimToEmpty(key).toLowerCase();

        if (clauses.containsKey(key)) {
            throw new IllegalArgumentException("Cannot add clause with key '" + key + "' because it is already defined");
        }

        clauses.put(key, subclauses);
        return this;
    }

Adds a new sub-clause at the end of the list with the given key.

Adds a new sub - clause at the end of the list with the given key .


public StringClauses prepend(String key, String clause) {
        return prependImpl(key, StringUtil.trimToEmpty(clause));
    }

public StringClauses prepend ( String key , String clause ) { return prependImpl ( key , StringUtil . trimToEmpty ( clause ) ) ; }

Adds a clause with the given key to the beginning of the list.

Adds a clause with the given key to the beginning of the list .


public StringClauses insertBefore(String existingKey, String newKey, String newValue) throws IllegalArgumentException {
        return insertBeforeImpl(existingKey, newKey, newValue);
    }

public StringClauses insertBefore ( String existingKey , String newKey , String newValue ) throws IllegalArgumentException { return insertBeforeImpl ( existingKey , newKey , newValue ) ; }

Inserts a new clause before the given key. Throws IllegalArgumentException if the existingKey does not exist.

Inserts a new clause before the given key . Throws IllegalArgumentException if the existingKey does not exist .


public StringClauses insertAfter(String existingKey, String newKey, String newValue) {
        return insertAfterImpl(existingKey, newKey, newValue);
    }

public StringClauses insertAfter ( String existingKey , String newKey , String newValue ) { return insertAfterImpl ( existingKey , newKey , newValue ) ; }

Inserts a new clause after the given key. Throws IllegalArgumentException if the existingKey does not exist.

Inserts a new clause after the given key . Throws IllegalArgumentException if the existingKey does not exist .


public String get(String exitingKey) {
        exitingKey = StringUtil.trimToEmpty(exitingKey).toLowerCase();
        Object clauses = getImpl(exitingKey);
        if (clauses == null) {
            return null;
        }
        return clauses.toString();
    }

public String get ( String exitingKey ) { exitingKey = StringUtil . trimToEmpty ( exitingKey ) . toLowerCase ( ) ; Object clauses = getImpl ( exitingKey ) ; if ( clauses == null ) { return null ; } return clauses . toString ( ) ; }

Retrieves the given key. Returns null if not set.
If clause at key is a StringClause, return the string version of it.
Will traverse sub-clauses to find the key.

Retrieves the given key . Returns null if not set . If clause at key is a StringClause return the string version of it . Will traverse sub - clauses to find the key .


public StringClauses getSubclause(String exitingKey) {
        exitingKey = StringUtil.trimToEmpty(exitingKey).toLowerCase();
        Object clauses = getImpl(exitingKey);
        if (clauses == null) {
            return null;
        }
        if (clauses instanceof String) {
            return new StringClauses().append((String) clauses);
        }
        return (StringClauses) clauses;
    }

public StringClauses getSubclause ( String exitingKey ) { exitingKey = StringUtil . trimToEmpty ( exitingKey ) . toLowerCase ( ) ; Object clauses = getImpl ( exitingKey ) ; if ( clauses == null ) { return null ; } if ( clauses instanceof String ) { return new StringClauses ( ) . append ( ( String ) clauses ) ; } return ( StringClauses ) clauses ; }

Retrieves the given key. Returns null if not set. If clause at key is a String, return a new StringClause version of it. Will traverse sub-clauses to find the key.

Retrieves the given key . Returns null if not set . If clause at key is a String return a new StringClause version of it . Will traverse sub - clauses to find the key .


public void print(PrintStream out, ChangeLogSerializer changeLogSerializer) throws ParserConfigurationException, IOException, DatabaseException {

        List<ChangeSet> changeSets = generateChangeSets();

        changeLogSerializer.write(changeSets, out);

        out.flush();
    }

public void print ( PrintStream out , ChangeLogSerializer changeLogSerializer ) throws ParserConfigurationException , IOException , DatabaseException { List < ChangeSet > changeSets = generateChangeSets ( ) ; changeLogSerializer . write ( changeSets , out ) ; out . flush ( ) ; }

Prints changeLog that would bring the target database to be the same as
the reference database


public List<Database> getImplementedDatabases() {
        List<Database> returnList = new ArrayList<>();
        for (SortedSet<Database> set : implementedDatabases.values()) {
            returnList.add(set.iterator().next());
        }
        return returnList;
    }

public List < Database > getImplementedDatabases ( ) { List < Database > returnList = new ArrayList <> ( ) ; for ( SortedSet < Database > set : implementedDatabases . values ( ) ) { returnList . add ( set . iterator ( ) . next ( ) ) ; } return returnList ; }

Returns instances of all implemented database types.

Returns instances of all implemented database types .


public List<Database> getInternalDatabases() {
        List<Database> returnList = new ArrayList<>();
        for (SortedSet<Database> set : internalDatabases.values()) {
            returnList.add(set.iterator().next());
        }
        return returnList;
    }

public List < Database > getInternalDatabases ( ) { List < Database > returnList = new ArrayList <> ( ) ; for ( SortedSet < Database > set : internalDatabases . values ( ) ) { returnList . add ( set . iterator ( ) . next ( ) ) ; } return returnList ; }

Returns instances of all "internal" database types.

Returns instances of all internal database types .


public boolean validate(Database database) {
        int maxParameters = this.getMaxParameters(database);
        int minParameters = this.getMinParameters(database);

        if (parameters.size() > maxParameters) {
            throw new UnexpectedLiquibaseException("Type "+getClass()+" doesn't support "+ maxParameters+" parameters");
        }
        if (parameters.size() < minParameters) {
            throw new UnexpectedLiquibaseException("Type "+getClass()+" requires "+ minParameters+" parameters");
        }

        return true;
    }

public
boolean
validate
(
Database
database
)
{
int
maxParameters
=
this
.
getMaxParameters
(
database
)
;
int
minParameters
=
this
.
getMinParameters
(
database
)
;
if
(
parameters
.
size
(
)
>
maxParameters
)
{
throw
new
UnexpectedLiquibaseException
(
"Type "
+
getClass
(
)
+
" doesn't support "
+
maxParameters
+
" parameters"
)
;
}
if
(
parameters
.
size
(
)
<
minParameters
)
{
throw
new
UnexpectedLiquibaseException
(
"Type "
+
getClass
(
)
+
" requires "
+
minParameters
+
" parameters"
)
;
}
return
true
;
}

Validates the correct state of this data type against a given database.
@param database the database to validate against
@return true if the current settings for this data type can be implemented on the given database, false otherwise

Validates the correct state of this data type against a given database .


public DatabaseDataType toDatabaseDataType(Database database) {
        if (database instanceof MSSQLDatabase) {
            String name = database.escapeDataTypeName(getName());
            int dataTypeMaxParameters = database.getDataTypeMaxParameters(getName());
            Object[] parameters = getParameters();
            if (dataTypeMaxParameters < parameters.length) {
                parameters = Arrays.copyOfRange(parameters, 0, dataTypeMaxParameters);
            }
            return new DatabaseDataType(name, parameters);
        }

        DatabaseDataType type = new DatabaseDataType(name.toUpperCase(Locale.US), getParameters());
        type.addAdditionalInformation(additionalInformation);

        return type;
    }

public DatabaseDataType toDatabaseDataType ( Database database ) { if ( database instanceof MSSQLDatabase ) { String name = database . escapeDataTypeName ( getName ( ) ) ; int dataTypeMaxParameters = database . getDataTypeMaxParameters ( getName ( ) ) ; Object [ ] parameters = getParameters ( ) ; if ( dataTypeMaxParameters < parameters . length ) { parameters = Arrays . copyOfRange ( parameters , 0 , dataTypeMaxParameters ) ; } return new DatabaseDataType ( name , parameters ) ; } DatabaseDataType type = new DatabaseDataType ( name . toUpperCase ( Locale . US ) , getParameters ( ) ) ; type . addAdditionalInformation ( additionalInformation ) ; return type ; }

Transforms this data type into the native data type of the target DBMS.
@param database the {@link Database} for which the native data type is to be constructed
@return the new, native data type

Transforms this data type into the native data type of the target DBMS .


public String objectToSql(Object value, Database database) {
        if ((value == null) || "null".equals(value.toString().toLowerCase(Locale.US))) {
            return null;
        } else if (value instanceof DatabaseFunction) {
            return functionToSql((DatabaseFunction) value, database);
        } else if (value instanceof Number) {
            return numberToSql((Number) value, database);
        }
        return otherToSql(value, database);
    }

public String objectToSql ( Object value , Database database ) { if ( ( value == null ) || "null" . equals ( value . toString ( ) . toLowerCase ( Locale . US ) ) ) { return null ; } else if ( value instanceof DatabaseFunction ) { return functionToSql ( ( DatabaseFunction ) value , database ) ; } else if ( value instanceof Number ) { return numberToSql ( ( Number ) value , database ) ; } return otherToSql ( value , database ) ; }

Returns the value object in a format to include in SQL. Quote if necessary.

Returns the value object in a format to include in SQL . Quote if necessary .


protected boolean isCurrentDateTimeFunction(String string, Database database) {
        return string.toLowerCase(Locale.US).startsWith("current_timestamp")
                || string.toLowerCase(Locale.US).startsWith(DatabaseFunction.CURRENT_DATE_TIME_PLACE_HOLDER)
                || database.getCurrentDateTimeFunction().toLowerCase(Locale.US).equals(string.toLowerCase(Locale.US));
    }

protected boolean isCurrentDateTimeFunction ( String string , Database database ) { return string . toLowerCase ( Locale . US ) . startsWith ( "current_timestamp" ) || string . toLowerCase ( Locale . US ) . startsWith ( DatabaseFunction . CURRENT_DATE_TIME_PLACE_HOLDER ) || database . getCurrentDateTimeFunction ( ) . toLowerCase ( Locale . US ) . equals ( string . toLowerCase ( Locale . US ) ) ; }

Determines if the given function name refers to the function that returns the current
time and date for a specific DBMS. Also returns true if the name returns the Liquibase wildcard
CURRENT_DATE_TIME_PLACE_HOLDER, which will later be translated into the appropriate function.
@param string The database function name to test
@param database A database object to test against
@return see above

Determines if the given function name refers to the function that returns the current time and date for a specific DBMS . Also returns true if the name returns the Liquibase wildcard CURRENT_DATE_TIME_PLACE_HOLDER which will later be translated into the appropriate function .


public boolean supportsBooleanDataType() {
		if (getConnection() == null)
			return false; /// assume not;
		try {

			final Integer fixPack = getDb2FixPack();

			if (fixPack == null)
				throw new DatabaseException("Error getting fix pack number");

			return getDatabaseMajorVersion() > 11
					|| getDatabaseMajorVersion() == 11 && getDatabaseMinorVersion() >= 1 && fixPack.intValue() >= 1;

		} catch (final DatabaseException e) {
			return false; // assume not
		}
	}

public
boolean
supportsBooleanDataType
(
)
{
if
(
getConnection
(
)
==
)
return
false
;
/// assume not;
try
{
final
Integer
fixPack
=
getDb2FixPack
(
)
;
if
(
fixPack
==
)
throw
new
DatabaseException
(
"Error getting fix pack number"
)
;
return
getDatabaseMajorVersion
(
)
>
11
||
getDatabaseMajorVersion
(
)
==
11
&&
getDatabaseMinorVersion
(
)
>=
1
&&
fixPack
.
intValue
(
)
>=
1
;
}
catch
(
final
DatabaseException
e
)
{
return
false
;
// assume not
}
}

boolean data type column are allowed for versions >= 11.1.1.1
@return

boolean data type column are allowed for versions > = 11 . 1 . 1 . 1


private String getConcatSql(List<String> values) {
        if (values.size() == 1) {
            return values.get(0);
        } else {
            return START_CONCAT + values.get(0) + SEP_CONCAT + getConcatSql(values.subList(1, values.size())) + END_CONCAT;
        }
    }

private String getConcatSql ( List < String > values ) { if ( values . size ( ) == 1 ) { return values . get ( 0 ) ; } else { return START_CONCAT + values . get ( 0 ) + SEP_CONCAT + getConcatSql ( values . subList ( 1 , values . size ( ) ) ) + END_CONCAT ; } }

Recursive way of building CONCAT instruction

@param values a non null List of String
@return a String containing the CONCAT instruction with all elements, or only a value if there is only one element in the list


public boolean generateStatementsVolatile(SqlStatement statement, Database database) {
        for (SqlGenerator generator : getGenerators(statement, database)) {
            if (generator.generateStatementsIsVolatile(database)) {
                return true;
            }
        }
        return false;
    }

public boolean generateStatementsVolatile ( SqlStatement statement , Database database ) { for ( SqlGenerator generator : getGenerators ( statement , database ) ) { if ( generator . generateStatementsIsVolatile ( database ) ) { return true ; } } return false ; }

Return true if the SqlStatement class queries the database in any way to determine Statements to execute.
If the statement queries the database, it cannot be used in updateSql type operations

Return true if the SqlStatement class queries the database in any way to determine Statements to execute . If the statement queries the database it cannot be used in updateSql type operations


private static void addArtifact(Set<URI> urls,
                                  Artifact artifact,
                                  Log log,
                                  boolean verbose)
          throws MalformedURLException {
    File f = artifact.getFile();
    if (f == null) {
      log.warn("Artifact with no actual file, '" + artifact.getGroupId()
               + ":" + artifact.getArtifactId() + "'");
    } else {
      addFile(urls, f, log, verbose);
    }
//    if (f != null) {
//      URL fileURL = f.toURI().toURL();
//      if (verbose) {
//        log.info("  artifact: " + fileURL);
//      }
//      urls.add(fileURL);
//    } else {
//      log.warning("Artifact with no actual file, '" + artifact.getGroupId()
//               + ":" + artifact.getArtifactId() + "'");
//    }
  }

//      URL fileURL = f.toURI().toURL();

//        log.info("  artifact: " + fileURL);

Adds the artifact file into the set of URLs so it can be used in a URLClassLoader.
@param urls The set to add the artifact file URL to.
@param artifact The Artifact to resolve the file for.
@throws MalformedURLException If there is a problem creating the URL for the file.

Adds the artifact file into the set of URLs so it can be used in a URLClassLoader .


public static Field getDeclaredField(Class clazz, String fieldName)
          throws NoSuchFieldException {
    Field f = getField(clazz, fieldName);
    if (f == null) {
      // Try the parent class
      Class parent = clazz.getSuperclass();
      if (parent != null) {
        return getDeclaredField(parent, fieldName);
      } else {
        throw new NoSuchFieldException("The field '" + fieldName + "' could not be "
                                       + "found in the class of any of its parent "
                                       + "classes.");
      }
    } else {
      return f;
    }
  }

Recursively searches for the field specified by the fieldName in the class and all
the super classes until it either finds it, or runs out of parents.
@param clazz The Class to start searching from.
@param fieldName The name of the field to retrieve.
@return The {@link Field} identified by the field name.
@throws NoSuchFieldException If the field was not found in the class or any of its
super classes.

Recursively searches for the field specified by the fieldName in the class and all the super classes until it either finds it or runs out of parents .


protected List<String> getAlternatePaths(String path) {
        List<String> alternatePaths = new ArrayList<>();

        if (path.startsWith("/")) { //People are often confused about leading slashes in resource paths...
            alternatePaths.add(path.substring(1));
        }

        return alternatePaths;

    }

Return alternate options for the given path that the user maybe meant. Return in order of likelihood.

Return alternate options for the given path that the user maybe meant . Return in order of likelihood .


public boolean matches(Contexts runtimeContexts) {
        if ((runtimeContexts == null) || runtimeContexts.isEmpty()) {
            return true;
        }
        if (this.contexts.isEmpty()) {
            return true;
        }

        for (String expression : this.contexts) {
            if (matches(expression, runtimeContexts)) {
                return true;
            }
        }
        return false;
    }

public boolean matches ( Contexts runtimeContexts ) { if ( ( runtimeContexts == null ) || runtimeContexts . isEmpty ( ) ) { return true ; } if ( this . contexts . isEmpty ( ) ) { return true ; } for ( String expression : this . contexts ) { if ( matches ( expression , runtimeContexts ) ) { return true ; } } return false ; }

Returns true if the passed runtime contexts match this context expression


private ResourceAccessor createResourceAccessor(ClassLoader classLoader) {
        List<ResourceAccessor> resourceAccessors = new ArrayList<ResourceAccessor>();
        resourceAccessors.add(new FileSystemResourceAccessor(Paths.get(".").toAbsolutePath().getRoot().toFile()));
        resourceAccessors.add(new ClassLoaderResourceAccessor(classLoader));
        String changeLogDirectory = getChangeLogDirectory();
        if (changeLogDirectory != null) {
          changeLogDirectory = changeLogDirectory.trim().replace('\\', '/');  //convert to standard / if using absolute path on windows
          resourceAccessors.add(new FileSystemResourceAccessor(new File(changeLogDirectory)));
        }
        return new CompositeResourceAccessor(resourceAccessors.toArray(new ResourceAccessor[0]));
    }

Creates a suitable ResourceAccessor for use in an Ant task..

@param classLoader The ClassLoader to use in the ResourceAccessor. It is preferable that it is an AntClassLoader.
@return A ResourceAccessor.

Creates a suitable ResourceAccessor for use in an Ant task ..


protected void closeDatabase(Database database) {
        try {
            if(database != null) {
                database.close();
            }
        } catch (DatabaseException e) {
            log("Error closing the database connection.", e, Project.MSG_WARN);
        }
    }

Convenience method to safely close the database connection.

@param database The database to close.

Convenience method to safely close the database connection .


private int appendNextCharacterAndAdvanceLoop(String line, StringBuilder sb, int i) {
        sb.append(line.charAt(i + 1));
        i++;
        return i;
    }

private int appendNextCharacterAndAdvanceLoop ( String line , StringBuilder sb , int i ) { sb . append ( line . charAt ( i + 1 ) ) ; i ++ ; return i ; }

Appends the next character in the line to the stringbuffer.

@param line - line to process
@param sb   - contains the processed character
@param i    - current position in the line.
@return new position in the line.

Appends the next character in the line to the stringbuffer .


private boolean isNextCharacterEscapedQuote(String nextLine, boolean inQuotes, int i) {
        return inQuotes  // we are in quotes, therefore there can be escaped quotes in here.
            && (nextLine.length() > (i + 1))  // there is indeed another character to check.
            && isCharacterQuoteCharacter(nextLine.charAt(i + 1));
    }

Checks to see if the character after the index is a quotation character.

precondition: the current character is a quote or an escape

@param nextLine the current line
@param inQuotes true if the current context is quoted
@param i        current index in line
@return true if the following character is a quote

Checks to see if the character after the index is a quotation character .


protected boolean isNextCharacterEscapable(String nextLine, boolean inQuotes, int i) {
        return inQuotes  // we are in quotes, therefore there can be escaped quotes in here.
            && (nextLine.length() > (i + 1))  // there is indeed another character to check.
            && isCharacterEscapable(nextLine.charAt(i + 1));
    }

Checks to see if the character after the current index in a String is an escapable character.
Meaning the next character is either a quotation character or the escape char and you are inside
quotes.

precondition: the current character is an escape

@param nextLine the current line
@param inQuotes true if the current context is quoted
@param i        current index in line
@return true if the following character is a quote

Checks to see if the character after the current index in a String is an escapable character . Meaning the next character is either a quotation character or the escape char and you are inside quotes .


public List<ParsedNode> getChildren(String namespace, String nodename) {
        List<ParsedNode> returnList = new ArrayList<>();
        for (ParsedNode node : children) {
            if (nodeMatches(node, namespace, nodename)) {
                returnList.add(node);
            }
        }
        return Collections.unmodifiableList(returnList);
    }

public List < ParsedNode > getChildren ( String namespace , String nodename ) { List < ParsedNode > returnList = new ArrayList <> ( ) ; for ( ParsedNode node : children ) { if ( nodeMatches ( node , namespace , nodename ) ) { returnList . add ( node ) ; } } return Collections . unmodifiableList ( returnList ) ; }

Returns all child nodes with the given namespace and name.
If none match, an empty list is returned.
Returned list is unmodifiableList.

Returns all child nodes with the given namespace and name . If none match an empty list is returned . Returned list is unmodifiableList .


public ParsedNode setValue(Object value) throws ParsedNodeException {
        if (value instanceof ParsedNode) {
            this.addChild((ParsedNode) value);
        } else if (value instanceof Collection) {
            List newValue = new ArrayList();
            for (Object obj : ((Collection) value)) {
                if (obj instanceof Map) {
                    addChildren((Map) obj);
                } else if (obj instanceof ParsedNode) {
                    addChild(((ParsedNode) obj));
                } else {
                    newValue.add(obj);
                }
            }
            if (newValue.isEmpty()) {
                //do nothing
            } else if (newValue.size() == 1) {
                this.value = newValue.get(0);
            } else {
                this.value = newValue;
            }
        } else if (value instanceof Map) {
            addChildren(((Map) value));
        } else {
            this.value = value;
        }
        return this;
    }

public
ParsedNode
setValue
(
Object
value
)
throws
ParsedNodeException
{
if
(
value
instanceof
ParsedNode
)
{
this
.
addChild
(
(
ParsedNode
)
value
)
;
}
else
if
(
value
instanceof
Collection
)
{
List
newValue
=
new
ArrayList
(
)
;
for
(
Object
obj
:
(
(
Collection
)
value
)
)
{
if
(
obj
instanceof
Map
)
{
addChildren
(
(
Map
)
obj
)
;
}
else
if
(
obj
instanceof
ParsedNode
)
{
addChild
(
(
(
ParsedNode
)
obj
)
)
;
}
else
{
newValue
.
add
(
obj
)
;
}
}
if
(
newValue
.
isEmpty
(
)
)
{
//do nothing
}
else
if
(
newValue
.
size
(
)
==
1
)
{
this
.
value
=
newValue
.
get
(
0
)
;
}
else
{
this
.
value
=
newValue
;
}
}
else
if
(
value
instanceof
Map
)
{
addChildren
(
(
(
Map
)
value
)
)
;
}
else
{
this
.
value
=
value
;
}
return
this
;
}

Sets the value of this ParsedNode.
If the passed value is a ParsedNode, it is added as a child, not as the value.
If the passed value is a Map, it is converted to a ParsedNode and added as a child, not as the value.
If the passed value is a Collection, each object is added as a child if it is a ParsedNode or a Map.
If there are multiple simple values in a passed collection, value is set to a List. If there is a single value in a collection, value is set to the single value.

Sets the value of this ParsedNode . If the passed value is a ParsedNode it is added as a child not as the value . If the passed value is a Map it is converted to a ParsedNode and added as a child not as the value . If the passed value is a Collection each object is added as a child if it is a ParsedNode or a Map . If there are multiple simple values in a passed collection value is set to a List . If there is a single value in a collection value is set to the single value .


public <T> T getValue(Class<T> type) throws ParsedNodeException {
        return convertObject(value, type);
    }

public < T > T getValue ( Class < T > type ) throws ParsedNodeException { return convertObject ( value , type ) ; }

Return the value associated with this node converted to the given type.

@throws ParsedNodeException if the current value type cannot be converted

Return the value associated with this node converted to the given type .


public ParsedNode getChild(String namespace, String name) throws ParsedNodeException {
        ParsedNode returnNode = null;
        for (ParsedNode node : children) {
            if (nodeMatches(node, namespace, name)) {
                if (returnNode != null) {
                    throw new ParsedNodeException("Multiple nodes match "+namespace+"/"+name);
                }
                returnNode = node;
            }
        }
        return returnNode;
    }

public
ParsedNode
getChild
(
String
namespace
,
String
name
)
throws
ParsedNodeException
{
ParsedNode
returnNode
=
;
for
(
ParsedNode
node
:
children
)
{
if
(
nodeMatches
(
node
,
namespace
,
name
)
)
{
if
(
returnNode
!=
)
{
throw
new
ParsedNodeException
(
"Multiple nodes match "
+
namespace
+
"/"
+
name
)
;
}
returnNode
=
node
;
}
}
return
returnNode
;
}

Returns the ParsedNode defined by the given namespace and name.
@throws liquibase.parser.core.ParsedNodeException if multiple nodes match.

Returns the ParsedNode defined by the given namespace and name .


public <T> T getChildValue(String namespace, String nodename, Class<T> type) throws ParsedNodeException {
        Object rawValue = getChildValue(namespace, nodename);
        if (rawValue == null) {
            return null;
        }
        return convertObject(rawValue, type);
    }

public < T > T getChildValue ( String namespace , String nodename , Class < T > type ) throws ParsedNodeException { Object rawValue = getChildValue ( namespace , nodename ) ; if ( rawValue == null ) { return null ; } return convertObject ( rawValue , type ) ; }

Returns the value of the given node, converted to the passed type.
@throws liquibase.parser.core.ParsedNodeException if there is an error converting the value

Returns the value of the given node converted to the passed type .


public Object getChildValue(String namespace, String nodename) throws ParsedNodeException {
        ParsedNode child = getChild(namespace, nodename);
        if (child == null) {
            return null;
        }
        return child.getValue();
    }

public Object getChildValue ( String namespace , String nodename ) throws ParsedNodeException { ParsedNode child = getChild ( namespace , nodename ) ; if ( child == null ) { return null ; } return child . getValue ( ) ; }

Returns the value of the given node with no conversion attempted.

Returns the value of the given node with no conversion attempted .


@Override
    public void close() throws IOException {
        for (InputStream stream : this) {
            try {
                stream.close();
            } catch (IOException e) {
                Scope.getCurrentScope().getLog(getClass()).severe("Error closing stream. Logging error and continuing", e);
            }
        }
    }


public boolean isAutoIncrement() {
        return "serial".equals(type.toLowerCase(Locale.US)) || "bigserial".equals(type.toLowerCase(Locale.US)) || "smallserial"
            .equals(type.toLowerCase(Locale.US));
    }

public boolean isAutoIncrement ( ) { return "serial" . equals ( type . toLowerCase ( Locale . US ) ) || "bigserial" . equals ( type . toLowerCase ( Locale . US ) ) || "smallserial" . equals ( type . toLowerCase ( Locale . US ) ) ; }

Mainly for postgres, check if the column is a serial data type.
@return Whether the type is serial

Mainly for postgres check if the column is a serial data type .


protected boolean isCompressedFile(Path path) {
        return path != null && (path.toString().startsWith("jar:") || path.toString().toLowerCase().endsWith(".jar") || path.toString().toLowerCase().endsWith(".zip"));
    }

protected boolean isCompressedFile ( Path path ) { return path != null && ( path . toString ( ) . startsWith ( "jar:" ) || path . toString ( ) . toLowerCase ( ) . endsWith ( ".jar" ) || path . toString ( ) . toLowerCase ( ) . endsWith ( ".zip" ) ) ; }

Returns true if the given path is a compressed file.

Returns true if the given path is a compressed file .


public Column getColumn(String columnName) {
        for (Column column : getColumns()) {
            if (column.getName().equalsIgnoreCase(columnName)) {
                return column;
            }
        }
        return null;
    }

public Column getColumn ( String columnName ) { for ( Column column : getColumns ( ) ) { if ( column . getName ( ) . equalsIgnoreCase ( columnName ) ) { return column ; } } return null ; }

Returns the column object for the given columnName.  If the column does not exist in this table,
return null.

Returns the column object for the given columnName . If the column does not exist in this table return null .


public <T extends SingletonObject> T getSingleton(Class<T> type) {
        if (getParent() != null) {
            return getParent().getSingleton(type);
        }

        String key = type.getName();
        T singleton = get(key, type);
        if (singleton == null) {
            try {
                try {
                    Constructor<T> constructor = type.getDeclaredConstructor(Scope.class);
                    constructor.setAccessible(true);
                    singleton = constructor.newInstance(this);
                } catch (NoSuchMethodException e) { //try without scope
                    Constructor<T> constructor = type.getDeclaredConstructor();
                    constructor.setAccessible(true);
                    singleton = constructor.newInstance();
                }
            } catch (Exception e) {
                throw new UnexpectedLiquibaseException(e);
            }

            values.put(key, singleton);
        }
        return singleton;
    }

public
<
T
extends
SingletonObject
>
T
getSingleton
(
Class
<
T
>
type
)
{
if
(
getParent
(
)
!=
)
{
return
getParent
(
)
.
getSingleton
(
type
)
;
}
String
key
=
type
.
getName
(
)
;
T
singleton
=
get
(
key
,
type
)
;
if
(
singleton
==
)
{
try
{
try
{
Constructor
<
T
>
constructor
=
type
.
getDeclaredConstructor
(
Scope
.
class
)
;
constructor
.
setAccessible
(
true
)
;
singleton
=
constructor
.
newInstance
(
this
)
;
}
catch
(
NoSuchMethodException
e
)
{
//try without scope
Constructor
<
T
>
constructor
=
type
.
getDeclaredConstructor
(
)
;
constructor
.
setAccessible
(
true
)
;
singleton
=
constructor
.
newInstance
(
)
;
}
}
catch
(
Exception
e
)
{
throw
new
UnexpectedLiquibaseException
(
e
)
;
}
values
.
put
(
key
,
singleton
)
;
}
return
singleton
;
}

Looks up the singleton object of the given type. If the singleton has not been created yet, it will be instantiated.
The singleton is a singleton based on the root scope and the same object will be returned for all child scopes of the root.

Looks up the singleton object of the given type . If the singleton has not been created yet it will be instantiated . The singleton is a singleton based on the root scope and the same object will be returned for all child scopes of the root .


@Override
    public void tag(final String tagString) throws DatabaseException {
        Database database = getDatabase();
        Executor executor = ExecutorService.getInstance().getExecutor(database);
        int totalRows = ExecutorService.getInstance().getExecutor(database).queryForInt(new
            SelectFromDatabaseChangeLogStatement(new ColumnConfig().setName("COUNT(*)", true)));
        if (totalRows == 0) {
            ChangeSet emptyChangeSet = new ChangeSet(String.valueOf(new Date().getTime()), "liquibase",
                false,false, "liquibase-internal", null, null,
                getDatabase().getObjectQuotingStrategy(), null);
            this.setExecType(emptyChangeSet, ChangeSet.ExecType.EXECUTED);
        }

        executor.execute(new TagDatabaseStatement(tagString));
        getDatabase().commit();

        if (this.ranChangeSetList != null) {
            ranChangeSetList.get(ranChangeSetList.size() - 1).setTag(tagString);
        }
    }

@ Override public void tag ( final String tagString ) throws DatabaseException { Database database = getDatabase ( ) ; Executor executor = ExecutorService . getInstance ( ) . getExecutor ( database ) ; int totalRows = ExecutorService . getInstance ( ) . getExecutor ( database ) . queryForInt ( new SelectFromDatabaseChangeLogStatement ( new ColumnConfig ( ) . setName ( "COUNT(*)" , true ) ) ) ; if ( totalRows == 0 ) { ChangeSet emptyChangeSet = new ChangeSet ( String . valueOf ( new Date ( ) . getTime ( ) ) , "liquibase" , false , false , "liquibase-internal" , null , null , getDatabase ( ) . getObjectQuotingStrategy ( ) , null ) ; this . setExecType ( emptyChangeSet , ChangeSet . ExecType . EXECUTED ) ; } executor . execute ( new TagDatabaseStatement ( tagString ) ) ; getDatabase ( ) . commit ( ) ; if ( this . ranChangeSetList != null ) { ranChangeSetList . get ( ranChangeSetList . size ( ) - 1 ) . setTag ( tagString ) ; } }

Tags the database changelog with the given string.

Tags the database changelog with the given string .


public Precondition create(String tagName) {
        Class<?> aClass = preconditions.get(tagName);
        if (aClass == null) {
            return null;
        }
        try {
            return (Precondition) aClass.getConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

public Precondition create ( String tagName ) { Class < ? > aClass = preconditions . get ( tagName ) ; if ( aClass == null ) { return null ; } try { return ( Precondition ) aClass . getConstructor ( ) . newInstance ( ) ; } catch ( Exception e ) { throw new RuntimeException ( e ) ; } }

Create a new Precondition subclass based on the given tag name.

Create a new Precondition subclass based on the given tag name .


public static boolean isNowOrTodayFormat(String value) {
        boolean ret = false;
        if (value != null) {
            String lowerValue = value.toLowerCase();
            if (lowerValue.length() >= NOW_LENGTH && lowerValue.startsWith(NOW)) {
                ret = true;
            } else if (lowerValue.length() >= TODAY_LENGTH && lowerValue.startsWith(TODAY)) {
                ret = true;
            }
        }
        return ret;
    }

public static boolean isNowOrTodayFormat ( String value ) { boolean ret = false ; if ( value != null ) { String lowerValue = value . toLowerCase ( ) ; if ( lowerValue . length ( ) >= NOW_LENGTH && lowerValue . startsWith ( NOW ) ) { ret = true ; } else if ( lowerValue . length ( ) >= TODAY_LENGTH && lowerValue . startsWith ( TODAY ) ) { ret = true ; } } return ret ; }

Checks if date starts with "NOW" or "TODAY".

@param value value to test
@return true if value starts with "NOW" or "TODAY" (case insensitive), false otherwise.

Checks if date starts with NOW or TODAY .


public Object getValue(String key, DatabaseChangeLog changeLog) {
        ChangeLogParameter parameter = findParameter(key, changeLog);
        return (parameter != null) ? parameter.getValue() : null;
    }

public Object getValue ( String key , DatabaseChangeLog changeLog ) { ChangeLogParameter parameter = findParameter ( key , changeLog ) ; return ( parameter != null ) ? parameter . getValue ( ) : null ; }

Return the value of a parameter

@param key Name of the parameter
@return The parameter value or null if not found. (Note that null can also be return if it is the parameter
value. For strict parameter existence use {@link #hasValue(String, DatabaseChangeLog)}


private void setValidateOptionIfAvailable(Database database, UniqueConstraint uniqueConstraint, Map<String, ?> columnsMetadata) {
        if (!(database instanceof OracleDatabase)) {
            return;
        }
        final Object constraintValidate = columnsMetadata.get("CONSTRAINT_VALIDATE");
        final String VALIDATE = "VALIDATED";
        if (constraintValidate!=null && !constraintValidate.toString().trim().isEmpty()) {
            uniqueConstraint.setShouldValidate(VALIDATE.equals(cleanNameFromDatabase(constraintValidate.toString().trim(), database)));
        }
    }

private void setValidateOptionIfAvailable ( Database database , UniqueConstraint uniqueConstraint , Map < String , ? > columnsMetadata ) { if ( ! ( database instanceof OracleDatabase ) ) { return ; } final Object constraintValidate = columnsMetadata . get ( "CONSTRAINT_VALIDATE" ) ; final String VALIDATE = "VALIDATED" ; if ( constraintValidate != null && ! constraintValidate . toString ( ) . trim ( ) . isEmpty ( ) ) { uniqueConstraint . setShouldValidate ( VALIDATE . equals ( cleanNameFromDatabase ( constraintValidate . toString ( ) . trim ( ) , database ) ) ) ; } }

Method to map 'validate' option for UC. This thing works only for ORACLE

@param database - DB where UC will be created
@param uniqueConstraint - UC object to persist validate option
@param columnsMetadata - it's a cache-map to get metadata about UC

Method to map validate option for UC . This thing works only for ORACLE


private String getUniqueConstraintsSqlInformix(InformixDatabase database, Schema schema, String name) {
        StringBuffer sqlBuf = new StringBuffer();

        sqlBuf.append("SELECT * FROM (\n");

        // Yes, I am serious about this. It appears there are neither CTE/WITH clauses nor PIVOT/UNPIVOT operators
        // in Informix SQL.
        for (int i=1; i<=16; i++) {
            if (i>1)
                sqlBuf.append("UNION ALL\n");
            sqlBuf.append(
                String.format("  SELECT\n" +
                        "    CONS.owner,\n" +
                        "    CONS.constrname AS constraint_name,\n" +
                        "    COL.colname AS column_name,\n" +
                        "    CONS.constrtype,\n" +
                        "    %d               AS column_index\n" +
                        "  FROM informix.sysconstraints CONS\n" +
                        "    JOIN informix.sysindexes IDX ON CONS.idxname = IDX.idxname\n" +
                        "    JOIN informix.syscolumns COL ON COL.tabid = CONS.tabid AND COL.colno = IDX.part%d\n",
                        i, i
                )
            );
        }

        // Finish the subquery and filter on the U(NIQUE) constraint type
        sqlBuf.append(
                "                ) SUBQ\n" +
                "WHERE constrtype='U' \n");

        String catalogName = database.correctObjectName(schema.getCatalogName(), Catalog.class);
        String constraintName = database.correctObjectName(name, UniqueConstraint.class);

        // If possible, filter for catalog name and/or constraint name
        if (catalogName != null) {
            sqlBuf.append("AND owner='" + catalogName + "'\n");
        }
        if (constraintName != null) {
            sqlBuf.append("AND constraint_name='" + constraintName + "'");
        }

        // For correct processing, it is important that we get all columns in order.
        sqlBuf.append("ORDER BY owner, constraint_name, column_index");

        // Return the query
        return sqlBuf.toString();
    }

"    %d               AS column_index\n"

Gets an SQL query that returns the constraint names and columns for all UNIQUE constraints.
@param database A database object of the InformixDatabase type
@param schema Name of the schema to examine (or null for all)
@param name Name of the constraint to examine (or null for all)
@return A lengthy SQL statement that fetches the constraint names and columns

Gets an SQL query that returns the constraint names and columns for all UNIQUE constraints .


public Map<String, ChangeParameterMetaData> getSetParameters(Change change) {
        Map<String, ChangeParameterMetaData> returnMap = new HashMap<>();
        for (Map.Entry<String, ChangeParameterMetaData> entry : getParameters().entrySet()) {
            if (entry.getValue().getCurrentValue(change) != null) {
                returnMap.put(entry.getKey(), entry.getValue());
            }
        }
        return Collections.unmodifiableMap(returnMap);
    }

public Map < String , ChangeParameterMetaData > getSetParameters ( Change change ) { Map < String , ChangeParameterMetaData > returnMap = new HashMap <> ( ) ; for ( Map . Entry < String , ChangeParameterMetaData > entry : getParameters ( ) . entrySet ( ) ) { if ( entry . getValue ( ) . getCurrentValue ( change ) != null ) { returnMap . put ( entry . getKey ( ) , entry . getValue ( ) ) ; } } return Collections . unmodifiableMap ( returnMap ) ; }

Return the parameters of the given change that are set to a non-null value. Will never return a null map, only an empty or populated map.

Return the parameters of the given change that are set to a non - null value . Will never return a null map only an empty or populated map .


public Map<String, ChangeParameterMetaData> getRequiredParameters(Database database) {
        Map<String, ChangeParameterMetaData> returnMap = new HashMap<>();

        for (ChangeParameterMetaData metaData : parameters.values()) {
            if (metaData.isRequiredFor(database)) {
                returnMap.put(metaData.getParameterName(), metaData);
            }
        }
        return returnMap;
    }

public Map < String , ChangeParameterMetaData > getRequiredParameters ( Database database ) { Map < String , ChangeParameterMetaData > returnMap = new HashMap <> ( ) ; for ( ChangeParameterMetaData metaData : parameters . values ( ) ) { if ( metaData . isRequiredFor ( database ) ) { returnMap . put ( metaData . getParameterName ( ) , metaData ) ; } } return returnMap ; }

Returns the required parameters for this change for the given database. Will never return a null map, only an empty or populated map.

Returns the required parameters for this change for the given database . Will never return a null map only an empty or populated map .


private String convertToString(Object newValue, Database database) {
    String sqlString;
    if (newValue == null || newValue.toString().equals("") || newValue.toString().equalsIgnoreCase("NULL")) {
      sqlString = "NULL::INTEGER";
    } else if (newValue instanceof String && !looksLikeFunctionCall(((String) newValue), database)) {
      sqlString = "'" + database.escapeStringForDatabase(newValue.toString()) + "'";
    } else if (newValue instanceof Date) {
      sqlString = database.getDateLiteral(((Date) newValue));
    } else if (newValue instanceof Boolean) {
      if (((Boolean) newValue)) {
        sqlString = DataTypeFactory.getInstance().getTrueBooleanValue(database);
      } else {
        sqlString = DataTypeFactory.getInstance().getFalseBooleanValue(database);
      }
    } else {
      sqlString = newValue.toString();
    }
    return sqlString;
  }

private String convertToString ( Object newValue , Database database ) { String sqlString ; if ( newValue == null || newValue . toString ( ) . equals ( "" ) || newValue . toString ( ) . equalsIgnoreCase ( "NULL" ) ) { sqlString = "NULL::INTEGER" ; } else if ( newValue instanceof String && ! looksLikeFunctionCall ( ( ( String ) newValue ) , database ) ) { sqlString = "'" + database . escapeStringForDatabase ( newValue . toString ( ) ) + "'" ; } else if ( newValue instanceof Date ) { sqlString = database . getDateLiteral ( ( ( Date ) newValue ) ) ; } else if ( newValue instanceof Boolean ) { if ( ( ( Boolean ) newValue ) ) { sqlString = DataTypeFactory . getInstance ( ) . getTrueBooleanValue ( database ) ; } else { sqlString = DataTypeFactory . getInstance ( ) . getFalseBooleanValue ( database ) ; } } else { sqlString = newValue . toString ( ) ; } return sqlString ; }

Copied and modified from liquibase.sqlgenerator.core.InsertOrUpdateGeneratorMySQL

Copied and modified from liquibase . sqlgenerator . core . InsertOrUpdateGeneratorMySQL


@Override
    public Set<String> getSerializableFields() {
        return Scope.getCurrentScope().getSingleton(ChangeFactory.class).getChangeMetaData(this).getParameters().keySet();
    }

@ Override public Set < String > getSerializableFields ( ) { return Scope . getCurrentScope ( ) . getSingleton ( ChangeFactory . class ) . getChangeMetaData ( this ) . getParameters ( ) . keySet ( ) ; }

Returns the fields on this change that are serializable.

Returns the fields on this change that are serializable .


private static String doGetFullPath(String filename, boolean includeSeparator) {
        if (filename == null) {
            return null;
        }
        int prefix = getPrefixLength(filename);
        if (prefix < 0) {
            return null;
        }
        if (prefix >= filename.length()) {
            if (includeSeparator) {
                return getPrefix(filename);  // add end slash if necessary
            } else {
                return filename;
            }
        }
        int index = indexOfLastSeparator(filename);
        if (index < 0) {
            return filename.substring(0, prefix);
        }
        int end = index + (includeSeparator ?  1 : 0);
        return filename.substring(0, end);
    }

private
static
String
doGetFullPath
(
String
filename
,
boolean
includeSeparator
)
{
if
(
filename
==
)
{
return
;
}
int
prefix
=
getPrefixLength
(
filename
)
;
if
(
prefix
<
0
)
{
return
;
}
if
(
prefix
>=
filename
.
length
(
)
)
{
if
(
includeSeparator
)
{
return
getPrefix
(
filename
)
;
// add end slash if necessary
}
else
{
return
filename
;
}
}
int
index
=
indexOfLastSeparator
(
filename
)
;
if
(
index
<
0
)
{
return
filename
.
substring
(
0
,
prefix
)
;
}
int
end
=
index
+
(
includeSeparator
1
:
0
)
;
return
filename
.
substring
(
0
,
end
)
;
}

Does the work of getting the path.

@param filename  the filename
@param includeSeparator  true to include the end separator
@return the path


protected void createIndexLookup(String[] values) {
      if (indexLookup.isEmpty()) {
         for (int i = 0; i < values.length; i++) {
            indexLookup.put(values[i], i);
         }
      }
   }

protected void createIndexLookup ( String [ ] values ) { if ( indexLookup . isEmpty ( ) ) { for ( int i = 0 ; i < values . length ; i ++ ) { indexLookup . put ( values [ i ] , i ) ; } } }

Creates an index map of column names to column position.
@param values - array of header values.

Creates an index map of column names to column position .


@Override
   public Integer getColumnIndex(String name) {
      if (null == header) {
         throw new IllegalStateException("The header row hasn't been read yet.");
      }

      createIndexLookup(header);

      return indexLookup.get(name);
   }

@
Override
public
Integer
getColumnIndex
(
String
name
)
{
if
(
==
header
)
{
throw
new
IllegalStateException
(
"The header row hasn't been read yet."
)
;
}
createIndexLookup
(
header
)
;
return
indexLookup
.
get
(
name
)
;
}

Gets the column index that corresponds to a specific colum name.
If the CSV file doesn't have a header row, this method will always return
null.

@param name the column name
@return the column index, or null if the name doesn't exist

Gets the column index that corresponds to a specific colum name . If the CSV file doesn t have a header row this method will always return null .


@Override
   public PropertyDescriptor findDescriptor(int col) throws IntrospectionException {
      String columnName = getColumnName(col);
      return (StringUtil.trimToNull(columnName) != null) ? findDescriptor(columnName) : null;
   }

@ Override public PropertyDescriptor findDescriptor ( int col ) throws IntrospectionException { String columnName = getColumnName ( col ) ; return ( StringUtil . trimToNull ( columnName ) != null ) ? findDescriptor ( columnName ) : null ; }

Gets the property descriptor for a given column position.
@param col the column to find the description for
@return - the property descriptor for the column position or null if one could not be found.
@throws IntrospectionException - thrown on error retrieving the property description.

Gets the property descriptor for a given column position .


@Override
   public BeanField findField(int col) {
      String columnName = getColumnName(col);
      return (StringUtil.trimToNull(columnName) != null) ? findField(columnName) : null;
   }

@ Override public BeanField findField ( int col ) { String columnName = getColumnName ( col ) ; return ( StringUtil . trimToNull ( columnName ) != null ) ? findField ( columnName ) : null ; }

Gets the field for a given column position.

@param col the column to find the field for
@return - BeanField containing the field - and whether it is mandatory - for a given column position, or null if
one could not be found

Gets the field for a given column position .


public String getColumnName(int col) {
      return ((null != header) && (col < header.length)) ? header[col] : null;
   }

public String getColumnName ( int col ) { return ( ( null != header ) && ( col < header . length ) ) ? header [ col ] : null ; }

Get the column name for a given column position.

@param col - column position.
@return - the column name or null if the position is larger than the header array or there is no headers defined.

Get the column name for a given column position .


protected PropertyDescriptor findDescriptor(String name) throws IntrospectionException {
      if (null == descriptorMap) {
         descriptorMap = loadDescriptorMap(); //lazy load descriptors
      }
      return descriptorMap.get(name.toUpperCase().trim());
   }

protected
PropertyDescriptor
findDescriptor
(
String
name
)
throws
IntrospectionException
{
if
(
==
descriptorMap
)
{
descriptorMap
=
loadDescriptorMap
(
)
;
//lazy load descriptors
}
return
descriptorMap
.
get
(
name
.
toUpperCase
(
)
.
trim
(
)
)
;
}

Find the property descriptor for a given column.
@param name - column name to look up.
@return - the property descriptor for the column.
@throws IntrospectionException - thrown on error loading the property descriptors.

Find the property descriptor for a given column .


protected BeanField findField(String name) {
      if (null == fieldMap) {
         fieldMap = loadFieldMap(); //lazy load fields
      }
      return fieldMap.get(name.toUpperCase().trim());
   }

protected
BeanField
findField
(
String
name
)
{
if
(
==
fieldMap
)
{
fieldMap
=
loadFieldMap
(
)
;
//lazy load fields
}
return
fieldMap
.
get
(
name
.
toUpperCase
(
)
.
trim
(
)
)
;
}

Find the field for a given column.

@param name - the column name to look up.
@return - BeanField containing the field - and whether it is mandatory - for the column.


protected boolean matches(String name, PropertyDescriptor desc) {
      return desc.getName().equals(name.trim());
   }

protected boolean matches ( String name , PropertyDescriptor desc ) { return desc . getName ( ) . equals ( name . trim ( ) ) ; }

Determines if the name of a property descriptor matches the column name.
Currently only used by unit tests.
@param name - name of the column.
@param desc - property descriptor to check against
@return - true if the name matches the name in the property descriptor.

Determines if the name of a property descriptor matches the column name . Currently only used by unit tests .


protected Map<String, PropertyDescriptor> loadDescriptorMap() throws IntrospectionException {
      Map<String, PropertyDescriptor> map = new HashMap<>();

      PropertyDescriptor[] descriptors;
      descriptors = loadDescriptors(getType());
      for (PropertyDescriptor descriptor : descriptors) {
         map.put(descriptor.getName().toUpperCase().trim(), descriptor);
      }

      return map;
   }

protected Map < String , PropertyDescriptor > loadDescriptorMap ( ) throws IntrospectionException { Map < String , PropertyDescriptor > map = new HashMap <> ( ) ; PropertyDescriptor [ ] descriptors ; descriptors = loadDescriptors ( getType ( ) ) ; for ( PropertyDescriptor descriptor : descriptors ) { map . put ( descriptor . getName ( ) . toUpperCase ( ) . trim ( ) , descriptor ) ; } return map ; }

builds a map of property descriptors for the Bean.
@return - map of property descriptors
@throws IntrospectionException - thrown on error getting information about the bean.

builds a map of property descriptors for the Bean .


@Override
   public String getColumnName(int col) {
      return (col < columnMapping.length) ? columnMapping[col] : null;
   }

@ Override public String getColumnName ( int col ) { return ( col < columnMapping . length ) ? columnMapping [ col ] : null ; }

gets a column name.
@param col - position of the column.
@return - column name or null if col > number of mappings.


public void setColumnMapping(String... columnMapping) {
       this.columnMapping = (columnMapping != null) ? columnMapping.clone() : new String[]{};
      resetIndexMap();
      createIndexLookup(this.columnMapping);
   }

public void setColumnMapping ( String ... columnMapping ) { this . columnMapping = ( columnMapping != null ) ? columnMapping . clone ( ) : new String [ ] { } ; resetIndexMap ( ) ; createIndexLookup ( this . columnMapping ) ; }

Setter for the ColumnMappings.
@param columnMapping - column names to be mapped.


protected int getSize() {
        if (getParameters().length == 0) {
            return -1;
        }

        if (getParameters()[0] instanceof String) {
            return Integer.parseInt((String) getParameters()[0]);
        }

        if (getParameters()[0] instanceof Number) {
            return ((Number) getParameters()[0]).intValue();
        }

        return -1;
    }

protected int getSize ( ) { if ( getParameters ( ) . length == 0 ) { return - 1 ; } if ( getParameters ( ) [ 0 ] instanceof String ) { return Integer . parseInt ( ( String ) getParameters ( ) [ 0 ] ) ; } if ( getParameters ( ) [ 0 ] instanceof Number ) { return ( ( Number ) getParameters ( ) [ 0 ] ) . intValue ( ) ; } return - 1 ; }

Return the size of this data type definition. If unknown or unspecified, return -1

Return the size of this data type definition . If unknown or unspecified return - 1


public static boolean supportsDefaultValueComputed(String columnType, String defaultValue) {
        HashSet<String> possibleComputedValues = SUPPORTED_DEFAULT_VALUE_COMPUTED_MAP.get(columnType);
        return (possibleComputedValues != null) && possibleComputedValues.contains(defaultValue.toLowerCase());
    }

public static boolean supportsDefaultValueComputed ( String columnType , String defaultValue ) { HashSet < String > possibleComputedValues = SUPPORTED_DEFAULT_VALUE_COMPUTED_MAP . get ( columnType ) ; return ( possibleComputedValues != null ) && possibleComputedValues . contains ( defaultValue . toLowerCase ( ) ) ; }

Checks to see if the string is an acceptable computed value for HSQL
"datetime" columns are the only columns for which HSQL supports computer values.

@param columnType   String of the column's data type
@param defaultValue String to be checked for valid valueComputed in HSQL
@return boolean True if the string represents a function supported by HSQL for default values

Checks to see if the string is an acceptable computed value for HSQL datetime columns are the only columns for which HSQL supports computer values .


public List<ChangeSetStatus> getChangeSetsToRun() {
        ArrayList<ChangeSetStatus> returnList = new ArrayList<>();
        for (ChangeSetStatus status : changeSetStatuses.values()) {
            if (status.getWillRun()) {
                returnList.add(status);
            }
        }

        return returnList;
    }

public List < ChangeSetStatus > getChangeSetsToRun ( ) { ArrayList < ChangeSetStatus > returnList = new ArrayList <> ( ) ; for ( ChangeSetStatus status : changeSetStatuses . values ( ) ) { if ( status . getWillRun ( ) ) { returnList . add ( status ) ; } } return returnList ; }

Return the change sets that will execute


@Override
    public String escapeObjectName(String objectName, Class<? extends DatabaseObject> objectType) {
        if ((quotingStrategy == ObjectQuotingStrategy.LEGACY) && hasMixedCase(objectName)) {
            return "\"" + objectName + "\"";
        } else if (objectType != null && LiquibaseColumn.class.isAssignableFrom(objectType)) {
            return (objectName != null && !objectName.isEmpty()) ? objectName.trim() : objectName;
        }

        return super.escapeObjectName(objectName, objectType);
    }

@ Override public String escapeObjectName ( String objectName , Class < ? extends DatabaseObject > objectType ) { if ( ( quotingStrategy == ObjectQuotingStrategy . LEGACY ) && hasMixedCase ( objectName ) ) { return "\"" + objectName + "\"" ; } else if ( objectType != null && LiquibaseColumn . class . isAssignableFrom ( objectType ) ) { return ( objectName != null && ! objectName . isEmpty ( ) ) ? objectName . trim ( ) : objectName ; } return super . escapeObjectName ( objectName , objectType ) ; }

This has special case logic to handle NOT quoting column names if they are
of type 'LiquibaseColumn' - columns in the DATABASECHANGELOG or DATABASECHANGELOGLOCK
tables.

This has special case logic to handle NOT quoting column names if they are of type LiquibaseColumn - columns in the DATABASECHANGELOG or DATABASECHANGELOGLOCK tables .


public ColumnConfig setValueNumeric(String valueNumeric) {
        if ((valueNumeric == null) || "null".equalsIgnoreCase(valueNumeric)) {
            this.valueNumeric = null;
        } else {
            String saved = valueNumeric;
            if (valueNumeric.startsWith("(")) {
                valueNumeric = valueNumeric.replaceFirst("^\\(", "");
                valueNumeric = valueNumeric.replaceFirst("\\)$", "");
            }

            try {
                this.valueNumeric = ValueNumeric.of(Locale.US, valueNumeric);
            } catch (ParseException e) {
                this.valueComputed = new DatabaseFunction(saved);
            }
        }

        return this;
    }

public ColumnConfig setValueNumeric ( String valueNumeric ) { if ( ( valueNumeric == null ) || "null" . equalsIgnoreCase ( valueNumeric ) ) { this . valueNumeric = null ; } else { String saved = valueNumeric ; if ( valueNumeric . startsWith ( "(" ) ) { valueNumeric = valueNumeric . replaceFirst ( "^\\(" , "" ) ; valueNumeric = valueNumeric . replaceFirst ( "\\)$" , "" ) ; } try { this . valueNumeric = ValueNumeric . of ( Locale . US , valueNumeric ) ; } catch ( ParseException e ) { this . valueComputed = new DatabaseFunction ( saved ) ; } } return this ; }

Set the number this column should be set to. Supports integers and decimals, and strips off any wrapping
parentheses. If the passed value cannot be parsed as a number in US locale, it is assumed to be a function
that returns a number. If the value "null" is passed, it will set a null value.

Set the number this column should be set to . Supports integers and decimals and strips off any wrapping parentheses . If the passed value cannot be parsed as a number in US locale it is assumed to be a function that returns a number . If the value null is passed it will set a null value .


public ColumnConfig setValueBoolean(String valueBoolean) {
        valueBoolean = StringUtil.trimToNull(valueBoolean);
        if ((valueBoolean == null) || "null".equalsIgnoreCase(valueBoolean)) {
            this.valueBoolean = null;
        } else {
            if ("true".equalsIgnoreCase(valueBoolean) || "1".equals(valueBoolean)) {
                this.valueBoolean = true;
            } else if ("false".equalsIgnoreCase(valueBoolean) || "0".equals(valueBoolean)) {
                this.valueBoolean = false;
            } else {
                this.valueComputed = new DatabaseFunction(valueBoolean);
            }

        }

        return this;
    }

public ColumnConfig setValueBoolean ( String valueBoolean ) { valueBoolean = StringUtil . trimToNull ( valueBoolean ) ; if ( ( valueBoolean == null ) || "null" . equalsIgnoreCase ( valueBoolean ) ) { this . valueBoolean = null ; } else { if ( "true" . equalsIgnoreCase ( valueBoolean ) || "1" . equals ( valueBoolean ) ) { this . valueBoolean = true ; } else if ( "false" . equalsIgnoreCase ( valueBoolean ) || "0" . equals ( valueBoolean ) ) { this . valueBoolean = false ; } else { this . valueComputed = new DatabaseFunction ( valueBoolean ) ; } } return this ; }

Set the valueBoolean based on a given string.
If the passed value cannot be parsed as a date, it is assumed to be a function that returns a boolean.
If the string "null" or an empty string is passed, it will set a null value.
If "1" is passed, defaultValueBoolean is set to true. If 0 is passed, defaultValueBoolean is set to false

Set the valueBoolean based on a given string . If the passed value cannot be parsed as a date it is assumed to be a function that returns a boolean . If the string null or an empty string is passed it will set a null value . If 1 is passed defaultValueBoolean is set to true . If 0 is passed defaultValueBoolean is set to false


public ColumnConfig setDefaultValueBoolean(String defaultValueBoolean) {
        defaultValueBoolean = StringUtil.trimToNull(defaultValueBoolean);
        if ((defaultValueBoolean == null) || "null".equalsIgnoreCase(defaultValueBoolean)) {
            this.defaultValueBoolean = null;
        } else {
            if ("true".equalsIgnoreCase(defaultValueBoolean) || "1".equals(defaultValueBoolean)) {
                this.defaultValueBoolean = true;
            } else if ("false".equalsIgnoreCase(defaultValueBoolean) || "0".equals(defaultValueBoolean)) {
                this.defaultValueBoolean = false;
            } else {
                this.defaultValueComputed = new DatabaseFunction(defaultValueBoolean);
            }

        }

        return this;
    }

public ColumnConfig setDefaultValueBoolean ( String defaultValueBoolean ) { defaultValueBoolean = StringUtil . trimToNull ( defaultValueBoolean ) ; if ( ( defaultValueBoolean == null ) || "null" . equalsIgnoreCase ( defaultValueBoolean ) ) { this . defaultValueBoolean = null ; } else { if ( "true" . equalsIgnoreCase ( defaultValueBoolean ) || "1" . equals ( defaultValueBoolean ) ) { this . defaultValueBoolean = true ; } else if ( "false" . equalsIgnoreCase ( defaultValueBoolean ) || "0" . equals ( defaultValueBoolean ) ) { this . defaultValueBoolean = false ; } else { this . defaultValueComputed = new DatabaseFunction ( defaultValueBoolean ) ; } } return this ; }

Set the defaultValueBoolean based on a given string.
If the passed value cannot be parsed as a date, it is assumed to be a function that returns a boolean.
If the string "null" or an empty string is passed, it will set a null value.
If "1" is passed, defaultValueBoolean is set to true. If 0 is passed, defaultValueBoolean is set to false

Set the defaultValueBoolean based on a given string . If the passed value cannot be parsed as a date it is assumed to be a function that returns a boolean . If the string null or an empty string is passed it will set a null value . If 1 is passed defaultValueBoolean is set to true . If 0 is passed defaultValueBoolean is set to false


public void unregister(String name) {
        for (Change change : new ArrayList<>(findAllInstances())) {
            if (getChangeMetaData(change).getName().equals(name)) {
                this.removeInstance(change);
            }
        }
    }

public void unregister ( String name ) { for ( Change change : new ArrayList <> ( findAllInstances ( ) ) ) { if ( getChangeMetaData ( change ) . getName ( ) . equals ( name ) ) { this . removeInstance ( change ) ; } } }

Unregister all instances of a given Change name. Normally used for testing, but can be called manually if needed.

Unregister all instances of a given Change name . Normally used for testing but can be called manually if needed .


public SortedSet<String> getDefinedChanges() {
        SortedSet<String> names = new TreeSet<>();
        for (Change change : findAllInstances()) {
            names.add(getChangeMetaData(change).getName());
        }
        return Collections.unmodifiableSortedSet(names);
    }

public SortedSet < String > getDefinedChanges ( ) { SortedSet < String > names = new TreeSet <> ( ) ; for ( Change change : findAllInstances ( ) ) { names . add ( getChangeMetaData ( change ) . getName ( ) ) ; } return Collections . unmodifiableSortedSet ( names ) ; }

Returns all defined changes in the registry. Returned set is not modifiable.

Returns all defined changes in the registry . Returned set is not modifiable .


public Change create(String name) {
        Change plugin = getPlugin(name);
        if (plugin == null) {
            return null;
        }
        try {
            return plugin.getClass().getConstructor().newInstance();
        } catch (Exception e) {
            throw new UnexpectedLiquibaseException(e);
        }
    }

public Change create ( String name ) { Change plugin = getPlugin ( name ) ; if ( plugin == null ) { return null ; } try { return plugin . getClass ( ) . getConstructor ( ) . newInstance ( ) ; } catch ( Exception e ) { throw new UnexpectedLiquibaseException ( e ) ; } }

Create a new Change implementation for the given change name. The class of the constructed object will be the Change implementation with the highest priority.
Each call to create will return a new instance of the Change.

Create a new Change implementation for the given change name . The class of the constructed object will be the Change implementation with the highest priority . Each call to create will return a new instance of the Change .


@Override
    public boolean promptForNonLocalDatabase(Database database) throws DatabaseException {
        return JOptionPane.showConfirmDialog(null, "You are running a database migration against a non-local database." + StreamUtil.getLineSeparator() +
                "Database URL is: " + database.getConnection().getURL() + StreamUtil.getLineSeparator() +
                "Username is: " + database.getConnection().getConnectionUserName() + StreamUtil.getLineSeparator() + StreamUtil.getLineSeparator() +
                "Are you sure you want to do this?",
                "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.NO_OPTION;
    }

Displays swing-based dialog about running against a non-localhost database.
Returns true if the user selected that they are OK with that.

Displays swing - based dialog about running against a non - localhost database . Returns true if the user selected that they are OK with that .