Skip to content

Commit

Permalink
Add support for vendor specific Flyway migration locations
Browse files Browse the repository at this point in the history
This commit adds support for using `{vendor}` placeholder in
`flyway.locations` configuration property value.

See spring-projectsgh-6900
  • Loading branch information
vpavic authored and snicoll committed Dec 22, 2016
1 parent 62bff10 commit 65c2d1f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,14 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -79,6 +82,8 @@ public StringOrNumberToMigrationVersionConverter stringOrNumberMigrationVersionC
@EnableConfigurationProperties(FlywayProperties.class)
public static class FlywayConfiguration {

private static final String VENDOR_PLACEHOLDER = "{vendor}";

private final FlywayProperties properties;

private final ResourceLoader resourceLoader;
Expand Down Expand Up @@ -126,7 +131,31 @@ private boolean hasAtLeastOneLocation() {
@Bean
@ConfigurationProperties(prefix = "flyway")
public Flyway flyway() {
Flyway flyway = new Flyway();
Flyway flyway = new Flyway() {

@Override
public void setLocations(String... locations) {
if (usesVendorLocation()) {
try {
String url = (String) JdbcUtils.extractDatabaseMetaData(
getDataSource(), "getURL");
DatabaseDriver vendor = DatabaseDriver.fromJdbcUrl(url);
if (vendor != DatabaseDriver.UNKNOWN) {
for (int i = 0; i < locations.length; i++) {
locations[i] = locations[i].replace(
VENDOR_PLACEHOLDER,
vendor.name().toLowerCase());
}
}
}
catch (MetaDataAccessException e) {
throw new IllegalStateException(e);
}
}
super.setLocations(locations);
}

};
if (this.properties.isCreateDataSource()) {
flyway.setDataSource(this.properties.getUrl(), this.properties.getUser(),
this.properties.getPassword(),
Expand All @@ -142,6 +171,15 @@ else if (this.flywayDataSource != null) {
return flyway;
}

private boolean usesVendorLocation() {
for (String location : this.properties.getLocations()) {
if (location.contains(VENDOR_PLACEHOLDER)) {
return true;
}
}
return false;
}

@Bean
@ConditionalOnMissingBean
public FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,18 @@ public void overrideBaselineVersionNumber() throws Exception {
.isEqualTo(MigrationVersion.fromVersion("1"));
}

@Test
public void useVendorDirectory() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context,
"flyway.locations:classpath:db/vendors/{vendor}");
registerAndRefresh(EmbeddedDataSourceConfiguration.class,
FlywayAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
Flyway flyway = this.context.getBean(Flyway.class);
assertThat(flyway.getLocations()).containsExactly(
"classpath:db/vendors/h2");
}

private void registerAndRefresh(Class<?>... annotatedClasses) {
this.context.register(annotatedClasses);
this.context.refresh();
Expand Down
Empty file.

0 comments on commit 65c2d1f

Please sign in to comment.