Revert "Fix detection logic for embedded databases"

This reverts commit c4a5a34702.

See gh-23721
This commit is contained in:
Stephane Nicoll
2020-10-19 12:25:00 +02:00
parent e8187f9bb0
commit dd74810c80
5 changed files with 17 additions and 188 deletions

View File

@@ -17,11 +17,8 @@
package org.springframework.boot.jdbc;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Locale;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.sql.DataSource;
@@ -46,25 +43,24 @@ public enum EmbeddedDatabaseConnection {
/**
* No Connection.
*/
NONE(null, null, null, (url) -> false),
NONE(null, null, null),
/**
* H2 Database Connection.
*/
H2(EmbeddedDatabaseType.H2, DatabaseDriver.H2.getDriverClassName(),
"jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", (url) -> url.contains(":h2:mem")),
"jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"),
/**
* Derby Database Connection.
*/
DERBY(EmbeddedDatabaseType.DERBY, DatabaseDriver.DERBY.getDriverClassName(), "jdbc:derby:memory:%s;create=true",
(url) -> true),
DERBY(EmbeddedDatabaseType.DERBY, DatabaseDriver.DERBY.getDriverClassName(), "jdbc:derby:memory:%s;create=true"),
/**
* HSQL Database Connection.
*/
HSQL(EmbeddedDatabaseType.HSQL, DatabaseDriver.HSQLDB.getDriverClassName(), "org.hsqldb.jdbcDriver",
"jdbc:hsqldb:mem:%s", (url) -> url.contains(":hsqldb:mem:"));
"jdbc:hsqldb:mem:%s");
private final EmbeddedDatabaseType type;
@@ -74,20 +70,15 @@ public enum EmbeddedDatabaseConnection {
private final String url;
private final Predicate<String> embeddedUrl;
EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, String url,
Predicate<String> embeddedUrl) {
this(type, driverClass, null, url, embeddedUrl);
EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, String url) {
this(type, driverClass, null, url);
}
EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, String fallbackDriverClass, String url,
Predicate<String> embeddedUrl) {
EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, String fallbackDriverClass, String url) {
this.type = type;
this.driverClass = driverClass;
this.alternativeDriverClass = fallbackDriverClass;
this.url = url;
this.embeddedUrl = embeddedUrl;
}
/**
@@ -116,48 +107,19 @@ public enum EmbeddedDatabaseConnection {
return (this.url != null) ? String.format(this.url, databaseName) : null;
}
boolean isEmbeddedUrl(String url) {
return this.embeddedUrl.test(url);
}
boolean isDriverCompatible(String driverClass) {
return (driverClass != null
&& (driverClass.equals(this.driverClass) || driverClass.equals(this.alternativeDriverClass)));
}
/**
* Convenience method to determine if a given driver class name represents an embedded
* database type.
* @param driverClass the driver class
* @return true if the driver class is one of the embedded types
* @deprecated since 2.3.5 in favor of {@link #isEmbedded(String, String)}
*/
@Deprecated
public static boolean isEmbedded(String driverClass) {
return isEmbedded(driverClass, null);
return driverClass != null
&& (matches(HSQL, driverClass) || matches(H2, driverClass) || matches(DERBY, driverClass));
}
/**
* Convenience method to determine if a given driver class name and url represent an
* embedded database type.
* @param driverClass the driver class
* @param url the jdbc url (can be {@code null)}
* @return true if the driver class and url refer to an embedded database
*/
public static boolean isEmbedded(String driverClass, String url) {
if (driverClass == null) {
return false;
}
EmbeddedDatabaseConnection connection = getEmbeddedDatabaseConnection(driverClass);
if (connection == NONE) {
return false;
}
return (url == null || connection.isEmbeddedUrl(url));
}
private static EmbeddedDatabaseConnection getEmbeddedDatabaseConnection(String driverClass) {
return Stream.of(H2, HSQL, DERBY).filter((connection) -> connection.isDriverCompatible(driverClass)).findFirst()
.orElse(NONE);
private static boolean matches(EmbeddedDatabaseConnection candidate, String driverClass) {
return driverClass.equals(candidate.driverClass) || driverClass.equals(candidate.alternativeDriverClass);
}
/**
@@ -198,8 +160,7 @@ public enum EmbeddedDatabaseConnection {
@Override
public Boolean doInConnection(Connection connection) throws SQLException, DataAccessException {
DatabaseMetaData metaData = connection.getMetaData();
String productName = metaData.getDatabaseProductName();
String productName = connection.getMetaData().getDatabaseProductName();
if (productName == null) {
return false;
}
@@ -207,8 +168,7 @@ public enum EmbeddedDatabaseConnection {
EmbeddedDatabaseConnection[] candidates = EmbeddedDatabaseConnection.values();
for (EmbeddedDatabaseConnection candidate : candidates) {
if (candidate != NONE && productName.contains(candidate.name())) {
String url = metaData.getURL();
return (url == null || candidate.isEmbeddedUrl(url));
return true;
}
}
return false;

View File

@@ -16,24 +16,10 @@
package org.springframework.boot.jdbc;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link EmbeddedDatabaseConnection}.
@@ -71,85 +57,4 @@ class EmbeddedDatabaseConnectionTests {
.withMessageContaining("DatabaseName must not be empty");
}
@ParameterizedTest(name = "{0} - {1}")
@MethodSource("embeddedDriverAndUrlParameters")
void isEmbeddedWithDriverAndUrl(String driverClassName, String url, boolean embedded) {
assertThat(EmbeddedDatabaseConnection.isEmbedded(driverClassName, url)).isEqualTo(embedded);
}
static Object[] embeddedDriverAndUrlParameters() {
return new Object[] {
new Object[] { EmbeddedDatabaseConnection.H2.getDriverClassName(), "jdbc:h2:~/test", false },
new Object[] { EmbeddedDatabaseConnection.H2.getDriverClassName(), "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
true },
new Object[] { EmbeddedDatabaseConnection.H2.getDriverClassName(), null, true },
new Object[] { EmbeddedDatabaseConnection.HSQL.getDriverClassName(), "jdbc:hsqldb:hsql://localhost",
false },
new Object[] { EmbeddedDatabaseConnection.HSQL.getDriverClassName(), "jdbc:hsqldb:mem:test", true },
new Object[] { EmbeddedDatabaseConnection.HSQL.getDriverClassName(), null, true },
new Object[] { EmbeddedDatabaseConnection.DERBY.getDriverClassName(), "jdbc:derby:memory:test", true },
new Object[] { EmbeddedDatabaseConnection.DERBY.getDriverClassName(), null, true },
new Object[] { "com.mysql.cj.jdbc.Driver", "jdbc:mysql:mem:test", false },
new Object[] { "com.mysql.cj.jdbc.Driver", null, false },
new Object[] { null, "jdbc:none:mem:test", false }, new Object[] { null, null, false } };
}
@Test
void isEmbeddedWithH2DataSource() {
testEmbeddedDatabase(new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build());
}
@Test
void isEmbeddedWithHsqlDataSource() {
testEmbeddedDatabase(new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).build());
}
@Test
void isEmbeddedWithDerbyDataSource() {
testEmbeddedDatabase(new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.DERBY).build());
}
void testEmbeddedDatabase(EmbeddedDatabase database) {
try {
assertThat(EmbeddedDatabaseConnection.isEmbedded(database)).isTrue();
}
finally {
database.shutdown();
}
}
@Test
void isEmbeddedWithUnknownDataSource() throws SQLException {
assertThat(EmbeddedDatabaseConnection.isEmbedded(mockDataSource("unknown-db", null))).isFalse();
}
@Test
void isEmbeddedWithH2File() throws SQLException {
assertThat(EmbeddedDatabaseConnection
.isEmbedded(mockDataSource(EmbeddedDatabaseConnection.H2.getDriverClassName(), "jdbc:h2:~/test")))
.isFalse();
}
@Test
void isEmbeddedWithMissingDriverClassMetadata() throws SQLException {
assertThat(EmbeddedDatabaseConnection.isEmbedded(mockDataSource(null, "jdbc:h2:meme:test"))).isFalse();
}
@Test
void isEmbeddedWithMissingUrlMetadata() throws SQLException {
assertThat(EmbeddedDatabaseConnection
.isEmbedded(mockDataSource(EmbeddedDatabaseConnection.H2.getDriverClassName(), null))).isTrue();
}
DataSource mockDataSource(String productName, String connectionUrl) throws SQLException {
DatabaseMetaData metaData = mock(DatabaseMetaData.class);
given(metaData.getDatabaseProductName()).willReturn(productName);
given(metaData.getURL()).willReturn(connectionUrl);
Connection connection = mock(Connection.class);
given(connection.getMetaData()).willReturn(metaData);
DataSource dataSource = mock(DataSource.class);
given(dataSource.getConnection()).willReturn(connection);
return dataSource;
}
}