diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java index d15f64df82..f22f8186b3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java +++ b/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 * {@link DataSource}. - * @param dataSource the auto-configured data source - * @return {@code SQLDialect} + * @param dataSource the data source + * @return the {@code SQLDialect} to use for that {@link DataSource} */ public SQLDialect determineSqlDialect(DataSource dataSource) { if (this.sqlDialect != null) { return this.sqlDialect; } - return SQLDialectLookup.getDialect(dataSource); + return SqlDialectLookup.getDialect(dataSource); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookup.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java similarity index 91% rename from spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookup.java rename to spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java index 39768a491a..300d3310dc 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookup.java +++ b/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}. * - * Note: This lookup only supports the SQL dialects that the open source edition of jOOQ supports. - * * @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 LOOKUP; @@ -55,7 +53,7 @@ final class SQLDialectLookup { LOOKUP = Collections.unmodifiableMap(map); } - private SQLDialectLookup() { + private SqlDialectLookup() { } /** diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTest.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTest.java new file mode 100644 index 0000000000..362885137f --- /dev/null +++ b/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 { + + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookupTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookupTests.java deleted file mode 100644 index d0fda22170..0000000000 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SQLDialectLookupTests.java +++ /dev/null @@ -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); - } - -} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java new file mode 100644 index 0000000000..dd3f4e7aa8 --- /dev/null +++ b/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); + } + +} diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 484dd64e0a..463bda3d6f 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/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 - -Spring Boot tries to determine the best SQL dialect for your datasource, but you can customize -the dialect used by jOOQ by setting `spring.jooq.sql-dialect` in your `application.properties`. -Spring Boot uses `SQLDialect.DEFAULT` if it cannot determine the type of your database. +==== jOOQ SQL dialect +Spring Boot determines the SQL dialect to use for your datasource unless the +`spring.jooq.sql-dialect` property has been configured. If the dialect couldn't be +detected, `DEFAULT` is used. -Spring Boot can only auto-configure dialects supported by the open source version of jOOQ. Dialects -supported by the commercial edition only have to be configured manually. For example, to specify -Oracle you would add: +NOTE: Spring Boot can only auto-configure dialects supported by the open source version of +jOOQ. -[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 which will be used when the jOOQ `Configuration` is created. You can define beans for the following jOOQ Types: