Reinstate mode for controlling DB initialization
Closes gh-26682
This commit is contained in:
parent
1a0e008a8c
commit
c52143727a
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.jdbc;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
|
@ -40,15 +39,14 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializationConfi
|
|||
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializationConfiguration.SharedCredentialsDataSourceInitializationConfiguration.DataSourceInitializationCondition;
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||
import org.springframework.boot.jdbc.DataSourceInitializationMode;
|
||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -80,6 +78,19 @@ class DataSourceInitializationConfiguration {
|
|||
return fallbackLocations;
|
||||
}
|
||||
|
||||
private static DatabaseInitializationMode mapMode(DataSourceInitializationMode mode) {
|
||||
switch (mode) {
|
||||
case ALWAYS:
|
||||
return DatabaseInitializationMode.ALWAYS;
|
||||
case EMBEDDED:
|
||||
return DatabaseInitializationMode.EMBEDDED;
|
||||
case NEVER:
|
||||
return DatabaseInitializationMode.NEVER;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected initialization mode '" + mode + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// Fully-qualified to work around javac bug in JDK 1.8
|
||||
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
|
||||
@org.springframework.context.annotation.Conditional(DifferentCredentialsCondition.class)
|
||||
|
|
@ -96,10 +107,10 @@ class DataSourceInitializationConfiguration {
|
|||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getSqlScriptEncoding());
|
||||
settings.setMode(mapMode(properties.getInitializationMode()));
|
||||
DataSource initializationDataSource = determineDataSource(dataSource::getObject,
|
||||
properties.getSchemaUsername(), properties.getSchemaPassword());
|
||||
return new InitializationModeDataSourceScriptDatabaseInitializer(initializationDataSource, settings,
|
||||
properties.getInitializationMode());
|
||||
return new DataSourceScriptDatabaseInitializer(initializationDataSource, settings);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
@ -111,10 +122,10 @@ class DataSourceInitializationConfiguration {
|
|||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getSqlScriptEncoding());
|
||||
settings.setMode(mapMode(properties.getInitializationMode()));
|
||||
DataSource initializationDataSource = determineDataSource(dataSource::getObject,
|
||||
properties.getDataUsername(), properties.getDataPassword());
|
||||
return new InitializationModeDataSourceScriptDatabaseInitializer(initializationDataSource, settings,
|
||||
properties.getInitializationMode());
|
||||
return new DataSourceScriptDatabaseInitializer(initializationDataSource, settings);
|
||||
}
|
||||
|
||||
static class DifferentCredentialsCondition extends AnyNestedCondition {
|
||||
|
|
@ -154,8 +165,8 @@ class DataSourceInitializationConfiguration {
|
|||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getSqlScriptEncoding());
|
||||
return new InitializationModeDataSourceScriptDatabaseInitializer(dataSource, settings,
|
||||
properties.getInitializationMode());
|
||||
settings.setMode(mapMode(properties.getInitializationMode()));
|
||||
return new DataSourceScriptDatabaseInitializer(dataSource, settings);
|
||||
}
|
||||
|
||||
static class DataSourceInitializationCondition extends SpringBootCondition {
|
||||
|
|
@ -186,25 +197,4 @@ class DataSourceInitializationConfiguration {
|
|||
|
||||
}
|
||||
|
||||
static class InitializationModeDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer {
|
||||
|
||||
private final DataSourceInitializationMode mode;
|
||||
|
||||
InitializationModeDataSourceScriptDatabaseInitializer(DataSource dataSource,
|
||||
DatabaseInitializationSettings settings, DataSourceInitializationMode mode) {
|
||||
super(dataSource, settings);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runScripts(List<Resource> resources, boolean continueOnError, String separator,
|
||||
Charset encoding) {
|
||||
if (this.mode == DataSourceInitializationMode.ALWAYS || (this.mode == DataSourceInitializationMode.EMBEDDED
|
||||
&& EmbeddedDatabaseConnection.isEmbedded(getDataSource()))) {
|
||||
super.runScripts(resources, continueOnError, separator, encoding);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
|
|||
}
|
||||
|
||||
@Deprecated
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.sql.init.enabled")
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.sql.init.mode")
|
||||
public DataSourceInitializationMode getInitializationMode() {
|
||||
return this.initializationMode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ final class SettingsCreator {
|
|||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getEncoding());
|
||||
settings.setMode(properties.getMode());
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,14 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
|||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration.SqlInitializationModeCondition;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
|
|
@ -36,11 +39,25 @@ import org.springframework.context.annotation.Import;
|
|||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(AbstractScriptDatabaseInitializer.class)
|
||||
@ConditionalOnProperty(prefix = "spring.sql.init", name = "enabled", matchIfMissing = true)
|
||||
@AutoConfigureAfter({ R2dbcAutoConfiguration.class, DataSourceAutoConfiguration.class })
|
||||
@EnableConfigurationProperties(SqlInitializationProperties.class)
|
||||
@Import({ DatabaseInitializationDependencyConfigurer.class, R2dbcInitializationConfiguration.class,
|
||||
DataSourceInitializationConfiguration.class })
|
||||
@ConditionalOnProperty(prefix = "spring.sql.init", name = "enabled", matchIfMissing = true)
|
||||
@Conditional(SqlInitializationModeCondition.class)
|
||||
public class SqlInitializationAutoConfiguration {
|
||||
|
||||
static class SqlInitializationModeCondition extends NoneNestedConditions {
|
||||
|
||||
SqlInitializationModeCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "spring.sql.init", name = "mode", havingValue = "never")
|
||||
static class ModeIsNever {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import java.nio.charset.Charset;
|
|||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties Configuration properties} for initializing an SQL
|
||||
|
|
@ -74,6 +75,11 @@ public class SqlInitializationProperties {
|
|||
*/
|
||||
private Charset encoding;
|
||||
|
||||
/**
|
||||
* Mode to apply when determining whether initialization should be performed.
|
||||
*/
|
||||
private DatabaseInitializationMode mode = DatabaseInitializationMode.EMBEDDED;
|
||||
|
||||
public List<String> getSchemaLocations() {
|
||||
return this.schemaLocations;
|
||||
}
|
||||
|
|
@ -138,4 +144,12 @@ public class SqlInitializationProperties {
|
|||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public DatabaseInitializationMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public void setMode(DatabaseInitializationMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1746,7 +1746,11 @@
|
|||
"name": "spring.sql.init.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether basic script-based initialization of an SQL database is enabled.",
|
||||
"defaultValue": true
|
||||
"defaultValue": true,
|
||||
"deprecation": {
|
||||
"replacement": "spring.sql.init.mode",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.thymeleaf.prefix",
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ class HikariDriverConfigurationFailureAnalyzerTests {
|
|||
private BeanCreationException createFailure(Class<?> configuration) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.datasource.hikari.data-source-class-name=com.example.Foo").applyTo(context);
|
||||
"spring.datasource.hikari.data-source-class-name=com.example.Foo", "spring.sql.init.mode=always")
|
||||
.applyTo(context);
|
||||
context.register(configuration);
|
||||
try {
|
||||
context.refresh();
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
|||
|
||||
@Test
|
||||
void testFlywaySwitchOffDdlAuto() {
|
||||
contextRunner().withPropertyValues("spring.sql.init.enabled:false", "spring.flyway.locations:classpath:db/city")
|
||||
contextRunner().withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city")
|
||||
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
|
||||
.run((context) -> assertThat(context).hasNotFailed());
|
||||
}
|
||||
|
|
@ -167,7 +167,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
|||
@Test
|
||||
void testFlywayPlusValidation() {
|
||||
contextRunner()
|
||||
.withPropertyValues("spring.sql.init.enabled:false", "spring.flyway.locations:classpath:db/city",
|
||||
.withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city",
|
||||
"spring.jpa.hibernate.ddl-auto:validate")
|
||||
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
|
||||
.run((context) -> assertThat(context).hasNotFailed());
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
|
|
@ -64,12 +66,21 @@ public class SqlInitializationAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void whenConnectionFactoryIsAvailableAndInitializationIsDisabledThenInitializerIsNotAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class))
|
||||
.withPropertyValues("spring.sql.init.enabled:false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenConnectionFactoryIsAvailableAndModeIsNeverThenInitializerIsNotAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class))
|
||||
.withInitializer(new ConditionEvaluationReportLoggingListener(LogLevel.INFO))
|
||||
.withPropertyValues("spring.sql.init.mode:never")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenDataSourceIsAvailableThenDataSourceInitializerIsAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
|
|
@ -77,12 +88,20 @@ public class SqlInitializationAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void whenDataSourceIsAvailableAndInitializationIsDisabledThenInitializerIsNotAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.sql.init.enabled:false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenDataSourceIsAvailableAndModeIsNeverThenThenInitializerIsNotAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.sql.init.mode:never")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenDataSourceAndConnectionFactoryAreAvailableThenOnlyR2dbcInitializerIsAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class))
|
||||
|
|
@ -135,6 +154,11 @@ public class SqlInitializationAutoConfigurationTests {
|
|||
// No-op
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEmbeddedDatabase() {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ It loads SQL from the standard root classpath locations: `schema.sql` and `data.
|
|||
In addition, Spring Boot processes the `schema-$\{platform}.sql` and `data-$\{platform}.sql` files (if present), where `platform` is the value of configprop:spring.sql.init.platform[].
|
||||
This allows you to switch to database-specific scripts if necessary.
|
||||
For example, you might choose to set it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`, `postgresql`, and so on).
|
||||
SQL database initialization can be disabled by setting configprop:spring.sql.init.enabled[] to `false`.
|
||||
By default, SQL database initialization is only performed when using an embedded in-memory database.
|
||||
To always initialize an SQL database, irrespective of its type, set configprop:spring.sql.init.mode[] to `always`.
|
||||
Similarly, to disable initialization, set configprop:spring.sql.init.mode[] to `never`.
|
||||
By default, Spring Boot enables the fail-fast feature of its script-based database initializer.
|
||||
This means that, if the scripts cause exceptions, the application fails to start.
|
||||
You can tune that behavior by setting configprop:spring.sql.init.continue-on-error[].
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
|
@ -58,6 +59,11 @@ public class DataSourceScriptDatabaseInitializer extends AbstractScriptDatabaseI
|
|||
return this.dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEmbeddedDatabase() {
|
||||
return EmbeddedDatabaseConnection.isEmbedded(this.dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runScripts(List<Resource> resources, boolean continueOnError, String separator, Charset encoding) {
|
||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import io.r2dbc.spi.ConnectionFactory;
|
|||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions.Builder;
|
||||
import io.r2dbc.spi.ValidationDepth;
|
||||
import io.r2dbc.spi.Wrapped;
|
||||
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -104,14 +103,9 @@ public final class ConnectionFactoryBuilder {
|
|||
}
|
||||
|
||||
private static ConnectionFactoryOptions extractOptionsIfPossible(ConnectionFactory connectionFactory) {
|
||||
if (connectionFactory instanceof OptionsCapableConnectionFactory) {
|
||||
return ((OptionsCapableConnectionFactory) connectionFactory).getOptions();
|
||||
}
|
||||
if (connectionFactory instanceof Wrapped) {
|
||||
Object unwrapped = ((Wrapped<?>) connectionFactory).unwrap();
|
||||
if (unwrapped instanceof ConnectionFactory) {
|
||||
return extractOptionsIfPossible((ConnectionFactory) unwrapped);
|
||||
}
|
||||
OptionsCapableConnectionFactory optionsCapable = OptionsCapableConnectionFactory.unwrapFrom(connectionFactory);
|
||||
if (optionsCapable != null) {
|
||||
return optionsCapable.getOptions();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@
|
|||
|
||||
package org.springframework.boot.r2dbc;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactory;
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
|
@ -31,21 +36,25 @@ public enum EmbeddedDatabaseConnection {
|
|||
/**
|
||||
* No Connection.
|
||||
*/
|
||||
NONE(null, null),
|
||||
NONE(null, null, (options) -> false),
|
||||
|
||||
/**
|
||||
* H2 Database Connection.
|
||||
*/
|
||||
H2("io.r2dbc.h2.H2ConnectionFactoryProvider",
|
||||
"r2dbc:h2:mem:///%s?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
|
||||
H2("io.r2dbc.h2.H2ConnectionFactoryProvider", "r2dbc:h2:mem:///%s?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE",
|
||||
(options) -> options.getValue(ConnectionFactoryOptions.DRIVER).equals("h2")
|
||||
&& options.getValue(ConnectionFactoryOptions.PROTOCOL).equals("mem"));
|
||||
|
||||
private final String driverClassName;
|
||||
|
||||
private final String url;
|
||||
|
||||
EmbeddedDatabaseConnection(String driverClassName, String url) {
|
||||
private Predicate<ConnectionFactoryOptions> embedded;
|
||||
|
||||
EmbeddedDatabaseConnection(String driverClassName, String url, Predicate<ConnectionFactoryOptions> embedded) {
|
||||
this.driverClassName = driverClassName;
|
||||
this.url = url;
|
||||
this.embedded = embedded;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -81,4 +90,27 @@ public enum EmbeddedDatabaseConnection {
|
|||
return NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to determine if a given connection factory represents an
|
||||
* embedded database type.
|
||||
* @param connectionFactory the connection factory to interrogate
|
||||
* @return true if the connection factory represents an embedded database
|
||||
* @since 2.5.1
|
||||
*/
|
||||
public static boolean isEmbedded(ConnectionFactory connectionFactory) {
|
||||
OptionsCapableConnectionFactory optionsCapable = OptionsCapableConnectionFactory.unwrapFrom(connectionFactory);
|
||||
if (optionsCapable == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot determine database's type as ConnectionFactory is not options-capable");
|
||||
}
|
||||
ConnectionFactoryOptions options = optionsCapable.getOptions();
|
||||
for (EmbeddedDatabaseConnection candidate : values()) {
|
||||
if (candidate.embedded.test(options)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,4 +67,28 @@ public class OptionsCapableConnectionFactory implements Wrapped<ConnectionFactor
|
|||
return this.delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns, if possible, an {@code OptionsCapableConnectionFactory} by unwrapping the
|
||||
* given {@code connectionFactory} as necessary. If the given
|
||||
* {@code connectionFactory} does not wrap an {@code OptionsCapableConnectionFactory}
|
||||
* and is not itself an {@code OptionsCapableConnectionFactory}, {@code null} is
|
||||
* returned.
|
||||
* @param connectionFactory the connection factory to unwrap
|
||||
* @return the {@code OptionsCapableConnectionFactory} or {@code null}
|
||||
* @since 2.5.1
|
||||
*/
|
||||
public static OptionsCapableConnectionFactory unwrapFrom(ConnectionFactory connectionFactory) {
|
||||
if (connectionFactory instanceof OptionsCapableConnectionFactory) {
|
||||
return (OptionsCapableConnectionFactory) connectionFactory;
|
||||
}
|
||||
if (connectionFactory instanceof Wrapped) {
|
||||
Object unwrapped = ((Wrapped<?>) connectionFactory).unwrap();
|
||||
if (unwrapped instanceof ConnectionFactory) {
|
||||
return unwrapFrom((ConnectionFactory) unwrapped);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
import io.r2dbc.spi.ConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.r2dbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
|
@ -51,6 +52,11 @@ public class R2dbcScriptDatabaseInitializer extends AbstractScriptDatabaseInitia
|
|||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEmbeddedDatabase() {
|
||||
return EmbeddedDatabaseConnection.isEmbedded(this.connectionFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runScripts(List<Resource> scripts, boolean continueOnError, String separator, Charset encoding) {
|
||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||
|
|
|
|||
|
|
@ -71,10 +71,30 @@ public abstract class AbstractScriptDatabaseInitializer implements ResourceLoade
|
|||
* {@code false}
|
||||
*/
|
||||
public boolean initializeDatabase() {
|
||||
ScriptLocationResolver locationResolver = new ScriptLocationResolver(this.resourceLoader);
|
||||
boolean initialized = applySchemaScripts(locationResolver);
|
||||
initialized = applyDataScripts(locationResolver) || initialized;
|
||||
return initialized;
|
||||
if (isEnabled()) {
|
||||
ScriptLocationResolver locationResolver = new ScriptLocationResolver(this.resourceLoader);
|
||||
boolean initialized = applySchemaScripts(locationResolver);
|
||||
initialized = applyDataScripts(locationResolver) || initialized;
|
||||
return initialized;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
if (this.settings.getMode() == DatabaseInitializationMode.NEVER) {
|
||||
return false;
|
||||
}
|
||||
return this.settings.getMode() == DatabaseInitializationMode.ALWAYS || isEmbeddedDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the database that is to be initialized is embedded.
|
||||
* @return {@code true} if the database is embedded, otherwise {@code false}
|
||||
* @since 2.5.1
|
||||
*/
|
||||
protected boolean isEmbeddedDatabase() {
|
||||
throw new IllegalStateException(
|
||||
"Database initialization mode is '" + this.settings.getMode() + "' and database type is unknown");
|
||||
}
|
||||
|
||||
private boolean applySchemaScripts(ScriptLocationResolver locationResolver) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.sql.init;
|
||||
|
||||
/**
|
||||
* Supported database initialization modes.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.5.1
|
||||
* @see AbstractScriptDatabaseInitializer
|
||||
*/
|
||||
public enum DatabaseInitializationMode {
|
||||
|
||||
/**
|
||||
* Always initialize the database.
|
||||
*/
|
||||
ALWAYS,
|
||||
|
||||
/**
|
||||
* Only initialize an embedded database.
|
||||
*/
|
||||
EMBEDDED,
|
||||
|
||||
/**
|
||||
* Never initialize the database.
|
||||
*/
|
||||
NEVER
|
||||
|
||||
}
|
||||
|
|
@ -37,6 +37,8 @@ public class DatabaseInitializationSettings {
|
|||
|
||||
private Charset encoding;
|
||||
|
||||
private DatabaseInitializationMode mode = DatabaseInitializationMode.EMBEDDED;
|
||||
|
||||
/**
|
||||
* Returns the locations of the schema (DDL) scripts to apply to the database.
|
||||
* @return the locations of the schema scripts
|
||||
|
|
@ -123,4 +125,24 @@ public class DatabaseInitializationSettings {
|
|||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mode to use when determining whether database initialization should be
|
||||
* performed.
|
||||
* @return the initialization mode
|
||||
* @since 2.5.1
|
||||
*/
|
||||
public DatabaseInitializationMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mode the use when determining whether database initialization should be
|
||||
* performed.
|
||||
* @param mode the initialization mode
|
||||
* @since 2.5.1
|
||||
*/
|
||||
public void setMode(DatabaseInitializationMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.springframework.boot.jdbc.init;
|
|||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
|
|
@ -25,6 +27,7 @@ import org.springframework.boot.jdbc.DataSourceBuilder;
|
|||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializerTests;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
/**
|
||||
|
|
@ -34,22 +37,44 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||
*/
|
||||
class DataSourceScriptDatabaseInitializerTests extends AbstractScriptDatabaseInitializerTests {
|
||||
|
||||
private final HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class)
|
||||
private final HikariDataSource embeddedDataSource = DataSourceBuilder.create().type(HikariDataSource.class)
|
||||
.url("jdbc:h2:mem:" + UUID.randomUUID()).build();
|
||||
|
||||
private final HikariDataSource standloneDataSource = DataSourceBuilder.create().type(HikariDataSource.class)
|
||||
.url("jdbc:h2:file:" + new BuildOutput(DataSourceScriptDatabaseInitializerTests.class).getRootLocation()
|
||||
.getAbsolutePath() + "/" + UUID.randomUUID())
|
||||
.build();
|
||||
|
||||
@AfterEach
|
||||
void closeDataSource() {
|
||||
this.dataSource.close();
|
||||
this.embeddedDataSource.close();
|
||||
this.standloneDataSource.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractScriptDatabaseInitializer createInitializer(DatabaseInitializationSettings settings) {
|
||||
return new DataSourceScriptDatabaseInitializer(this.dataSource, settings);
|
||||
protected AbstractScriptDatabaseInitializer createEmbeddedDatabaseInitializer(
|
||||
DatabaseInitializationSettings settings) {
|
||||
return new DataSourceScriptDatabaseInitializer(this.embeddedDataSource, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int numberOfRows(String sql) {
|
||||
return new JdbcTemplate(this.dataSource).queryForObject(sql, Integer.class);
|
||||
protected AbstractScriptDatabaseInitializer createStandaloneDatabaseInitializer(
|
||||
DatabaseInitializationSettings settings) {
|
||||
return new DataSourceScriptDatabaseInitializer(this.standloneDataSource, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int numberOfEmbeddedRows(String sql) {
|
||||
return numberOfRows(this.embeddedDataSource, sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int numberOfStandaloneRows(String sql) {
|
||||
return numberOfRows(this.standloneDataSource, sql);
|
||||
}
|
||||
|
||||
private int numberOfRows(DataSource dataSource, String sql) {
|
||||
return new JdbcTemplate(dataSource).queryForObject(sql, Integer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,23 @@ package org.springframework.boot.r2dbc;
|
|||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactories;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link EmbeddedDatabaseConnection}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class EmbeddedDatabaseConnectionTests {
|
||||
|
||||
|
|
@ -53,6 +57,41 @@ class EmbeddedDatabaseConnectionTests {
|
|||
.isEqualTo(EmbeddedDatabaseConnection.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenH2IsInMemoryThenIsEmbeddedReturnsTrue() {
|
||||
assertThat(EmbeddedDatabaseConnection
|
||||
.isEmbedded(ConnectionFactoryBuilder.withUrl("r2dbc:h2:mem:///" + UUID.randomUUID()).build())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenH2IsUsingFileStorageThenIsEmbeddedReturnsFalse() {
|
||||
assertThat(EmbeddedDatabaseConnection
|
||||
.isEmbedded(ConnectionFactoryBuilder.withUrl("r2dbc:h2:file:///" + UUID.randomUUID()).build()))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPoolIsBasedByH2InMemoryThenIsEmbeddedReturnsTrue() {
|
||||
assertThat(EmbeddedDatabaseConnection
|
||||
.isEmbedded(ConnectionFactoryBuilder.withUrl("r2dbc:pool:h2:mem:///" + UUID.randomUUID()).build()))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPoolIsBasedByH2WithFileStorageThenIsEmbeddedReturnsFalse() {
|
||||
assertThat(EmbeddedDatabaseConnection
|
||||
.isEmbedded(ConnectionFactoryBuilder.withUrl("r2dbc:pool:h2:file:///" + UUID.randomUUID()).build()))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenConnectionFactoryIsNotOptionsCapableThenIsEmbeddedThrows() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> EmbeddedDatabaseConnection
|
||||
.isEmbedded(ConnectionFactories.get("r2dbc:pool:h2:mem:///" + UUID.randomUUID())))
|
||||
.withMessage("Cannot determine database's type as ConnectionFactory is not options-capable");
|
||||
}
|
||||
|
||||
static Stream<Arguments> urlParameters() {
|
||||
return Stream.of(Arguments.arguments(EmbeddedDatabaseConnection.NONE, null),
|
||||
Arguments.arguments(EmbeddedDatabaseConnection.H2,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import org.springframework.boot.r2dbc.ConnectionFactoryBuilder;
|
|||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializerTests;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
|
||||
/**
|
||||
|
|
@ -33,18 +34,38 @@ import org.springframework.r2dbc.core.DatabaseClient;
|
|||
*/
|
||||
class R2dbcScriptDatabaseInitializerTests extends AbstractScriptDatabaseInitializerTests {
|
||||
|
||||
private final ConnectionFactory connectionFactory = ConnectionFactoryBuilder
|
||||
private final ConnectionFactory embeddedConnectionFactory = ConnectionFactoryBuilder
|
||||
.withUrl("r2dbc:h2:mem:///" + UUID.randomUUID() + "?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE")
|
||||
.build();
|
||||
|
||||
private final ConnectionFactory standaloneConnectionFactory = ConnectionFactoryBuilder.withUrl("r2dbc:h2:file:///"
|
||||
+ new BuildOutput(R2dbcScriptDatabaseInitializerTests.class).getRootLocation().getAbsolutePath() + "/"
|
||||
+ UUID.randomUUID() + "?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE").build();
|
||||
|
||||
@Override
|
||||
protected AbstractScriptDatabaseInitializer createInitializer(DatabaseInitializationSettings settings) {
|
||||
return new R2dbcScriptDatabaseInitializer(this.connectionFactory, settings);
|
||||
protected AbstractScriptDatabaseInitializer createEmbeddedDatabaseInitializer(
|
||||
DatabaseInitializationSettings settings) {
|
||||
return new R2dbcScriptDatabaseInitializer(this.embeddedConnectionFactory, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int numberOfRows(String sql) {
|
||||
return DatabaseClient.create(this.connectionFactory).sql(sql).map((row, metadata) -> row.get(0)).first()
|
||||
protected AbstractScriptDatabaseInitializer createStandaloneDatabaseInitializer(
|
||||
DatabaseInitializationSettings settings) {
|
||||
return new R2dbcScriptDatabaseInitializer(this.standaloneConnectionFactory, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int numberOfEmbeddedRows(String sql) {
|
||||
return numberOfRows(this.embeddedConnectionFactory, sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int numberOfStandaloneRows(String sql) {
|
||||
return numberOfRows(this.standaloneConnectionFactory, sql);
|
||||
}
|
||||
|
||||
private int numberOfRows(ConnectionFactory connectionFactory, String sql) {
|
||||
return DatabaseClient.create(connectionFactory).sql(sql).map((row, metadata) -> row.get(0)).first()
|
||||
.map((number) -> ((Number) number).intValue()).block();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,16 +38,16 @@ public abstract class AbstractScriptDatabaseInitializerTests {
|
|||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isTrue();
|
||||
assertThat(numberOfRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1);
|
||||
assertThat(numberOfEmbeddedRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenContinueOnErrorIsFalseThenInitializationFailsOnError() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThatExceptionOfType(DataAccessException.class).isThrownBy(() -> initializer.initializeDatabase());
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ public abstract class AbstractScriptDatabaseInitializerTests {
|
|||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setContinueOnError(true);
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isTrue();
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ public abstract class AbstractScriptDatabaseInitializerTests {
|
|||
void whenNoScriptsExistAtASchemaLocationThenInitializationFails() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("does-not-exist.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThatIllegalStateException().isThrownBy(initializer::initializeDatabase)
|
||||
.withMessage("No schema scripts found at location 'does-not-exist.sql'");
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ public abstract class AbstractScriptDatabaseInitializerTests {
|
|||
void whenNoScriptsExistAtADataLocationThenInitializationFails() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setDataLocations(Arrays.asList("does-not-exist.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThatIllegalStateException().isThrownBy(initializer::initializeDatabase)
|
||||
.withMessage("No data scripts found at location 'does-not-exist.sql'");
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ public abstract class AbstractScriptDatabaseInitializerTests {
|
|||
void whenNoScriptsExistAtAnOptionalSchemaLocationThenInitializationSucceeds() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("optional:does-not-exist.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isFalse();
|
||||
}
|
||||
|
||||
|
|
@ -90,12 +90,81 @@ public abstract class AbstractScriptDatabaseInitializerTests {
|
|||
void whenNoScriptsExistAtAnOptionalDataLocationThenInitializationSucceeds() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setDataLocations(Arrays.asList("optional:does-not-exist.sql"));
|
||||
AbstractScriptDatabaseInitializer initializer = createInitializer(settings);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isFalse();
|
||||
}
|
||||
|
||||
protected abstract AbstractScriptDatabaseInitializer createInitializer(DatabaseInitializationSettings settings);
|
||||
@Test
|
||||
void whenModeIsNeverThenEmbeddedDatabaseIsNotInitialized() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
settings.setMode(DatabaseInitializationMode.NEVER);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isFalse();
|
||||
}
|
||||
|
||||
protected abstract int numberOfRows(String sql);
|
||||
@Test
|
||||
void whenModeIsNeverThenStandaloneDatabaseIsNotInitialized() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
settings.setMode(DatabaseInitializationMode.NEVER);
|
||||
AbstractScriptDatabaseInitializer initializer = createStandaloneDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenModeIsEmbeddedThenEmbeddedDatabaseIsInitialized() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
settings.setMode(DatabaseInitializationMode.EMBEDDED);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isTrue();
|
||||
assertThat(numberOfEmbeddedRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenModeIsEmbeddedThenStandaloneDatabaseIsNotInitialized() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
settings.setMode(DatabaseInitializationMode.EMBEDDED);
|
||||
AbstractScriptDatabaseInitializer initializer = createStandaloneDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenModeIsAlwaysThenEmbeddedDatabaseIsInitialized() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
settings.setMode(DatabaseInitializationMode.ALWAYS);
|
||||
AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isTrue();
|
||||
assertThat(numberOfEmbeddedRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenModeIsAlwaysThenStandaloneDatabaseIsInitialized() {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(Arrays.asList("schema.sql"));
|
||||
settings.setDataLocations(Arrays.asList("data.sql"));
|
||||
settings.setMode(DatabaseInitializationMode.ALWAYS);
|
||||
AbstractScriptDatabaseInitializer initializer = createStandaloneDatabaseInitializer(settings);
|
||||
assertThat(initializer.initializeDatabase()).isTrue();
|
||||
assertThat(numberOfStandaloneRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1);
|
||||
}
|
||||
|
||||
protected abstract AbstractScriptDatabaseInitializer createStandaloneDatabaseInitializer(
|
||||
DatabaseInitializationSettings settings);
|
||||
|
||||
protected abstract AbstractScriptDatabaseInitializer createEmbeddedDatabaseInitializer(
|
||||
DatabaseInitializationSettings settings);
|
||||
|
||||
protected abstract int numberOfEmbeddedRows(String sql);
|
||||
|
||||
protected abstract int numberOfStandaloneRows(String sql);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue