GH-804 - Polishing.
Actively reject attempts to use a dedicated schema with SQL Server. Prevent schema reset being executed if no schema is used. Properly report exception during database name detection. Original pull request: GH-808.
This commit is contained in:
@@ -67,8 +67,9 @@ class DatabaseSchemaInitializer implements InitializingBean {
|
||||
|
||||
var initialSchema = connection.getSchema();
|
||||
var schemaName = properties.getSchema();
|
||||
var useSchema = schemaName != null && !schemaName.isEmpty();
|
||||
|
||||
if (schemaName != null && !schemaName.isEmpty()) { // A schema name has been specified.
|
||||
if (useSchema) { // A schema name has been specified.
|
||||
|
||||
if (eventPublicationTableExists(schemaName)) {
|
||||
return;
|
||||
@@ -82,7 +83,7 @@ class DatabaseSchemaInitializer implements InitializingBean {
|
||||
new ResourceDatabasePopulator(locator.getSchemaResource(databaseType)).execute(dataSource);
|
||||
|
||||
// Return to the initial schema.
|
||||
if (initialSchema != null) {
|
||||
if (initialSchema != null && useSchema) {
|
||||
jdbcOperations.execute(databaseType.getSetSchemaSql(initialSchema));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,16 @@ enum DatabaseType {
|
||||
UUID databaseToUUID(Object id) {
|
||||
return UUID.fromString(id.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isSchemaSupported() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
POSTGRES("postgresql", "PostgreSQL"),
|
||||
|
||||
MSSQL("sqlserver", "Microsoft SQL Server"){
|
||||
MSSQL("sqlserver", "Microsoft SQL Server") {
|
||||
|
||||
@Override
|
||||
Object uuidToDatabase(UUID id) {
|
||||
@@ -58,6 +63,11 @@ enum DatabaseType {
|
||||
UUID databaseToUUID(Object id) {
|
||||
return UUID.fromString(id.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isSchemaSupported() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static final String SCHEMA_NOT_SUPPORTED = "Setting the schema name not supported on MySQL!";
|
||||
@@ -92,14 +102,21 @@ enum DatabaseType {
|
||||
return "/schema-" + value + ".sql";
|
||||
}
|
||||
|
||||
boolean isSchemaSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
String getSetSchemaSql(String schema) {
|
||||
|
||||
if (!isSchemaSupported()) {
|
||||
throw new IllegalArgumentException(SCHEMA_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
return switch (this) {
|
||||
|
||||
case MYSQL -> throw new IllegalArgumentException(SCHEMA_NOT_SUPPORTED);
|
||||
case H2, HSQLDB -> "SET SCHEMA " + schema;
|
||||
case POSTGRES -> "SET search_path TO " + schema;
|
||||
case MSSQL -> ""; // No equivalent schema-switching command in MSSQL
|
||||
default -> throw new IllegalArgumentException(SCHEMA_NOT_SUPPORTED);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class JdbcConfigurationProperties {
|
||||
|
||||
void verify(DatabaseType databaseType) {
|
||||
|
||||
if (schema != null && databaseType.equals(DatabaseType.MYSQL)) {
|
||||
if (schema != null && !databaseType.isSchemaSupported()) {
|
||||
throw new IllegalStateException(DatabaseType.SCHEMA_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,9 @@ class JdbcEventPublicationAutoConfiguration implements EventPublicationConfigura
|
||||
var metadata = JdbcUtils.extractDatabaseMetaData(dataSource, DatabaseMetaData::getDatabaseProductName);
|
||||
name = JdbcUtils.commonDatabaseName(metadata);
|
||||
|
||||
} catch (Exception o_O) {}
|
||||
} catch (Exception o_O) {
|
||||
throw new RuntimeException(o_O);
|
||||
}
|
||||
|
||||
return name == null ? "UNKNOWN" : name;
|
||||
}
|
||||
|
||||
@@ -9,4 +9,4 @@ CREATE TABLE EVENT_PUBLICATION
|
||||
COMPLETION_DATE DATETIME2(6) NULL,
|
||||
PRIMARY KEY (ID),
|
||||
INDEX EVENT_PUBLICATION_BY_COMPLETION_DATE_IDX (COMPLETION_DATE)
|
||||
);
|
||||
);
|
||||
|
||||
@@ -44,11 +44,18 @@ class DatabaseSchemaInitializerUnitTests {
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "", "test" })
|
||||
void rejectsExplicitSchemaNameForMySql(String schema) {
|
||||
assertThatIllegalStateException().isThrownBy(() -> createInitializer(withSchema(schema)));
|
||||
assertThatIllegalStateException().isThrownBy(() -> createInitializer(withSchema(schema), DatabaseType.MYSQL));
|
||||
}
|
||||
|
||||
private DatabaseSchemaInitializer createInitializer(JdbcConfigurationProperties properties) {
|
||||
return new DatabaseSchemaInitializer(dataSource, resourceLoader, DatabaseType.MYSQL, jdbcTemplate, properties);
|
||||
// GH-804
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "", "test" })
|
||||
void rejectsExplicitSchemaNameForMSSql(String schema) {
|
||||
assertThatIllegalStateException().isThrownBy(() -> createInitializer(withSchema(schema), DatabaseType.MSSQL));
|
||||
}
|
||||
|
||||
private DatabaseSchemaInitializer createInitializer(JdbcConfigurationProperties properties, DatabaseType type) {
|
||||
return new DatabaseSchemaInitializer(dataSource, resourceLoader, type, jdbcTemplate, properties);
|
||||
}
|
||||
|
||||
private static JdbcConfigurationProperties withSchema(String schema) {
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.modulith.events.core.EventSerializer;
|
||||
@@ -46,6 +45,7 @@ import org.springframework.modulith.events.support.CompletionMode;
|
||||
import org.springframework.modulith.testapp.TestApplication;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
/**
|
||||
@@ -454,11 +454,9 @@ class JdbcEventPublicationRepositoryIntegrationTests {
|
||||
class PostgresWithDeleteCompletion extends WithDeleteCompletion {}
|
||||
|
||||
// MSSQL
|
||||
@WithMssql
|
||||
class MssqlWithNoDefinedSchemaName extends WithNoDefinedSchemaName {}
|
||||
|
||||
@WithMssql
|
||||
class MssqlWithEmptySchemaName extends WithEmptySchemaName {}
|
||||
class MssqlWithNoDefinedSchemaName extends WithNoDefinedSchemaName {}
|
||||
|
||||
@WithMssql
|
||||
class MssqlWithDeleteCompletion extends WithDeleteCompletion {}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
spring.datasource.url=jdbc:tc:sqlserver:2022-latest:///events;encrypt=false;TC_ACCEPT_LICENSE=accept
|
||||
spring.datasource.driverClassName=org.testcontainers.jdbc.ContainerDatabaseDriver
|
||||
spring.datasource.url=jdbc:tc:sqlserver:2022-latest:///events;encrypt=false
|
||||
spring.datasource.driverClassName=org.testcontainers.jdbc.ContainerDatabaseDriver
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
mcr.microsoft.com/mssql/server:2022-latest
|
||||
Reference in New Issue
Block a user