diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java index e170acc3c4..4ab0661905 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java @@ -71,13 +71,9 @@ public abstract class AbstractScriptDatabaseInitializer implements ResourceLoade * {@code false} */ public boolean initializeDatabase() { - if (isEnabled()) { - ScriptLocationResolver locationResolver = new ScriptLocationResolver(this.resourceLoader); - boolean initialized = applySchemaScripts(locationResolver); - initialized = applyDataScripts(locationResolver) || initialized; - return initialized; - } - return false; + ScriptLocationResolver locationResolver = new ScriptLocationResolver(this.resourceLoader); + boolean initialized = applySchemaScripts(locationResolver); + return applyDataScripts(locationResolver) || initialized; } private boolean isEnabled() { @@ -107,10 +103,11 @@ public abstract class AbstractScriptDatabaseInitializer implements ResourceLoade private boolean applyScripts(List locations, String type, ScriptLocationResolver locationResolver) { List scripts = getScripts(locations, type, locationResolver); - if (!scripts.isEmpty()) { + if (!scripts.isEmpty() && isEnabled()) { runScripts(scripts); + return true; } - return !scripts.isEmpty(); + return false; } private List getScripts(List locations, String type, ScriptLocationResolver locationResolver) { @@ -145,9 +142,6 @@ public abstract class AbstractScriptDatabaseInitializer implements ResourceLoade } private void runScripts(List resources) { - if (resources.isEmpty()) { - return; - } runScripts(resources, this.settings.isContinueOnError(), this.settings.getSeparator(), this.settings.getEncoding()); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java index 428f031c65..46a24b1316 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java @@ -24,18 +24,20 @@ import com.zaxxer.hikari.HikariDataSource; import org.junit.jupiter.api.AfterEach; 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; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests for {@link DataSourceScriptDatabaseInitializer}. * * @author Andy Wilkinson */ -class DataSourceScriptDatabaseInitializerTests extends AbstractScriptDatabaseInitializerTests { +class DataSourceScriptDatabaseInitializerTests + extends AbstractScriptDatabaseInitializerTests { private final HikariDataSource embeddedDataSource = DataSourceBuilder.create().type(HikariDataSource.class) .url("jdbc:h2:mem:" + UUID.randomUUID()).build(); @@ -52,13 +54,13 @@ class DataSourceScriptDatabaseInitializerTests extends AbstractScriptDatabaseIni } @Override - protected AbstractScriptDatabaseInitializer createEmbeddedDatabaseInitializer( + protected DataSourceScriptDatabaseInitializer createEmbeddedDatabaseInitializer( DatabaseInitializationSettings settings) { return new DataSourceScriptDatabaseInitializer(this.embeddedDataSource, settings); } @Override - protected AbstractScriptDatabaseInitializer createStandaloneDatabaseInitializer( + protected DataSourceScriptDatabaseInitializer createStandaloneDatabaseInitializer( DatabaseInitializationSettings settings) { return new DataSourceScriptDatabaseInitializer(this.standloneDataSource, settings); } @@ -77,4 +79,9 @@ class DataSourceScriptDatabaseInitializerTests extends AbstractScriptDatabaseIni return new JdbcTemplate(dataSource).queryForObject(sql, Integer.class); } + @Override + protected void assertDatabaseAccessed(boolean accessed, DataSourceScriptDatabaseInitializer initializer) { + assertThat(((HikariDataSource) initializer.getDataSource()).isRunning()).isEqualTo(accessed); + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java index 4e4c3e0342..2baa9b00e3 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java @@ -21,7 +21,6 @@ import java.util.UUID; import io.r2dbc.spi.ConnectionFactory; 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; @@ -32,7 +31,8 @@ import org.springframework.r2dbc.core.DatabaseClient; * * @author Andy Wilkinson */ -class R2dbcScriptDatabaseInitializerTests extends AbstractScriptDatabaseInitializerTests { +class R2dbcScriptDatabaseInitializerTests + extends AbstractScriptDatabaseInitializerTests { private final ConnectionFactory embeddedConnectionFactory = ConnectionFactoryBuilder .withUrl("r2dbc:h2:mem:///" + UUID.randomUUID() + "?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE") @@ -43,13 +43,13 @@ class R2dbcScriptDatabaseInitializerTests extends AbstractScriptDatabaseInitiali + UUID.randomUUID() + "?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE").build(); @Override - protected AbstractScriptDatabaseInitializer createEmbeddedDatabaseInitializer( + protected R2dbcScriptDatabaseInitializer createEmbeddedDatabaseInitializer( DatabaseInitializationSettings settings) { return new R2dbcScriptDatabaseInitializer(this.embeddedConnectionFactory, settings); } @Override - protected AbstractScriptDatabaseInitializer createStandaloneDatabaseInitializer( + protected R2dbcScriptDatabaseInitializer createStandaloneDatabaseInitializer( DatabaseInitializationSettings settings) { return new R2dbcScriptDatabaseInitializer(this.standaloneConnectionFactory, settings); } @@ -69,4 +69,9 @@ class R2dbcScriptDatabaseInitializerTests extends AbstractScriptDatabaseInitiali .map((number) -> ((Number) number).intValue()).block(); } + @Override + protected void assertDatabaseAccessed(boolean accessed, R2dbcScriptDatabaseInitializer initializer) { + // No-op as R2DBC does not need to access the database to determine its type + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java index 664ba215b8..a3854f440a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java @@ -29,16 +29,17 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; /** * Base class for testing {@link AbstractScriptDatabaseInitializer} implementations. * + * @param type of the initializer being tested * @author Andy Wilkinson */ -public abstract class AbstractScriptDatabaseInitializerTests { +public abstract class AbstractScriptDatabaseInitializerTests { @Test void whenDatabaseIsInitializedThenSchemaAndDataScriptsAreApplied() { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isTrue(); assertThat(numberOfEmbeddedRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1); } @@ -47,8 +48,9 @@ public abstract class AbstractScriptDatabaseInitializerTests { void whenContinueOnErrorIsFalseThenInitializationFailsOnError() { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setDataLocations(Arrays.asList("data.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThatExceptionOfType(DataAccessException.class).isThrownBy(() -> initializer.initializeDatabase()); + assertThatDatabaseWasAccessed(initializer); } @Test @@ -56,42 +58,47 @@ public abstract class AbstractScriptDatabaseInitializerTests { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setContinueOnError(true); settings.setDataLocations(Arrays.asList("data.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isTrue(); + assertThatDatabaseWasAccessed(initializer); } @Test void whenNoScriptsExistAtASchemaLocationThenInitializationFails() { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setSchemaLocations(Arrays.asList("does-not-exist.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThatIllegalStateException().isThrownBy(initializer::initializeDatabase) .withMessage("No schema scripts found at location 'does-not-exist.sql'"); + assertThatDatabaseWasNotAccessed(initializer); } @Test void whenNoScriptsExistAtADataLocationThenInitializationFails() { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setDataLocations(Arrays.asList("does-not-exist.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThatIllegalStateException().isThrownBy(initializer::initializeDatabase) .withMessage("No data scripts found at location 'does-not-exist.sql'"); + assertThatDatabaseWasNotAccessed(initializer); } @Test - void whenNoScriptsExistAtAnOptionalSchemaLocationThenInitializationSucceeds() { + void whenNoScriptsExistAtAnOptionalSchemaLocationThenDatabaseIsNotAccessed() { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setSchemaLocations(Arrays.asList("optional:does-not-exist.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isFalse(); + assertThatDatabaseWasNotAccessed(initializer); } @Test - void whenNoScriptsExistAtAnOptionalDataLocationThenInitializationSucceeds() { + void whenNoScriptsExistAtAnOptionalDataLocationThenDatabaseIsNotAccessed() { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); settings.setDataLocations(Arrays.asList("optional:does-not-exist.sql")); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isFalse(); + assertThatDatabaseWasNotAccessed(initializer); } @Test @@ -100,8 +107,9 @@ public abstract class AbstractScriptDatabaseInitializerTests { settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); settings.setMode(DatabaseInitializationMode.NEVER); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isFalse(); + assertThatDatabaseWasNotAccessed(initializer); } @Test @@ -110,8 +118,9 @@ public abstract class AbstractScriptDatabaseInitializerTests { settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); settings.setMode(DatabaseInitializationMode.NEVER); - AbstractScriptDatabaseInitializer initializer = createStandaloneDatabaseInitializer(settings); + T initializer = createStandaloneDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isFalse(); + assertThatDatabaseWasNotAccessed(initializer); } @Test @@ -120,7 +129,7 @@ public abstract class AbstractScriptDatabaseInitializerTests { settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); settings.setMode(DatabaseInitializationMode.EMBEDDED); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isTrue(); assertThat(numberOfEmbeddedRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1); } @@ -131,8 +140,9 @@ public abstract class AbstractScriptDatabaseInitializerTests { settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); settings.setMode(DatabaseInitializationMode.EMBEDDED); - AbstractScriptDatabaseInitializer initializer = createStandaloneDatabaseInitializer(settings); + T initializer = createStandaloneDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isFalse(); + assertThatDatabaseWasAccessed(initializer); } @Test @@ -141,7 +151,7 @@ public abstract class AbstractScriptDatabaseInitializerTests { settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); settings.setMode(DatabaseInitializationMode.ALWAYS); - AbstractScriptDatabaseInitializer initializer = createEmbeddedDatabaseInitializer(settings); + T initializer = createEmbeddedDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isTrue(); assertThat(numberOfEmbeddedRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1); } @@ -152,19 +162,27 @@ public abstract class AbstractScriptDatabaseInitializerTests { settings.setSchemaLocations(Arrays.asList("schema.sql")); settings.setDataLocations(Arrays.asList("data.sql")); settings.setMode(DatabaseInitializationMode.ALWAYS); - AbstractScriptDatabaseInitializer initializer = createStandaloneDatabaseInitializer(settings); + T initializer = createStandaloneDatabaseInitializer(settings); assertThat(initializer.initializeDatabase()).isTrue(); assertThat(numberOfStandaloneRows("SELECT COUNT(*) FROM EXAMPLE")).isEqualTo(1); } - protected abstract AbstractScriptDatabaseInitializer createStandaloneDatabaseInitializer( - DatabaseInitializationSettings settings); + protected abstract T createStandaloneDatabaseInitializer(DatabaseInitializationSettings settings); - protected abstract AbstractScriptDatabaseInitializer createEmbeddedDatabaseInitializer( - DatabaseInitializationSettings settings); + protected abstract T createEmbeddedDatabaseInitializer(DatabaseInitializationSettings settings); protected abstract int numberOfEmbeddedRows(String sql); protected abstract int numberOfStandaloneRows(String sql); + private void assertThatDatabaseWasAccessed(T initializer) { + assertDatabaseAccessed(true, initializer); + } + + private void assertThatDatabaseWasNotAccessed(T initializer) { + assertDatabaseAccessed(false, initializer); + } + + protected abstract void assertDatabaseAccessed(boolean accessed, T initializer); + }