All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.flyway.ant.AbstractMigrationLoadingTask Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010-2013 Axel Fontaine and the many contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.flyway.ant;

import com.googlecode.flyway.core.Flyway;
import com.googlecode.flyway.core.api.MigrationVersion;
import com.googlecode.flyway.core.util.Location;
import com.googlecode.flyway.core.util.StringUtils;
import com.googlecode.flyway.core.validation.ValidationErrorMode;
import org.apache.tools.ant.Project;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

/**
 * Base class for tasks that rely on loading migrations from the classpath.
 */
@SuppressWarnings({"UnusedDeclaration"})
public abstract class AbstractMigrationLoadingTask extends AbstractFlywayTask {
    /**
     * Property name prefix for placeholders that are configured through properties.
     */
    private static final String PLACEHOLDERS_PROPERTY_PREFIX = "flyway.placeholders.";

    /**
     * Locations on the classpath to scan recursively for migrations. Locations may contain both sql
     * and java-based migrations. (default: db.migration)
Also configurable with Ant Property: ${flyway.locations} */ private String[] locations; /** * The encoding of Sql migrations. (default: UTF-8)
Also configurable with Ant Property: ${flyway.encoding} */ private String encoding; /** * The file name prefix for Sql migrations (default: V)
Also configurable with Ant Property: ${flyway.sqlMigrationPrefix} */ private String sqlMigrationPrefix; /** * The file name suffix for Sql migrations (default: .sql)
Also configurable with Ant Property: ${flyway.sqlMigrationSuffix} */ private String sqlMigrationSuffix; /** * The action to take when validation fails.

Possible values are:

FAIL (default)
* Throw an exception and fail.

CLEAN (Warning ! Do not use in produktion !)
Cleans the * database.

This is exclusively intended as a convenience for development. Even tough we strongly * recommend not to change migration scripts once they have been checked into SCM and run, this provides a way of * dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that the next * migration will bring you back to the state checked into SCM.

This property has no effect when * validationMode is set to NONE.

Also configurable with Ant Property: ${flyway.validationErrorMode} * * @deprecated Use cleanOnValidationError instead. Will be removed in Flyway 3.0. */ @Deprecated private String validationErrorMode; /** * Whether to automatically call clean or not when a validation error occurs. (default: {@code false})
*

This is exclusively intended as a convenience for development. Even tough we * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that * the next migration will bring you back to the state checked into SCM.

*

Warning ! Do not enable in production !

*
Also configurable with Ant Property: ${flyway.cleanOnValidationError} */ private boolean cleanOnValidationError; /** * The target version up to which Flyway should run migrations. Migrations with a higher version number will not be * applied. (default: the latest version)
Also configurable with Ant Property: ${flyway.target} */ private String target; /** * Allows migrations to be run "out of order" (default: {@code false}). *

If you already have versions 1 and 3 applied, and now a version 2 is found, * it will be applied too instead of being ignored.

* Also configurable with Ant Property: ${flyway.outOfOrder} */ private boolean outOfOrder; /** * A map of <placeholder, replacementValue> to apply to sql migration scripts. */ private Map placeholders = new HashMap(); /** * The prefix of every placeholder. (default: ${ )
Also configurable with Ant Property: ${flyway.placeholderPrefix} */ private String placeholderPrefix; /** * The suffix of every placeholder. (default: } )
Also configurable with Ant Property: ${flyway.placeholderSuffix} */ private String placeholderSuffix; /** * Do not use. For Ant itself. * * @param locations The locations on the classpath. */ public void addConfiguredLocations(Locations locations) { this.locations = locations.locations.toArray(new String[locations.locations.size()]); } /** * @param encoding The encoding of Sql migrations. (default: UTF-8)
Also configurable with Ant Property: ${flyway.encoding} */ public void setEncoding(String encoding) { this.encoding = encoding; } /** * @param sqlMigrationPrefix The file name prefix for Sql migrations (default: V)
Also configurable with Ant Property: ${flyway.sqlMigrationPrefix} */ public void setSqlMigrationPrefix(String sqlMigrationPrefix) { this.sqlMigrationPrefix = sqlMigrationPrefix; } /** * @param sqlMigrationSuffix The file name suffix for Sql migrations (default: .sql)
Also configurable with Ant Property: ${flyway.sqlMigrationSuffix} */ public void setSqlMigrationSuffix(String sqlMigrationSuffix) { this.sqlMigrationSuffix = sqlMigrationSuffix; } /** * @param target The target version up to which Flyway should run migrations. Migrations with a higher version number will not be * applied. (default: the latest version)
Also configurable with Ant Property: ${flyway.target} */ public void setTarget(String target) { this.target = target; } /** * @param validationErrorMode The action to take when validation fails.

Possible values are:

FAIL (default)
* Throw an exception and fail.

CLEAN (Warning ! Do not use in produktion !)
Cleans the * database.

This is exclusively intended as a convenience for development. Even tough we strongly * recommend not to change migration scripts once they have been checked into SCM and run, this provides a way of * dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that the next * migration will bring you back to the state checked into SCM.

This property has no effect when * validationMode is set to NONE.

Also configurable with Ant Property: ${flyway.validationErrorMode} * @deprecated Use cleanOnValidationError instead. Will be removed in Flyway 3.0. */ @Deprecated public void setValidationErrorMode(String validationErrorMode) { this.validationErrorMode = validationErrorMode; } /** * @param cleanOnValidationError Whether to automatically call clean or not when a validation error occurs. (default: {@code false})
*

This is exclusively intended as a convenience for development. Even tough we * strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a * way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that * the next migration will bring you back to the state checked into SCM.

*

Warning ! Do not enable in production !

*
Also configurable with Ant Property: ${flyway.cleanOnValidationError} */ public void setCleanOnValidationError(boolean cleanOnValidationError) { this.cleanOnValidationError = cleanOnValidationError; } /** * @param outOfOrder Allows migrations to be run "out of order" (default: {@code false}). *

If you already have versions 1 and 3 applied, and now a version 2 is found, * it will be applied too instead of being ignored.

* Also configurable with Ant Property: ${flyway.outOfOrder} */ public void setOutOfOrder(boolean outOfOrder) { this.outOfOrder = outOfOrder; } /** * @param placeholderPrefix The prefix of every placeholder. (default: ${ )
Also configurable with Ant Property: ${flyway.placeholderPrefix} */ public void setPlaceholderPrefix(String placeholderPrefix) { this.placeholderPrefix = placeholderPrefix; } /** * @param placeholderSuffix The suffix of every placeholder. (default: } )
Also configurable with Ant Property: ${flyway.placeholderSuffix} */ public void setPlaceholderSuffix(String placeholderSuffix) { this.placeholderSuffix = placeholderSuffix; } /** * Adds a placeholder from a nested <placeholder> element. Called by Ant. * * @param placeholder The fully configured placeholder element. * @deprecated Use the <placeholders> element instead of adding individual <placeholder> elements directly. Will be removed in Flyway 3.0. */ @Deprecated public void addConfiguredPlaceholder(PlaceholderElement placeholder) { getProject().log(this, "The direct use of is deprecated." + " They should be nested inside a element." + " Support for this will be removed in Flyway 3.0.", null, Project.MSG_WARN); placeholders.put(placeholder.name, placeholder.value); } /** * Adds placeholders from a nested <placeholders> element. Called by Ant. * * @param placeholders The fully configured placeholders element. */ public void addConfiguredPlaceholders(PlaceholdersElement placeholders) { this.placeholders = placeholders.placeholders; } @Override protected final void doExecute(Flyway flyway) throws Exception { String[] locationsValue = getLocations(); if (locationsValue != null) { flyway.setLocations(locationsValue); } String encodingValue = useValueIfPropertyNotSet(encoding, "encoding"); if (encodingValue != null) { flyway.setEncoding(encodingValue); } String sqlMigrationPrefixValue = useValueIfPropertyNotSet(sqlMigrationPrefix, "sqlMigrationPrefix"); if (sqlMigrationPrefixValue != null) { flyway.setSqlMigrationPrefix(sqlMigrationPrefixValue); } String sqlMigrationSuffixValue = useValueIfPropertyNotSet(sqlMigrationSuffix, "sqlMigrationSuffix"); if (sqlMigrationSuffixValue != null) { flyway.setSqlMigrationSuffix(sqlMigrationSuffixValue); } String validationErrorModeValue = useValueIfPropertyNotSet(validationErrorMode, "validationErrorMode"); if (validationErrorModeValue != null) { flyway.setValidationErrorMode(ValidationErrorMode.valueOf(validationErrorModeValue.toUpperCase())); } flyway.setCleanOnValidationError(useValueIfPropertyNotSet(cleanOnValidationError, "cleanOnValidationError")); flyway.setOutOfOrder(useValueIfPropertyNotSet(outOfOrder, "outOfOrder")); String targetValue = useValueIfPropertyNotSet(target, "target"); if (targetValue != null) { flyway.setTarget(new MigrationVersion(targetValue)); } addPlaceholdersFromProperties(placeholders, getProject().getProperties()); flyway.setPlaceholders(placeholders); String placeholderPrefixValue = useValueIfPropertyNotSet(placeholderPrefix, "placeholderPrefix"); if (placeholderPrefixValue != null) { flyway.setPlaceholderPrefix(placeholderPrefixValue); } String placeholderSuffixValue = useValueIfPropertyNotSet(placeholderSuffix, "placeholderSuffix"); if (placeholderSuffixValue != null) { flyway.setPlaceholderSuffix(placeholderSuffixValue); } doExecuteWithMigrationConfig(flyway); } /** * @return The locations configured through Ant. */ private String[] getLocations() { String locationsProperty = getProject().getProperty("flyway.locations"); String[] locationsVal = null; if (locationsProperty != null) { locationsVal = StringUtils.tokenizeToStringArray(locationsProperty, ","); } else if (locations != null) { locationsVal = locations; } if (locationsVal != null) { //Adjust relative locations to be relative from Ant's basedir. File baseDir = getProject().getBaseDir(); for (int i = 0; i < locationsVal.length; i++) { locationsVal[i] = adjustRelativeFileSystemLocationToBaseDir(baseDir, locationsVal[i]); } } return locationsVal; } /** * Adjusts a relative filesystem location to Ant's basedir. All other locations are left untouched. * * @param baseDir Ant's basedir. * @param locationStr The location to adjust. * @return The adjusted location. */ /* private -> testing */ static String adjustRelativeFileSystemLocationToBaseDir(File baseDir, String locationStr) { Location location = new Location(locationStr); if (location.isFileSystem() && !new File(location.getPath()).isAbsolute()) { return Location.FILESYSTEM_PREFIX + baseDir.getAbsolutePath() + "/" + location.getPath(); } return locationStr; } /** * Adds the additional placeholders contained in these properties to the existing list. * * @param placeholders The existing list of placeholders. * @param properties The properties containing additional placeholders. */ private static void addPlaceholdersFromProperties(Map placeholders, Hashtable properties) { for (Object property : properties.keySet()) { String propertyName = (String) property; if (propertyName.startsWith(PLACEHOLDERS_PROPERTY_PREFIX) && propertyName.length() > PLACEHOLDERS_PROPERTY_PREFIX.length()) { String placeholderName = propertyName.substring(PLACEHOLDERS_PROPERTY_PREFIX.length()); String placeholderValue = (String) properties.get(propertyName); placeholders.put(placeholderName, placeholderValue); } } } /** * Executes Flyway fully configured for loading migrations. * * @param flyway The instance of Flyway to launch. * @throws Exception when the execution failed. */ protected abstract void doExecuteWithMigrationConfig(Flyway flyway) throws Exception; /** * The nested <locations> element of the task. Contains 1 or more <location> sub-elements. */ public static class Locations { /** * The classpath locations. */ List locations = new ArrayList(); /** * Do not use. For Ant itself. * * @param location A location on the classpath. */ public void addConfiguredLocation(LocationElement location) { locations.add(location.path); } } /** * One <location> sub-element within the <locations> element. */ public static class LocationElement { /** * The path of the location. */ private String path; /** * Do not use. For Ant itself. * * @param path The path of the location. */ public void setPath(String path) { this.path = path; } } /** * Nested <placeholders> element of the migrate Ant task. */ public static class PlaceholdersElement { /** * A map of <placeholder, replacementValue> to apply to sql migration scripts. */ Map placeholders = new HashMap(); /** * Adds a placeholder from a nested <placeholder> element. Called by Ant. * * @param placeholder The fully configured placeholder element. */ public void addConfiguredPlaceholder(PlaceholderElement placeholder) { placeholders.put(placeholder.name, placeholder.value); } } /** * Nested <placeholder> element inside the <placeholders> element of the migrate Ant task. */ public static class PlaceholderElement { /** * The name of the placeholder. */ private String name; /** * The value of the placeholder. */ private String value; /** * @param name The name of the placeholder. */ public void setName(String name) { this.name = name; } /** * @param value The value of the placeholder. */ public void setValue(String value) { this.value = value; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy