Reinstate support for jOOQ as it now supports Jakarta EE 9
Closes gh-29271pull/29274/head
parent
ccc924b908
commit
c2e86096cd
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import org.jooq.impl.DefaultConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback interface that can be implemented by beans wishing to customize the
|
||||||
|
* {@link DefaultConfiguration} whilst retaining default auto-configuration.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @since 2.5.0
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface DefaultConfigurationCustomizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customize the {@link DefaultConfiguration jOOQ Configuration}.
|
||||||
|
* @param configuration the configuration to customize
|
||||||
|
*/
|
||||||
|
void customize(DefaultConfiguration configuration);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
|
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
|
||||||
|
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link BeanFactoryPostProcessor} that can be used to dynamically declare that all
|
||||||
|
* {@link DSLContext} beans should "depend on" one or more specific beans.
|
||||||
|
*
|
||||||
|
* @author Eddú Meléndez
|
||||||
|
* @since 2.3.9
|
||||||
|
* @see BeanDefinition#setDependsOn(String[])
|
||||||
|
* @deprecated since 2.5.0 for removal in 2.7.0 in favor of
|
||||||
|
* {@link DependsOnDatabaseInitializationDetector}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class DslContextDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@code DslContextDependsOnPostProcessor} that will set up
|
||||||
|
* dependencies upon beans with the given names.
|
||||||
|
* @param dependsOn names of the beans to depend upon
|
||||||
|
*/
|
||||||
|
public DslContextDependsOnPostProcessor(String... dependsOn) {
|
||||||
|
super(DSLContext.class, dependsOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@code DslContextDependsOnPostProcessor} that will set up
|
||||||
|
* dependencies upon beans with the given types.
|
||||||
|
* @param dependsOn types of the beans to depend upon
|
||||||
|
*/
|
||||||
|
public DslContextDependsOnPostProcessor(Class<?>... dependsOn) {
|
||||||
|
super(DSLContext.class, dependsOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.ConnectionProvider;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.ExecuteListenerProvider;
|
||||||
|
import org.jooq.ExecutorProvider;
|
||||||
|
import org.jooq.RecordListenerProvider;
|
||||||
|
import org.jooq.RecordMapperProvider;
|
||||||
|
import org.jooq.RecordUnmapperProvider;
|
||||||
|
import org.jooq.TransactionListenerProvider;
|
||||||
|
import org.jooq.TransactionProvider;
|
||||||
|
import org.jooq.VisitListenerProvider;
|
||||||
|
import org.jooq.conf.Settings;
|
||||||
|
import org.jooq.impl.DataSourceConnectionProvider;
|
||||||
|
import org.jooq.impl.DefaultConfiguration;
|
||||||
|
import org.jooq.impl.DefaultDSLContext;
|
||||||
|
import org.jooq.impl.DefaultExecuteListenerProvider;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EnableAutoConfiguration Auto-configuration} for JOOQ.
|
||||||
|
*
|
||||||
|
* @author Andreas Ahlenstorf
|
||||||
|
* @author Michael Simons
|
||||||
|
* @author Dmytro Nosan
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnClass(DSLContext.class)
|
||||||
|
@ConditionalOnBean(DataSource.class)
|
||||||
|
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, TransactionAutoConfiguration.class })
|
||||||
|
public class JooqAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(ConnectionProvider.class)
|
||||||
|
public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource) {
|
||||||
|
return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(PlatformTransactionManager.class)
|
||||||
|
public SpringTransactionProvider transactionProvider(PlatformTransactionManager txManager) {
|
||||||
|
return new SpringTransactionProvider(txManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Order(0)
|
||||||
|
public DefaultExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider() {
|
||||||
|
return new DefaultExecuteListenerProvider(new JooqExceptionTranslator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnMissingBean(DSLContext.class)
|
||||||
|
@EnableConfigurationProperties(JooqProperties.class)
|
||||||
|
public static class DslContextConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DefaultDSLContext dslContext(org.jooq.Configuration configuration) {
|
||||||
|
return new DefaultDSLContext(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(org.jooq.Configuration.class)
|
||||||
|
public DefaultConfiguration jooqConfiguration(JooqProperties properties, ConnectionProvider connectionProvider,
|
||||||
|
DataSource dataSource, ObjectProvider<ExecuteListenerProvider> executeListenerProviders,
|
||||||
|
ObjectProvider<DefaultConfigurationCustomizer> configurationCustomizers) {
|
||||||
|
DefaultConfiguration configuration = new DefaultConfiguration();
|
||||||
|
configuration.set(properties.determineSqlDialect(dataSource));
|
||||||
|
configuration.set(connectionProvider);
|
||||||
|
configuration.set(executeListenerProviders.orderedStream().toArray(ExecuteListenerProvider[]::new));
|
||||||
|
configurationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(configuration));
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Deprecated
|
||||||
|
public DefaultConfigurationCustomizer jooqProvidersDefaultConfigurationCustomizer(
|
||||||
|
ObjectProvider<TransactionProvider> transactionProvider,
|
||||||
|
ObjectProvider<RecordMapperProvider> recordMapperProvider,
|
||||||
|
ObjectProvider<RecordUnmapperProvider> recordUnmapperProvider, ObjectProvider<Settings> settings,
|
||||||
|
ObjectProvider<RecordListenerProvider> recordListenerProviders,
|
||||||
|
ObjectProvider<VisitListenerProvider> visitListenerProviders,
|
||||||
|
ObjectProvider<TransactionListenerProvider> transactionListenerProviders,
|
||||||
|
ObjectProvider<ExecutorProvider> executorProvider) {
|
||||||
|
return new OrderedDefaultConfigurationCustomizer((configuration) -> {
|
||||||
|
transactionProvider.ifAvailable(configuration::set);
|
||||||
|
recordMapperProvider.ifAvailable(configuration::set);
|
||||||
|
recordUnmapperProvider.ifAvailable(configuration::set);
|
||||||
|
settings.ifAvailable(configuration::set);
|
||||||
|
executorProvider.ifAvailable(configuration::set);
|
||||||
|
configuration.set(recordListenerProviders.orderedStream().toArray(RecordListenerProvider[]::new));
|
||||||
|
configuration.set(visitListenerProviders.orderedStream().toArray(VisitListenerProvider[]::new));
|
||||||
|
configuration.setTransactionListenerProvider(
|
||||||
|
transactionListenerProviders.orderedStream().toArray(TransactionListenerProvider[]::new));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class OrderedDefaultConfigurationCustomizer implements DefaultConfigurationCustomizer, Ordered {
|
||||||
|
|
||||||
|
private final DefaultConfigurationCustomizer delegate;
|
||||||
|
|
||||||
|
OrderedDefaultConfigurationCustomizer(DefaultConfigurationCustomizer delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(DefaultConfiguration configuration) {
|
||||||
|
this.delegate.customize(configuration);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.jooq.ExecuteContext;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.jooq.impl.DefaultExecuteListener;
|
||||||
|
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
|
||||||
|
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
||||||
|
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms {@link java.sql.SQLException} into a Spring-specific
|
||||||
|
* {@link DataAccessException}.
|
||||||
|
*
|
||||||
|
* @author Lukas Eder
|
||||||
|
* @author Andreas Ahlenstorf
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @since 1.5.10
|
||||||
|
*/
|
||||||
|
public class JooqExceptionTranslator extends DefaultExecuteListener {
|
||||||
|
|
||||||
|
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(JooqExceptionTranslator.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exception(ExecuteContext context) {
|
||||||
|
SQLExceptionTranslator translator = getTranslator(context);
|
||||||
|
// The exception() callback is not only triggered for SQL exceptions but also for
|
||||||
|
// "normal" exceptions. In those cases sqlException() returns null.
|
||||||
|
SQLException exception = context.sqlException();
|
||||||
|
while (exception != null) {
|
||||||
|
handle(context, translator, exception);
|
||||||
|
exception = exception.getNextException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SQLExceptionTranslator getTranslator(ExecuteContext context) {
|
||||||
|
SQLDialect dialect = context.configuration().dialect();
|
||||||
|
if (dialect != null && dialect.thirdParty() != null) {
|
||||||
|
String dbName = dialect.thirdParty().springDbName();
|
||||||
|
if (dbName != null) {
|
||||||
|
return new SQLErrorCodeSQLExceptionTranslator(dbName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SQLStateSQLExceptionTranslator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a single exception in the chain. SQLExceptions might be nested multiple
|
||||||
|
* levels deep. The outermost exception is usually the least interesting one ("Call
|
||||||
|
* getNextException to see the cause."). Therefore the innermost exception is
|
||||||
|
* propagated and all other exceptions are logged.
|
||||||
|
* @param context the execute context
|
||||||
|
* @param translator the exception translator
|
||||||
|
* @param exception the exception
|
||||||
|
*/
|
||||||
|
private void handle(ExecuteContext context, SQLExceptionTranslator translator, SQLException exception) {
|
||||||
|
DataAccessException translated = translate(context, translator, exception);
|
||||||
|
if (exception.getNextException() == null) {
|
||||||
|
if (translated != null) {
|
||||||
|
context.exception(translated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.error("Execution of SQL statement failed.", (translated != null) ? translated : exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataAccessException translate(ExecuteContext context, SQLExceptionTranslator translator,
|
||||||
|
SQLException exception) {
|
||||||
|
return translator.translate("jOOQ", context.sql(), exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration properties for the JOOQ database library.
|
||||||
|
*
|
||||||
|
* @author Andreas Ahlenstorf
|
||||||
|
* @author Michael Simons
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "spring.jooq")
|
||||||
|
public class JooqProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL dialect to use. Auto-detected by default.
|
||||||
|
*/
|
||||||
|
private SQLDialect sqlDialect;
|
||||||
|
|
||||||
|
public SQLDialect getSqlDialect() {
|
||||||
|
return this.sqlDialect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSqlDialect(SQLDialect sqlDialect) {
|
||||||
|
this.sqlDialect = sqlDialect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the {@link SQLDialect} to use based on this configuration and the primary
|
||||||
|
* {@link DataSource}.
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||||
|
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
|
||||||
|
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
|
class NoDslContextBeanFailureAnalyzer extends AbstractFailureAnalyzer<NoSuchBeanDefinitionException>
|
||||||
|
implements Ordered, BeanFactoryAware {
|
||||||
|
|
||||||
|
private BeanFactory beanFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FailureAnalysis analyze(Throwable rootFailure, NoSuchBeanDefinitionException cause) {
|
||||||
|
if (DSLContext.class.equals(cause.getBeanType()) && hasR2dbcAutoConfiguration()) {
|
||||||
|
return new FailureAnalysis(
|
||||||
|
"jOOQ has not been auto-configured as R2DBC has been auto-configured in favor of JDBC and jOOQ "
|
||||||
|
+ "auto-configuration does not yet support R2DBC. ",
|
||||||
|
"To use jOOQ with JDBC, exclude R2dbcAutoConfiguration. To use jOOQ with R2DBC, define your own "
|
||||||
|
+ "jOOQ configuration.",
|
||||||
|
cause);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasR2dbcAutoConfiguration() {
|
||||||
|
try {
|
||||||
|
this.beanFactory.getBean(R2dbcAutoConfiguration.class);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||||
|
this.beanFactory = beanFactory;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import org.jooq.Transaction;
|
||||||
|
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapts a Spring transaction for JOOQ.
|
||||||
|
*
|
||||||
|
* @author Lukas Eder
|
||||||
|
* @author Andreas Ahlenstorf
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
class SpringTransaction implements Transaction {
|
||||||
|
|
||||||
|
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
|
||||||
|
|
||||||
|
private final TransactionStatus transactionStatus;
|
||||||
|
|
||||||
|
SpringTransaction(TransactionStatus transactionStatus) {
|
||||||
|
this.transactionStatus = transactionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionStatus getTxStatus() {
|
||||||
|
return this.transactionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import org.jooq.TransactionContext;
|
||||||
|
import org.jooq.TransactionProvider;
|
||||||
|
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows Spring Transaction to be used with JOOQ.
|
||||||
|
*
|
||||||
|
* @author Lukas Eder
|
||||||
|
* @author Andreas Ahlenstorf
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.5.10
|
||||||
|
*/
|
||||||
|
public class SpringTransactionProvider implements TransactionProvider {
|
||||||
|
|
||||||
|
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
|
||||||
|
|
||||||
|
private final PlatformTransactionManager transactionManager;
|
||||||
|
|
||||||
|
public SpringTransactionProvider(PlatformTransactionManager transactionManager) {
|
||||||
|
this.transactionManager = transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void begin(TransactionContext context) {
|
||||||
|
TransactionDefinition definition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NESTED);
|
||||||
|
TransactionStatus status = this.transactionManager.getTransaction(definition);
|
||||||
|
context.transaction(new SpringTransaction(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commit(TransactionContext ctx) {
|
||||||
|
this.transactionManager.commit(getTransactionStatus(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rollback(TransactionContext ctx) {
|
||||||
|
this.transactionManager.rollback(getTransactionStatus(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransactionStatus getTransactionStatus(TransactionContext ctx) {
|
||||||
|
SpringTransaction transaction = (SpringTransaction) ctx.transaction();
|
||||||
|
return transaction.getTxStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.jooq.tools.jdbc.JDBCUtils;
|
||||||
|
|
||||||
|
import org.springframework.jdbc.support.JdbcUtils;
|
||||||
|
import org.springframework.jdbc.support.MetaDataAccessException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility to lookup well known {@link SQLDialect SQLDialects} from a {@link DataSource}.
|
||||||
|
*
|
||||||
|
* @author Michael Simons
|
||||||
|
* @author Lukas Eder
|
||||||
|
*/
|
||||||
|
final class SqlDialectLookup {
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(SqlDialectLookup.class);
|
||||||
|
|
||||||
|
private SqlDialectLookup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the most suitable {@link SQLDialect} for the given {@link DataSource}.
|
||||||
|
* @param dataSource the source {@link DataSource}
|
||||||
|
* @return the most suitable {@link SQLDialect}
|
||||||
|
*/
|
||||||
|
static SQLDialect getDialect(DataSource dataSource) {
|
||||||
|
if (dataSource == null) {
|
||||||
|
return SQLDialect.DEFAULT;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String url = JdbcUtils.extractDatabaseMetaData(dataSource, DatabaseMetaData::getURL);
|
||||||
|
SQLDialect sqlDialect = JDBCUtils.dialect(url);
|
||||||
|
if (sqlDialect != null) {
|
||||||
|
return sqlDialect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MetaDataAccessException ex) {
|
||||||
|
logger.warn("Unable to determine jdbc url from datasource", ex);
|
||||||
|
}
|
||||||
|
return SQLDialect.DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for JOOQ.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.autoconfigure.jooq;
|
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.CharsetProvider;
|
||||||
|
import org.jooq.ConnectionProvider;
|
||||||
|
import org.jooq.ConverterProvider;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.ExecuteListener;
|
||||||
|
import org.jooq.ExecuteListenerProvider;
|
||||||
|
import org.jooq.ExecutorProvider;
|
||||||
|
import org.jooq.RecordListenerProvider;
|
||||||
|
import org.jooq.RecordMapperProvider;
|
||||||
|
import org.jooq.RecordUnmapperProvider;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.jooq.TransactionListenerProvider;
|
||||||
|
import org.jooq.TransactionalRunnable;
|
||||||
|
import org.jooq.VisitListenerProvider;
|
||||||
|
import org.jooq.impl.DataSourceConnectionProvider;
|
||||||
|
import org.jooq.impl.DefaultExecuteListenerProvider;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
|
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link JooqAutoConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Andreas Ahlenstorf
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @author Dmytro Nosan
|
||||||
|
*/
|
||||||
|
class JooqAutoConfigurationTests {
|
||||||
|
|
||||||
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class))
|
||||||
|
.withPropertyValues("spring.datasource.name:jooqtest");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noDataSource() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context.getBeansOfType(DSLContext.class)).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jooqWithoutTx() {
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class).run((context) -> {
|
||||||
|
assertThat(context).doesNotHaveBean(PlatformTransactionManager.class);
|
||||||
|
assertThat(context).doesNotHaveBean(SpringTransactionProvider.class);
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
dsl.execute("create table jooqtest (name varchar(255) primary key);");
|
||||||
|
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;", "0"));
|
||||||
|
dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest (name) values ('foo');"));
|
||||||
|
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;", "1"));
|
||||||
|
assertThatExceptionOfType(DataIntegrityViolationException.class)
|
||||||
|
.isThrownBy(() -> dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest (name) values ('bar');",
|
||||||
|
"insert into jooqtest (name) values ('foo');")));
|
||||||
|
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;", "2"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jooqWithTx() {
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class, TxManagerConfiguration.class)
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(PlatformTransactionManager.class);
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
assertThat(dsl.configuration().dialect()).isEqualTo(SQLDialect.HSQLDB);
|
||||||
|
dsl.execute("create table jooqtest_tx (name varchar(255) primary key);");
|
||||||
|
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest_tx;", "0"));
|
||||||
|
dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest_tx (name) values ('foo');"));
|
||||||
|
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest_tx;", "1"));
|
||||||
|
assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
|
||||||
|
() -> dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest (name) values ('bar');",
|
||||||
|
"insert into jooqtest (name) values ('foo');")));
|
||||||
|
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest_tx;", "1"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jooqWithDefaultConnectionProvider() {
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class).run((context) -> {
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
ConnectionProvider connectionProvider = dsl.configuration().connectionProvider();
|
||||||
|
assertThat(connectionProvider).isInstanceOf(DataSourceConnectionProvider.class);
|
||||||
|
DataSource connectionProviderDataSource = ((DataSourceConnectionProvider) connectionProvider).dataSource();
|
||||||
|
assertThat(connectionProviderDataSource).isInstanceOf(TransactionAwareDataSourceProxy.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jooqWithDefaultExecuteListenerProvider() {
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class).run((context) -> {
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
assertThat(dsl.configuration().executeListenerProviders()).hasSize(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jooqWithSeveralExecuteListenerProviders() {
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class, TestExecuteListenerProvider.class)
|
||||||
|
.run((context) -> {
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
ExecuteListenerProvider[] executeListenerProviders = dsl.configuration().executeListenerProviders();
|
||||||
|
assertThat(executeListenerProviders).hasSize(2);
|
||||||
|
assertThat(executeListenerProviders[0]).isInstanceOf(DefaultExecuteListenerProvider.class);
|
||||||
|
assertThat(executeListenerProviders[1]).isInstanceOf(TestExecuteListenerProvider.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void dslContextWithConfigurationCustomizersAreApplied() {
|
||||||
|
ConverterProvider converterProvider = mock(ConverterProvider.class);
|
||||||
|
CharsetProvider charsetProvider = mock(CharsetProvider.class);
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class)
|
||||||
|
.withBean("configurationCustomizer1", DefaultConfigurationCustomizer.class,
|
||||||
|
() -> (configuration) -> configuration.set(converterProvider))
|
||||||
|
.withBean("configurationCustomizer2", DefaultConfigurationCustomizer.class,
|
||||||
|
() -> (configuration) -> configuration.set(charsetProvider))
|
||||||
|
.run((context) -> {
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
assertThat(dsl.configuration().converterProvider()).isSameAs(converterProvider);
|
||||||
|
assertThat(dsl.configuration().charsetProvider()).isSameAs(charsetProvider);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Deprecated
|
||||||
|
void customProvidersArePickedUp() {
|
||||||
|
RecordMapperProvider recordMapperProvider = mock(RecordMapperProvider.class);
|
||||||
|
RecordUnmapperProvider recordUnmapperProvider = mock(RecordUnmapperProvider.class);
|
||||||
|
RecordListenerProvider recordListenerProvider = mock(RecordListenerProvider.class);
|
||||||
|
VisitListenerProvider visitListenerProvider = mock(VisitListenerProvider.class);
|
||||||
|
TransactionListenerProvider transactionListenerProvider = mock(TransactionListenerProvider.class);
|
||||||
|
ExecutorProvider executorProvider = mock(ExecutorProvider.class);
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class, TxManagerConfiguration.class)
|
||||||
|
.withBean(RecordMapperProvider.class, () -> recordMapperProvider)
|
||||||
|
.withBean(RecordUnmapperProvider.class, () -> recordUnmapperProvider)
|
||||||
|
.withBean(RecordListenerProvider.class, () -> recordListenerProvider)
|
||||||
|
.withBean(VisitListenerProvider.class, () -> visitListenerProvider)
|
||||||
|
.withBean(TransactionListenerProvider.class, () -> transactionListenerProvider)
|
||||||
|
.withBean(ExecutorProvider.class, () -> executorProvider).run((context) -> {
|
||||||
|
DSLContext dsl = context.getBean(DSLContext.class);
|
||||||
|
assertThat(dsl.configuration().recordMapperProvider()).isSameAs(recordMapperProvider);
|
||||||
|
assertThat(dsl.configuration().recordUnmapperProvider()).isSameAs(recordUnmapperProvider);
|
||||||
|
assertThat(dsl.configuration().executorProvider()).isSameAs(executorProvider);
|
||||||
|
assertThat(dsl.configuration().recordListenerProviders()).containsExactly(recordListenerProvider);
|
||||||
|
assertThat(dsl.configuration().visitListenerProviders()).containsExactly(visitListenerProvider);
|
||||||
|
assertThat(dsl.configuration().transactionListenerProviders())
|
||||||
|
.containsExactly(transactionListenerProvider);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void relaxedBindingOfSqlDialect() {
|
||||||
|
this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class)
|
||||||
|
.withPropertyValues("spring.jooq.sql-dialect:PoSTGrES")
|
||||||
|
.run((context) -> assertThat(context.getBean(org.jooq.Configuration.class).dialect())
|
||||||
|
.isEqualTo(SQLDialect.POSTGRES));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AssertFetch implements TransactionalRunnable {
|
||||||
|
|
||||||
|
private final DSLContext dsl;
|
||||||
|
|
||||||
|
private final String sql;
|
||||||
|
|
||||||
|
private final String expected;
|
||||||
|
|
||||||
|
AssertFetch(DSLContext dsl, String sql, String expected) {
|
||||||
|
this.dsl = dsl;
|
||||||
|
this.sql = sql;
|
||||||
|
this.expected = expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(org.jooq.Configuration configuration) {
|
||||||
|
assertThat(this.dsl.fetch(this.sql).getValue(0, 0).toString()).isEqualTo(this.expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ExecuteSql implements TransactionalRunnable {
|
||||||
|
|
||||||
|
private final DSLContext dsl;
|
||||||
|
|
||||||
|
private final String[] sql;
|
||||||
|
|
||||||
|
ExecuteSql(DSLContext dsl, String... sql) {
|
||||||
|
this.dsl = dsl;
|
||||||
|
this.sql = sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(org.jooq.Configuration configuration) {
|
||||||
|
for (String statement : this.sql) {
|
||||||
|
this.dsl.execute(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class JooqDataSourceConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
DataSource jooqDataSource() {
|
||||||
|
return DataSourceBuilder.create().url("jdbc:hsqldb:mem:jooqtest").username("sa").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class TxManagerConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
PlatformTransactionManager transactionManager(DataSource dataSource) {
|
||||||
|
return new DataSourceTransactionManager(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Order(100)
|
||||||
|
static class TestExecuteListenerProvider implements ExecuteListenerProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecuteListener provide() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.jooq.Configuration;
|
||||||
|
import org.jooq.ExecuteContext;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
|
import org.springframework.jdbc.BadSqlGrammarException;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link JooqExceptionTranslator}
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
class JooqExceptionTranslatorTests {
|
||||||
|
|
||||||
|
private final JooqExceptionTranslator exceptionTranslator = new JooqExceptionTranslator();
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}")
|
||||||
|
@MethodSource
|
||||||
|
void exceptionTranslation(SQLDialect dialect, SQLException sqlException) {
|
||||||
|
ExecuteContext context = mock(ExecuteContext.class);
|
||||||
|
Configuration configuration = mock(Configuration.class);
|
||||||
|
given(context.configuration()).willReturn(configuration);
|
||||||
|
given(configuration.dialect()).willReturn(dialect);
|
||||||
|
given(context.sqlException()).willReturn(sqlException);
|
||||||
|
this.exceptionTranslator.exception(context);
|
||||||
|
ArgumentCaptor<RuntimeException> captor = ArgumentCaptor.forClass(RuntimeException.class);
|
||||||
|
verify(context).exception(captor.capture());
|
||||||
|
assertThat(captor.getValue()).isInstanceOf(BadSqlGrammarException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenExceptionCannotBeTranslatedThenExecuteContextExceptionIsNotCalled() {
|
||||||
|
ExecuteContext context = mock(ExecuteContext.class);
|
||||||
|
Configuration configuration = mock(Configuration.class);
|
||||||
|
given(context.configuration()).willReturn(configuration);
|
||||||
|
given(configuration.dialect()).willReturn(SQLDialect.POSTGRES);
|
||||||
|
given(context.sqlException()).willReturn(new SQLException(null, null, 123456789));
|
||||||
|
this.exceptionTranslator.exception(context);
|
||||||
|
verify(context, times(0)).exception(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object[] exceptionTranslation() {
|
||||||
|
return new Object[] { new Object[] { SQLDialect.DERBY, sqlException("42802") },
|
||||||
|
new Object[] { SQLDialect.H2, sqlException(42000) },
|
||||||
|
new Object[] { SQLDialect.HSQLDB, sqlException(-22) },
|
||||||
|
new Object[] { SQLDialect.MARIADB, sqlException(1054) },
|
||||||
|
new Object[] { SQLDialect.MYSQL, sqlException(1054) },
|
||||||
|
new Object[] { SQLDialect.POSTGRES, sqlException("03000") },
|
||||||
|
new Object[] { SQLDialect.SQLITE, sqlException("21000") } };
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SQLException sqlException(String sqlState) {
|
||||||
|
return new SQLException(null, sqlState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SQLException sqlException(int vendorCode) {
|
||||||
|
return new SQLException(null, null, vendorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.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
|
||||||
|
*/
|
||||||
|
class JooqPropertiesTests {
|
||||||
|
|
||||||
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void close() {
|
||||||
|
if (this.context != null) {
|
||||||
|
this.context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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
|
||||||
|
void determineSqlDialectWithKnownUrl() {
|
||||||
|
JooqProperties properties = load();
|
||||||
|
SQLDialect sqlDialect = properties.determineSqlDialect(mockDataSource("jdbc:h2:mem:testdb"));
|
||||||
|
assertThat(sqlDialect).isEqualTo(SQLDialect.H2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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
|
||||||
|
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 ex) {
|
||||||
|
// 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(proxyBeanMethods = false)
|
||||||
|
@EnableConfigurationProperties(JooqProperties.class)
|
||||||
|
static class TestConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link NoDslContextBeanFailureAnalyzer}.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
class NoDslContextBeanFailureAnalyzerTests {
|
||||||
|
|
||||||
|
private final NoDslContextBeanFailureAnalyzer failureAnalyzer = new NoDslContextBeanFailureAnalyzer();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noAnalysisWithoutR2dbcAutoConfiguration() {
|
||||||
|
new ApplicationContextRunner().run((context) -> {
|
||||||
|
this.failureAnalyzer.setBeanFactory(context.getBeanFactory());
|
||||||
|
assertThat(this.failureAnalyzer.analyze(new NoSuchBeanDefinitionException(DSLContext.class))).isNull();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void analysisWithR2dbcAutoConfiguration() {
|
||||||
|
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class))
|
||||||
|
.run((context) -> {
|
||||||
|
this.failureAnalyzer.setBeanFactory(context.getBeanFactory());
|
||||||
|
assertThat(this.failureAnalyzer.analyze(new NoSuchBeanDefinitionException(DSLContext.class)))
|
||||||
|
.isNotNull();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.junit.jupiter.api.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
|
||||||
|
*/
|
||||||
|
class SqlDialectLookupTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenDataSourceIsNullShouldReturnDefault() {
|
||||||
|
assertThat(SqlDialectLookup.getDialect(null)).isEqualTo(SQLDialect.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenDataSourceIsUnknownShouldReturnDefault() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:idontexist:", SQLDialect.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenDerbyShouldReturnDerby() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:derby:", SQLDialect.DERBY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenH2ShouldReturnH2() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:h2:", SQLDialect.H2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenHsqldbShouldReturnHsqldb() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:hsqldb:", SQLDialect.HSQLDB);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenMysqlShouldReturnMysql() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:mysql:", SQLDialect.MYSQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenOracleShouldReturnDefault() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:oracle:", SQLDialect.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenPostgresShouldReturnPostgres() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:postgresql:", SQLDialect.POSTGRES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenSqlserverShouldReturnDefault() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:sqlserver:", SQLDialect.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenDb2ShouldReturnDefault() throws Exception {
|
||||||
|
testGetSqlDialect("jdbc:db2:", SQLDialect.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSqlDialectWhenInformixShouldReturnDefault() 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.docs.data.sql.jooq.dslcontext;
|
||||||
|
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static org.springframework.boot.docs.data.sql.jooq.dslcontext.Tables.AUTHOR;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MyBean {
|
||||||
|
|
||||||
|
private final DSLContext create;
|
||||||
|
|
||||||
|
public MyBean(DSLContext dslContext) {
|
||||||
|
this.create = dslContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tag::method[]
|
||||||
|
public List<GregorianCalendar> authorsBornAfter1980() {
|
||||||
|
// @formatter:off
|
||||||
|
return this.create.selectFrom(AUTHOR)
|
||||||
|
.where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
|
||||||
|
.fetch(AUTHOR.DATE_OF_BIRTH);
|
||||||
|
// @formatter:on
|
||||||
|
} // end::method[]
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.docs.data.sql.jooq.dslcontext;
|
||||||
|
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
import org.jooq.Name;
|
||||||
|
import org.jooq.Table;
|
||||||
|
import org.jooq.TableField;
|
||||||
|
import org.jooq.impl.TableImpl;
|
||||||
|
import org.jooq.impl.TableRecordImpl;
|
||||||
|
|
||||||
|
abstract class Tables {
|
||||||
|
|
||||||
|
static final TAuthor AUTHOR = null;
|
||||||
|
|
||||||
|
abstract class TAuthor extends TableImpl<TAuthorRecord> {
|
||||||
|
|
||||||
|
TAuthor(Name name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final TableField<TAuthorRecord, GregorianCalendar> DATE_OF_BIRTH = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TAuthorRecord extends TableRecordImpl<TAuthorRecord> {
|
||||||
|
|
||||||
|
TAuthorRecord(Table<TAuthorRecord> table) {
|
||||||
|
super(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.autoconfiguredjooq;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.jooq.JooqTest;
|
||||||
|
|
||||||
|
@JooqTest
|
||||||
|
class MyJooqTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private DSLContext dslContext;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.springframework.boot.starter"
|
||||||
|
}
|
||||||
|
|
||||||
|
description = "Starter for using jOOQ to access SQL databases with JDBC. An alternative to spring-boot-starter-data-jpa or spring-boot-starter-jdbc"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc"))
|
||||||
|
api("org.springframework:spring-tx")
|
||||||
|
api("org.jooq:jooq")
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ImportAutoConfiguration Auto-configuration imports} for typical jOOQ tests. Most
|
||||||
|
* tests should consider using {@link JooqTest @JooqTest} rather than using this
|
||||||
|
* annotation directly.
|
||||||
|
*
|
||||||
|
* @author Michael Simons
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
@ImportAutoConfiguration
|
||||||
|
public @interface AutoConfigureJooq {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
|
||||||
|
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
|
||||||
|
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
||||||
|
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||||
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.test.context.BootstrapWith;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation for a jOOQ test that focuses <strong>only</strong> on jOOQ-based components.
|
||||||
|
* <p>
|
||||||
|
* Using this annotation will disable full auto-configuration and instead apply only
|
||||||
|
* configuration relevant to jOOQ tests.
|
||||||
|
* <p>
|
||||||
|
* By default, tests annotated with {@code @JooqTest} use the configured database. If you
|
||||||
|
* want to replace any explicit or usually auto-configured DataSource by an embedded
|
||||||
|
* in-memory database, the {@link AutoConfigureTestDatabase @AutoConfigureTestDatabase}
|
||||||
|
* annotation can be used to override these settings.
|
||||||
|
* <p>
|
||||||
|
* When using JUnit 4, this annotation should be used in combination with
|
||||||
|
* {@code @RunWith(SpringRunner.class)}.
|
||||||
|
*
|
||||||
|
* @author Michael Simons
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @author Artsiom Yudovin
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
@BootstrapWith(JooqTestContextBootstrapper.class)
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@OverrideAutoConfiguration(enabled = false)
|
||||||
|
@TypeExcludeFilters(JooqTypeExcludeFilter.class)
|
||||||
|
@Transactional
|
||||||
|
@AutoConfigureCache
|
||||||
|
@AutoConfigureJooq
|
||||||
|
@ImportAutoConfiguration
|
||||||
|
public @interface JooqTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties in form {@literal key=value} that should be added to the Spring
|
||||||
|
* {@link Environment} before the test runs.
|
||||||
|
* @return the properties to add
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
String[] properties() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if default filtering should be used with
|
||||||
|
* {@link SpringBootApplication @SpringBootApplication}. By default no beans are
|
||||||
|
* included.
|
||||||
|
* @see #includeFilters()
|
||||||
|
* @see #excludeFilters()
|
||||||
|
* @return if default filters should be used
|
||||||
|
*/
|
||||||
|
boolean useDefaultFilters() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of include filters which can be used to add otherwise filtered beans to the
|
||||||
|
* application context.
|
||||||
|
* @return include filters to apply
|
||||||
|
*/
|
||||||
|
Filter[] includeFilters() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of exclude filters which can be used to filter beans that would otherwise be
|
||||||
|
* added to the application context.
|
||||||
|
* @return exclude filters to apply
|
||||||
|
*/
|
||||||
|
Filter[] excludeFilters() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration exclusions that should be applied for this test.
|
||||||
|
* @return auto-configuration exclusions to apply
|
||||||
|
*/
|
||||||
|
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
|
||||||
|
Class<?>[] excludeAutoConfiguration() default {};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
|
||||||
|
import org.springframework.core.annotation.MergedAnnotations;
|
||||||
|
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||||
|
import org.springframework.test.context.TestContextBootstrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TestContextBootstrapper} for {@link JooqTest @JooqTest} support.
|
||||||
|
*
|
||||||
|
* @author Artsiom Yudovin
|
||||||
|
*/
|
||||||
|
class JooqTestContextBootstrapper extends SpringBootTestContextBootstrapper {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getProperties(Class<?> testClass) {
|
||||||
|
return MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS).get(JooqTest.class)
|
||||||
|
.getValue("properties", String[].class).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.TypeExcludeFilter;
|
||||||
|
import org.springframework.boot.test.autoconfigure.filter.StandardAnnotationCustomizableTypeExcludeFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TypeExcludeFilter} for {@link JooqTest @JooqTest}.
|
||||||
|
*
|
||||||
|
* @author Michael Simons
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public final class JooqTypeExcludeFilter extends StandardAnnotationCustomizableTypeExcludeFilter<JooqTest> {
|
||||||
|
|
||||||
|
JooqTypeExcludeFilter(Class<?> testClass) {
|
||||||
|
super(testClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for jOOQ tests.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.test.autoconfigure.jooq;
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example {@link SpringBootApplication @SpringBootApplication} used with
|
||||||
|
* {@link JooqTest @JooqTest} tests.
|
||||||
|
*
|
||||||
|
* @author Michael Simons
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ExampleJooqApplication {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
return new EmbeddedDatabaseBuilder().generateUniqueName(true).setType(EmbeddedDatabaseType.HSQL).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.orm.jpa.ExampleComponent;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
import static org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.importedAutoConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link JooqTest @JooqTest}.
|
||||||
|
*
|
||||||
|
* @author Michael Simons
|
||||||
|
*/
|
||||||
|
@JooqTest
|
||||||
|
class JooqTestIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext dsl;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDSLContext() {
|
||||||
|
assertThat(this.dsl.selectCount().from("INFORMATION_SCHEMA.TABLES").fetchOne(0, Integer.class))
|
||||||
|
.isGreaterThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void useDefinedDataSource() throws Exception {
|
||||||
|
String product = this.dataSource.getConnection().getMetaData().getDatabaseProductName();
|
||||||
|
assertThat(product).startsWith("HSQL");
|
||||||
|
assertThat(this.dsl.configuration().dialect()).isEqualTo(SQLDialect.HSQLDB);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void didNotInjectExampleComponent() {
|
||||||
|
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||||
|
.isThrownBy(() -> this.applicationContext.getBean(ExampleComponent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void flywayAutoConfigurationWasImported() {
|
||||||
|
assertThat(this.applicationContext).has(importedAutoConfiguration(FlywayAutoConfiguration.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void liquibaseAutoConfigurationWasImported() {
|
||||||
|
assertThat(this.applicationContext).has(importedAutoConfiguration(LiquibaseAutoConfiguration.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void cacheAutoConfigurationWasImported() {
|
||||||
|
assertThat(this.applicationContext).has(importedAutoConfiguration(CacheAutoConfiguration.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the {@link JooqTest#properties properties} attribute of
|
||||||
|
* {@link JooqTest @JooqTest}.
|
||||||
|
*
|
||||||
|
* @author Artsiom Yudovin
|
||||||
|
*/
|
||||||
|
@JooqTest(properties = "spring.profiles.active=test")
|
||||||
|
class JooqTestPropertiesIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void environmentWithNewProfile() {
|
||||||
|
assertThat(this.environment.getActiveProfiles()).containsExactly("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.test.autoconfigure.jooq;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.SQLDialect;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||||
|
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link JooqTest @JooqTest}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
@JooqTest
|
||||||
|
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
|
||||||
|
class JooqTestWithAutoConfigureTestDatabaseIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext dsl;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void replacesAutoConfiguredDataSource() throws Exception {
|
||||||
|
String product = this.dataSource.getConnection().getMetaData().getDatabaseProductName();
|
||||||
|
assertThat(product).startsWith("H2");
|
||||||
|
assertThat(this.dsl.configuration().dialect()).isEqualTo(SQLDialect.H2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.jooq;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
|
||||||
|
import org.springframework.boot.sql.init.dependency.AbstractBeansOfTypeDependsOnDatabaseInitializationDetector;
|
||||||
|
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link DependsOnDatabaseInitializationDetector} for jOOQ.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
class JooqDependsOnDatabaseInitializationDetector extends AbstractBeansOfTypeDependsOnDatabaseInitializationDetector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<Class<?>> getDependsOnDatabaseInitializationBeanTypes() {
|
||||||
|
return Collections.singleton(DSLContext.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for jOOQ.
|
||||||
|
*
|
||||||
|
* @see org.springframework.boot.json.JsonParser
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.jooq;
|
Loading…
Reference in New Issue