Browse Source

Polish "Auto-detect jOOQ dialect"

Closes gh-9355
pull/9227/merge
Stephane Nicoll 9 years ago
parent
commit
efdf451e6e
  1. 6
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java
  2. 8
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java
  3. 125
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTest.java
  4. 104
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookupTests.java
  5. 105
      spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java
  6. 20
      spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

6
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java

@ -49,14 +49,14 @@ public class JooqProperties {
/** /**
* Determine the {@link SQLDialect} to use based on this configuration and the primary * Determine the {@link SQLDialect} to use based on this configuration and the primary
* {@link DataSource}. * {@link DataSource}.
* @param dataSource the auto-configured data source * @param dataSource the data source
* @return {@code SQLDialect} * @return the {@code SQLDialect} to use for that {@link DataSource}
*/ */
public SQLDialect determineSqlDialect(DataSource dataSource) { public SQLDialect determineSqlDialect(DataSource dataSource) {
if (this.sqlDialect != null) { if (this.sqlDialect != null) {
return this.sqlDialect; return this.sqlDialect;
} }
return SQLDialectLookup.getDialect(dataSource); return SqlDialectLookup.getDialect(dataSource);
} }
} }

8
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookup.java → spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java

@ -33,13 +33,11 @@ import org.springframework.jdbc.support.MetaDataAccessException;
/** /**
* Utility to lookup well known {@link SQLDialect SQLDialects} from a {@link DataSource}. * Utility to lookup well known {@link SQLDialect SQLDialects} from a {@link DataSource}.
* *
* Note: This lookup only supports the SQL dialects that the open source edition of jOOQ supports.
*
* @author Michael Simons * @author Michael Simons
*/ */
final class SQLDialectLookup { final class SqlDialectLookup {
private static final Log logger = LogFactory.getLog(SQLDialectLookup.class); private static final Log logger = LogFactory.getLog(SqlDialectLookup.class);
private static final Map<DatabaseDriver, SQLDialect> LOOKUP; private static final Map<DatabaseDriver, SQLDialect> LOOKUP;
@ -55,7 +53,7 @@ final class SQLDialectLookup {
LOOKUP = Collections.unmodifiableMap(map); LOOKUP = Collections.unmodifiableMap(map);
} }
private SQLDialectLookup() { private SqlDialectLookup() {
} }
/** /**

125
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTest.java

@ -0,0 +1,125 @@
/*
* Copyright 2012-2017 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
*
* http://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.jooq;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.jooq.SQLDialect;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link JooqProperties}.
*
* @author Stephane Nicoll
*/
public class JooqPropertiesTest {
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void determineSqlDialectNoCheckIfDialectIsSet() throws SQLException {
JooqProperties properties = load("spring.jooq.sql-dialect=postgres");
DataSource dataSource = mockStandaloneDataSource();
SQLDialect sqlDialect = properties.determineSqlDialect(dataSource);
assertThat(sqlDialect).isEqualTo(SQLDialect.POSTGRES);
verify(dataSource, never()).getConnection();
}
@Test
public void determineSqlDialectWithKnownUrl() {
JooqProperties properties = load();
SQLDialect sqlDialect = properties
.determineSqlDialect(mockDataSource("jdbc:h2:mem:testdb"));
assertThat(sqlDialect).isEqualTo(SQLDialect.H2);
}
@Test
public void determineSqlDialectWithKnownUrlAndUserConfig() {
JooqProperties properties = load("spring.jooq.sql-dialect=mysql");
SQLDialect sqlDialect = properties
.determineSqlDialect(mockDataSource("jdbc:h2:mem:testdb"));
assertThat(sqlDialect).isEqualTo(SQLDialect.MYSQL);
}
@Test
public void determineSqlDialectWithUnknownUrl() {
JooqProperties properties = load();
SQLDialect sqlDialect = properties
.determineSqlDialect(mockDataSource("jdbc:unknown://localhost"));
assertThat(sqlDialect).isEqualTo(SQLDialect.DEFAULT);
}
private DataSource mockStandaloneDataSource() throws SQLException {
DataSource ds = mock(DataSource.class);
given(ds.getConnection()).willThrow(SQLException.class);
return ds;
}
private DataSource mockDataSource(String jdbcUrl) {
DataSource ds = mock(DataSource.class);
try {
DatabaseMetaData metadata = mock(DatabaseMetaData.class);
given(metadata.getURL()).willReturn(jdbcUrl);
Connection connection = mock(Connection.class);
given(connection.getMetaData()).willReturn(metadata);
given(ds.getConnection()).willReturn(connection);
}
catch (SQLException e) {
// Do nothing
}
return ds;
}
private JooqProperties load(String... environment) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
TestPropertyValues.of(environment).applyTo(ctx);
ctx.register(TestConfiguration.class);
ctx.refresh();
this.context = ctx;
return this.context.getBean(JooqProperties.class);
}
@Configuration
@EnableConfigurationProperties(JooqProperties.class)
static class TestConfiguration {
}
}

104
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookupTests.java

@ -1,104 +0,0 @@
/*
* Copyright 2012-2017 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
*
* http://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.jooq;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import javax.sql.DataSource;
import org.jooq.SQLDialect;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link SQLDialectLookup}.
*
* @author Michael Simons
*/
public class SQLDialectLookupTests {
@Test
public void getDatabaseWhenDataSourceIsNullShouldReturnDefault() throws Exception {
assertThat(SQLDialectLookup.getDialect(null)).isEqualTo(SQLDialect.DEFAULT);
}
@Test
public void getDatabaseWhenDataSourceIsUnknownShouldReturnDefault() throws Exception {
testGetDatabase("jdbc:idontexist:", SQLDialect.DEFAULT);
}
@Test
public void getDatabaseWhenDerbyShouldReturnDerby() throws Exception {
testGetDatabase("jdbc:derby:", SQLDialect.DERBY);
}
@Test
public void getDatabaseWhenH2ShouldReturnH2() throws Exception {
testGetDatabase("jdbc:h2:", SQLDialect.H2);
}
@Test
public void getDatabaseWhenHsqldbShouldReturnHsqldb() throws Exception {
testGetDatabase("jdbc:hsqldb:", SQLDialect.HSQLDB);
}
@Test
public void getDatabaseWhenMysqlShouldReturnMysql() throws Exception {
testGetDatabase("jdbc:mysql:", SQLDialect.MYSQL);
}
@Test
public void getDatabaseWhenOracleShouldReturnOracle() throws Exception {
testGetDatabase("jdbc:oracle:", SQLDialect.DEFAULT);
}
@Test
public void getDatabaseWhenPostgresShouldReturnPostgres() throws Exception {
testGetDatabase("jdbc:postgresql:", SQLDialect.POSTGRES);
}
@Test
public void getDatabaseWhenSqlserverShouldReturnSqlserver() throws Exception {
testGetDatabase("jdbc:sqlserver:", SQLDialect.DEFAULT);
}
@Test
public void getDatabaseWhenDb2ShouldReturnDb2() throws Exception {
testGetDatabase("jdbc:db2:", SQLDialect.DEFAULT);
}
@Test
public void getDatabaseWhenInformixShouldReturnInformix() throws Exception {
testGetDatabase("jdbc:informix-sqli:", SQLDialect.DEFAULT);
}
private void testGetDatabase(String url, SQLDialect expected) throws Exception {
DataSource dataSource = mock(DataSource.class);
Connection connection = mock(Connection.class);
DatabaseMetaData metaData = mock(DatabaseMetaData.class);
given(dataSource.getConnection()).willReturn(connection);
given(connection.getMetaData()).willReturn(metaData);
given(metaData.getURL()).willReturn(url);
SQLDialect sQLDialect = SQLDialectLookup.getDialect(dataSource);
assertThat(sQLDialect).isEqualTo(expected);
}
}

105
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java

@ -0,0 +1,105 @@
/*
* Copyright 2012-2017 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
*
* http://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.jooq;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import javax.sql.DataSource;
import org.jooq.SQLDialect;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link SqlDialectLookup}.
*
* @author Michael Simons
* @author Stephane Nicoll
*/
public class SqlDialectLookupTests {
@Test
public void getSqlDialectWhenDataSourceIsNullShouldReturnDefault() throws Exception {
assertThat(SqlDialectLookup.getDialect(null)).isEqualTo(SQLDialect.DEFAULT);
}
@Test
public void getSqlDialectWhenDataSourceIsUnknownShouldReturnDefault() throws Exception {
testGetSqlDialect("jdbc:idontexist:", SQLDialect.DEFAULT);
}
@Test
public void getSqlDialectWhenDerbyShouldReturnDerby() throws Exception {
testGetSqlDialect("jdbc:derby:", SQLDialect.DERBY);
}
@Test
public void getSqlDialectWhenH2ShouldReturnH2() throws Exception {
testGetSqlDialect("jdbc:h2:", SQLDialect.H2);
}
@Test
public void getSqlDialectWhenHsqldbShouldReturnHsqldb() throws Exception {
testGetSqlDialect("jdbc:hsqldb:", SQLDialect.HSQLDB);
}
@Test
public void getSqlDialectWhenMysqlShouldReturnMysql() throws Exception {
testGetSqlDialect("jdbc:mysql:", SQLDialect.MYSQL);
}
@Test
public void getSqlDialectWhenOracleShouldReturnOracle() throws Exception {
testGetSqlDialect("jdbc:oracle:", SQLDialect.DEFAULT);
}
@Test
public void getSqlDialectWhenPostgresShouldReturnPostgres() throws Exception {
testGetSqlDialect("jdbc:postgresql:", SQLDialect.POSTGRES);
}
@Test
public void getSqlDialectWhenSqlserverShouldReturnSqlserver() throws Exception {
testGetSqlDialect("jdbc:sqlserver:", SQLDialect.DEFAULT);
}
@Test
public void getSqlDialectWhenDb2ShouldReturnDb2() throws Exception {
testGetSqlDialect("jdbc:db2:", SQLDialect.DEFAULT);
}
@Test
public void getSqlDialectWhenInformixShouldReturnInformix() throws Exception {
testGetSqlDialect("jdbc:informix-sqli:", SQLDialect.DEFAULT);
}
private void testGetSqlDialect(String url, SQLDialect expected) throws Exception {
DataSource dataSource = mock(DataSource.class);
Connection connection = mock(Connection.class);
DatabaseMetaData metaData = mock(DatabaseMetaData.class);
given(dataSource.getConnection()).willReturn(connection);
given(connection.getMetaData()).willReturn(metaData);
given(metaData.getURL()).willReturn(url);
SQLDialect sqlDialect = SqlDialectLookup.getDialect(dataSource);
assertThat(sqlDialect).isEqualTo(expected);
}
}

20
spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

@ -3213,23 +3213,17 @@ You can then use the `DSLContext` to construct your queries:
==== Customizing jOOQ ==== jOOQ SQL dialect
Spring Boot determines the SQL dialect to use for your datasource unless the
Spring Boot tries to determine the best SQL dialect for your datasource, but you can customize `spring.jooq.sql-dialect` property has been configured. If the dialect couldn't be
the dialect used by jOOQ by setting `spring.jooq.sql-dialect` in your `application.properties`. detected, `DEFAULT` is used.
Spring Boot uses `SQLDialect.DEFAULT` if it cannot determine the type of your database.
Spring Boot can only auto-configure dialects supported by the open source version of jOOQ. Dialects NOTE: Spring Boot can only auto-configure dialects supported by the open source version of
supported by the commercial edition only have to be configured manually. For example, to specify jOOQ.
Oracle you would add:
[source,properties,indent=0]
----
spring.jooq.sql-dialect=ORACLE12C
----
Refer to `org.jooq.SQLDialect` for all valid dialects.
==== Customizing jOOQ
More advanced customizations can be achieved by defining your own `@Bean` definitions More advanced customizations can be achieved by defining your own `@Bean` definitions
which will be used when the jOOQ `Configuration` is created. You can define beans for which will be used when the jOOQ `Configuration` is created. You can define beans for
the following jOOQ Types: the following jOOQ Types:

Loading…
Cancel
Save