diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java index e9bff2fb6238..27cd382507e7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializer.java @@ -22,6 +22,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationMode; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Initialize the Spring Batch schema (ignoring errors, so it should be idempotent). @@ -65,6 +66,10 @@ protected String getSchemaLocation() { @Override protected String getDatabaseName() { + String platform = this.jdbcProperties.getPlatform(); + if (StringUtils.hasText(platform)) { + return platform; + } String databaseName = super.getDatabaseName(); if ("oracle".equals(databaseName)) { return "oracle10g"; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java index dbd4b1ad53ad..8e10b3c663aa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java @@ -16,12 +16,15 @@ package org.springframework.boot.autoconfigure.batch; +import java.util.List; + import javax.sql.DataSource; import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver; import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.util.StringUtils; /** * {@link DataSourceScriptDatabaseInitializer} for the Spring Batch database. May be @@ -67,13 +70,20 @@ public BatchDataSourceScriptDatabaseInitializer(DataSource dataSource, DatabaseI */ public static DatabaseInitializationSettings getSettings(DataSource dataSource, BatchProperties.Jdbc properties) { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); - PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); - platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.ORACLE, "oracle10g"); - platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql"); - settings.setSchemaLocations(platformResolver.resolveAll(dataSource, properties.getSchema())); + settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties)); settings.setMode(properties.getInitializeSchema()); settings.setContinueOnError(true); return settings; } + private static List resolveSchemaLocations(DataSource dataSource, BatchProperties.Jdbc properties) { + PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); + platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.ORACLE, "oracle10g"); + platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql"); + if (StringUtils.hasText(properties.getPlatform())) { + return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema()); + } + return platformResolver.resolveAll(dataSource, properties.getSchema()); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java index bad63c477704..2a5669306b06 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java @@ -122,6 +122,12 @@ public static class Jdbc { */ private String schema = DEFAULT_SCHEMA_LOCATION; + /** + * Platform to use in initialization scripts if the @@platform@@ placeholder is + * used. Auto-detected by default. + */ + private String platform; + /** * Table prefix for all the batch meta-data tables. */ @@ -140,6 +146,14 @@ public void setSchema(String schema) { this.schema = schema; } + public String getPlatform() { + return this.platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + public String getTablePrefix() { return this.tablePrefix; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializer.java index 24d5356ce0b0..7f2663d13917 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializer.java @@ -21,6 +21,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationMode; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Initializer for Spring Integration schema. @@ -61,4 +62,13 @@ protected String getSchemaLocation() { return this.properties.getSchema(); } + @Override + protected String getDatabaseName() { + String platform = this.properties.getPlatform(); + if (StringUtils.hasText(platform)) { + return platform; + } + return super.getDatabaseName(); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java index 2b15c6b3e8a6..281d233fcb4a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java @@ -16,11 +16,14 @@ package org.springframework.boot.autoconfigure.integration; +import java.util.List; + import javax.sql.DataSource; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver; import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.util.StringUtils; /** * {@link DataSourceScriptDatabaseInitializer} for the Spring Integration database. May be @@ -66,11 +69,18 @@ public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource, */ static DatabaseInitializationSettings getSettings(DataSource dataSource, IntegrationProperties.Jdbc properties) { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); - PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); - settings.setSchemaLocations(platformResolver.resolveAll(dataSource, properties.getSchema())); + settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties)); settings.setMode(properties.getInitializeSchema()); settings.setContinueOnError(true); return settings; } + private static List resolveSchemaLocations(DataSource dataSource, IntegrationProperties.Jdbc properties) { + PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); + if (StringUtils.hasText(properties.getPlatform())) { + return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema()); + } + return platformResolver.resolveAll(dataSource, properties.getSchema()); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java index 22b1bf6142b1..65ace115b14c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java @@ -209,6 +209,12 @@ public static class Jdbc { */ private String schema = DEFAULT_SCHEMA_LOCATION; + /** + * Platform to use in initialization scripts if the @@platform@@ placeholder is + * used. Auto-detected by default. + */ + private String platform; + /** * Database schema initialization mode. */ @@ -222,6 +228,14 @@ public void setSchema(String schema) { this.schema = schema; } + public String getPlatform() { + return this.platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + public DatabaseInitializationMode getInitializeSchema() { return this.initializeSchema; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializer.java index 55539c4d479d..512d5f181174 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializer.java @@ -22,6 +22,7 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Initialize the Quartz Scheduler schema. @@ -69,6 +70,10 @@ protected String getSchemaLocation() { @Override protected String getDatabaseName() { + String platform = this.properties.getJdbc().getPlatform(); + if (StringUtils.hasText(platform)) { + return platform; + } String databaseName = super.getDatabaseName(); if ("db2".equals(databaseName)) { return "db2_v95"; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java index b230fca1cb3d..8fca4af47573 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java @@ -16,12 +16,15 @@ package org.springframework.boot.autoconfigure.quartz; +import java.util.List; + import javax.sql.DataSource; import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver; import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.util.StringUtils; /** * {@link DataSourceScriptDatabaseInitializer} for the Quartz Scheduler database. May be @@ -66,16 +69,23 @@ public QuartzDataSourceScriptDatabaseInitializer(DataSource dataSource, Database */ public static DatabaseInitializationSettings getSettings(DataSource dataSource, QuartzProperties properties) { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); + settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties.getJdbc())); + settings.setMode(properties.getJdbc().getInitializeSchema()); + settings.setContinueOnError(true); + return settings; + } + + private static List resolveSchemaLocations(DataSource dataSource, QuartzProperties.Jdbc properties) { PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.DB2, "db2_v95"); platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MYSQL, "mysql_innodb"); platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql_innodb"); platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.POSTGRESQL, "postgres"); platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.SQLSERVER, "sqlServer"); - settings.setSchemaLocations(platformResolver.resolveAll(dataSource, properties.getJdbc().getSchema())); - settings.setMode(properties.getJdbc().getInitializeSchema()); - settings.setContinueOnError(true); - return settings; + if (StringUtils.hasText(properties.getPlatform())) { + return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema()); + } + return platformResolver.resolveAll(dataSource, properties.getSchema()); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java index 03da194afb78..cc2ebaf5e56b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java @@ -141,6 +141,12 @@ public static class Jdbc { */ private String schema = DEFAULT_SCHEMA_LOCATION; + /** + * Platform to use in initialization scripts if the @@platform@@ placeholder is + * used. Auto-detected by default. + */ + private String platform; + /** * Database schema initialization mode. */ @@ -159,6 +165,14 @@ public void setSchema(String schema) { this.schema = schema; } + public String getPlatform() { + return this.platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + public DatabaseInitializationMode getInitializeSchema() { return this.initializeSchema; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializer.java index 15078aaa56d6..f855c5263728 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializer.java @@ -21,6 +21,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationMode; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Initializer for Spring Session schema. @@ -61,4 +62,13 @@ protected String getSchemaLocation() { return this.properties.getSchema(); } + @Override + protected String getDatabaseName() { + String platform = this.properties.getPlatform(); + if (StringUtils.hasText(platform)) { + return platform; + } + return super.getDatabaseName(); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java index 851694049b50..64f1ec5e2fdb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java @@ -16,11 +16,14 @@ package org.springframework.boot.autoconfigure.session; +import java.util.List; + import javax.sql.DataSource; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver; import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.util.StringUtils; /** * {@link DataSourceScriptDatabaseInitializer} for the Spring Session JDBC database. May @@ -67,11 +70,18 @@ public JdbcSessionDataSourceScriptDatabaseInitializer(DataSource dataSource, */ static DatabaseInitializationSettings getSettings(DataSource dataSource, JdbcSessionProperties properties) { DatabaseInitializationSettings settings = new DatabaseInitializationSettings(); - PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); - settings.setSchemaLocations(platformResolver.resolveAll(dataSource, properties.getSchema())); + settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties)); settings.setMode(properties.getInitializeSchema()); settings.setContinueOnError(true); return settings; } + private static List resolveSchemaLocations(DataSource dataSource, JdbcSessionProperties properties) { + PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver(); + if (StringUtils.hasText(properties.getPlatform())) { + return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema()); + } + return platformResolver.resolveAll(dataSource, properties.getSchema()); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java index 3cde29abcd8b..80fedbdf1100 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java @@ -42,6 +42,12 @@ public class JdbcSessionProperties { */ private String schema = DEFAULT_SCHEMA_LOCATION; + /** + * Platform to use in initialization scripts if the @@platform@@ placeholder is used. + * Auto-detected by default. + */ + private String platform; + /** * Name of the database table used to store sessions. */ @@ -77,6 +83,14 @@ public void setSchema(String schema) { this.schema = schema; } + public String getPlatform() { + return this.platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + public String getTableName() { return this.tableName; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializerTests.java new file mode 100644 index 000000000000..88fabb00d159 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.batch; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.core.io.DefaultResourceLoader; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link BatchDataSourceInitializer}. + * + * @author Stephane Nicoll + */ +@Deprecated +class BatchDataSourceInitializerTests { + + @Test + void getDatabaseNameWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + BatchProperties properties = new BatchProperties(); + properties.getJdbc().setPlatform("test"); + BatchDataSourceInitializer initializer = new BatchDataSourceInitializer(dataSource, new DefaultResourceLoader(), + properties); + assertThat(initializer.getDatabaseName()).isEqualTo("test"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializerTests.java new file mode 100644 index 000000000000..d5c230d0d2c4 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.batch; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.sql.init.DatabaseInitializationSettings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link BatchDataSourceScriptDatabaseInitializer}. + * + * @author Stephane Nicoll + */ +class BatchDataSourceScriptDatabaseInitializerTests { + + @Test + void getSettingsWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + BatchProperties properties = new BatchProperties(); + properties.getJdbc().setPlatform("test"); + DatabaseInitializationSettings settings = BatchDataSourceScriptDatabaseInitializer.getSettings(dataSource, + properties.getJdbc()); + assertThat(settings.getSchemaLocations()) + .containsOnly("classpath:org/springframework/batch/core/schema-test.sql"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializerTests.java new file mode 100644 index 000000000000..c98814cf0026 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.integration; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.core.io.DefaultResourceLoader; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link IntegrationDataSourceInitializer}. + * + * @author Stephane Nicoll + */ +@Deprecated +class IntegrationDataSourceInitializerTests { + + @Test + void getDatabaseNameWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + IntegrationProperties properties = new IntegrationProperties(); + properties.getJdbc().setPlatform("test"); + IntegrationDataSourceInitializer initializer = new IntegrationDataSourceInitializer(dataSource, + new DefaultResourceLoader(), properties); + assertThat(initializer.getDatabaseName()).isEqualTo("test"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializerTests.java new file mode 100644 index 000000000000..6e6a719f86f2 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.integration; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.sql.init.DatabaseInitializationSettings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link IntegrationDataSourceScriptDatabaseInitializer}. + * + * @author Stephane Nicoll + */ +class IntegrationDataSourceScriptDatabaseInitializerTests { + + @Test + void getSettingsWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + IntegrationProperties properties = new IntegrationProperties(); + properties.getJdbc().setPlatform("test"); + DatabaseInitializationSettings settings = IntegrationDataSourceScriptDatabaseInitializer.getSettings(dataSource, + properties.getJdbc()); + assertThat(settings.getSchemaLocations()) + .containsOnly("classpath:org/springframework/integration/jdbc/schema-test.sql"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializerTests.java index 89cc60747460..488118cb926d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceInitializerTests.java @@ -30,10 +30,13 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.core.JdbcTemplate; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; /** * Tests for {@link QuartzDataSourceInitializer}. @@ -49,6 +52,17 @@ class QuartzDataSourceInitializerTests { .withPropertyValues("spring.datasource.url=" + String.format( "jdbc:h2:mem:test-%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", UUID.randomUUID().toString())); + @Test + void getDatabaseNameWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + QuartzProperties properties = new QuartzProperties(); + properties.getJdbc().setPlatform("test"); + QuartzDataSourceInitializer initializer = new QuartzDataSourceInitializer(dataSource, + new DefaultResourceLoader(), properties); + assertThat(initializer.getDatabaseName()).isEqualTo("test"); + verifyNoInteractions(dataSource); + } + @Test void hashIsUsedAsACommentPrefixByDefault() { this.contextRunner.withUserConfiguration(TestConfiguration.class).withPropertyValues( diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializerTests.java new file mode 100644 index 000000000000..16b2d56ff902 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.quartz; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.sql.init.DatabaseInitializationSettings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link QuartzDataSourceScriptDatabaseInitializer}. + * + * @author Stephane Nicoll + */ +class QuartzDataSourceScriptDatabaseInitializerTests { + + @Test + void getSettingsWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + QuartzProperties properties = new QuartzProperties(); + properties.getJdbc().setPlatform("test"); + DatabaseInitializationSettings settings = QuartzDataSourceScriptDatabaseInitializer.getSettings(dataSource, + properties); + assertThat(settings.getSchemaLocations()) + .containsOnly("classpath:org/quartz/impl/jdbcjobstore/tables_test.sql"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializerTests.java new file mode 100644 index 000000000000..0a7e0bf9b0c7 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.session; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.sql.init.DatabaseInitializationSettings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link JdbcSessionDataSourceScriptDatabaseInitializer}. + * + * @author Stephane Nicoll + */ +class JdbcSessionDataSourceScriptDatabaseInitializerTests { + + @Test + void getSettingsWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + JdbcSessionProperties properties = new JdbcSessionProperties(); + properties.setPlatform("test"); + DatabaseInitializationSettings settings = JdbcSessionDataSourceScriptDatabaseInitializer.getSettings(dataSource, + properties); + assertThat(settings.getSchemaLocations()) + .containsOnly("classpath:org/springframework/session/jdbc/schema-test.sql"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/kotlin/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/kotlin/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializerTests.java new file mode 100644 index 000000000000..886b960903c0 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/kotlin/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceInitializerTests.java @@ -0,0 +1,48 @@ +/* + * 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.autoconfigure.session; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.core.io.DefaultResourceLoader; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link JdbcSessionDataSourceInitializer}. + * + * @author Stephane Nicoll + */ +@Deprecated +class JdbcSessionDataSourceInitializerTests { + + @Test + void getDatabaseNameWithPlatformDoesNotTouchDataSource() { + DataSource dataSource = mock(DataSource.class); + JdbcSessionProperties properties = new JdbcSessionProperties(); + properties.setPlatform("test"); + JdbcSessionDataSourceInitializer initializer = new JdbcSessionDataSourceInitializer(dataSource, + new DefaultResourceLoader(), properties); + assertThat(initializer.getDatabaseName()).isEqualTo("test"); + verifyNoInteractions(dataSource); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java index 10e62713d2fa..67fb0edb1510 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java @@ -21,6 +21,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Supplier; import javax.sql.DataSource; @@ -92,6 +93,23 @@ public PlatformPlaceholderDatabaseDriverResolver withDriverPlatform(DatabaseDriv */ public List resolveAll(DataSource dataSource, String... values) { Assert.notNull(dataSource, "DataSource must not be null"); + return resolveAll(() -> determinePlatform(dataSource), values); + } + + /** + * Resolves the placeholders in the given {@code values}, replacing them with the + * given platform. + * @param platform the platform to use + * @param values the values in which placeholders are resolved + * @return the values with their placeholders resolved + * @since 2.6.2 + */ + public List resolveAll(String platform, String... values) { + Assert.notNull(platform, "Platform must not be null"); + return resolveAll(() -> platform, values); + } + + private List resolveAll(Supplier platformProvider, String... values) { if (ObjectUtils.isEmpty(values)) { return Collections.emptyList(); } @@ -100,7 +118,7 @@ public List resolveAll(DataSource dataSource, String... values) { for (String value : values) { if (StringUtils.hasLength(value)) { if (value.contains(this.placeholder)) { - platform = (platform != null) ? platform : determinePlatform(dataSource); + platform = (platform != null) ? platform : platformProvider.get(); value = value.replace(this.placeholder, platform); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java index 6dbe746b3b45..1dd057f814db 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java @@ -35,29 +35,50 @@ * Tests for {@link PlatformPlaceholderDatabaseDriverResolver} * * @author Andy Wilkinson + * @author Stephane Nicoll */ class PlatformPlaceholderDatabaseDriverResolverTests { @Test - void resolveAllWhenThereAreNoValuesShouldReturnEmptyList() { + void resolveAllWithPlatformWhenThereAreNoValuesShouldReturnEmptyList() { + assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll("test")).isEmpty(); + } + + @Test + void resolveAllWithPlatformWhenValueDoesNotContainPlaceholderShouldReturnValueUnchanged() { + assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll("test", "schema.sql")) + .containsExactly("schema.sql"); + } + + @Test + void resolveAllWithPlatformWhenValuesContainPlaceholdersShouldReturnValuesWithPlaceholdersReplaced() { + assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll("postgresql", "schema.sql", + "schema-@@platform@@.sql", "data-@@platform@@.sql")).containsExactly("schema.sql", + "schema-postgresql.sql", "data-postgresql.sql"); + } + + @Test + void resolveAllWithDataSourceWhenThereAreNoValuesShouldReturnEmptyList() { assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll(mock(DataSource.class))).isEmpty(); } @Test - void resolveAllWhenValueDoesNotContainPlaceholderShouldReturnValueUnchanged() { + void resolveAllWithDataSourceWhenValueDoesNotContainPlaceholderShouldReturnValueUnchanged() { assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll(mock(DataSource.class), "schema.sql")) .containsExactly("schema.sql"); } @Test - void resolveAllWhenValuesContainPlaceholdersShouldReturnValuesWithPlaceholdersReplaced() throws SQLException { + void resolveAllWithDataSourceWhenValuesContainPlaceholdersShouldReturnValuesWithPlaceholdersReplaced() + throws SQLException { assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll(dataSourceWithProductName("PostgreSQL"), "schema.sql", "schema-@@platform@@.sql", "data-@@platform@@.sql")).containsExactly("schema.sql", "schema-postgresql.sql", "data-postgresql.sql"); } @Test - void resolveAllWhenDriverMappingsAreCustomizedShouldResolvePlaceholderUsingCustomMapping() throws SQLException { + void resolveAllWithDataSourceWhenDriverMappingsAreCustomizedShouldResolvePlaceholderUsingCustomMapping() + throws SQLException { assertThat(new PlatformPlaceholderDatabaseDriverResolver() .withDriverPlatform(DatabaseDriver.POSTGRESQL, "postgres") .resolveAll(dataSourceWithProductName("PostgreSQL"), "schema-@@platform@@.sql")) @@ -65,19 +86,19 @@ void resolveAllWhenDriverMappingsAreCustomizedShouldResolvePlaceholderUsingCusto } @Test - void resolveAllWhenValueIsAnEmptyStringShouldReturnValueUnchanged() { + void resolveAllWithDataSourceWhenValueIsAnEmptyStringShouldReturnValueUnchanged() { assertThat(new PlatformPlaceholderDatabaseDriverResolver().resolveAll(mock(DataSource.class), "")) .containsExactly(""); } @Test - void resolveAllWhenDriverIsUnknownShouldThrow() { + void resolveAllWithDataSourceWhenDriverIsUnknownShouldThrow() { assertThatIllegalStateException().isThrownBy(() -> new PlatformPlaceholderDatabaseDriverResolver() .resolveAll(dataSourceWithProductName("CustomDB"), "schema-@@platform@@.sql")); } @Test - void resolveAllWhenPlaceholderIsCustomizedShouldResolvePlaceholders() throws SQLException { + void resolveAllWithDataSourceWhenPlaceholderIsCustomizedShouldResolvePlaceholders() throws SQLException { assertThat(new PlatformPlaceholderDatabaseDriverResolver("##platform##").resolveAll( dataSourceWithProductName("PostgreSQL"), "schema-##platform##.sql", "schema-@@platform@@.sql")) .containsExactly("schema-postgresql.sql", "schema-@@platform@@.sql");