diff --git a/jOOQ/src/main/java/org/jooq/AttachableQueryPart.java b/jOOQ/src/main/java/org/jooq/AttachableQueryPart.java
new file mode 100644
index 0000000000..177674d9a6
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/AttachableQueryPart.java
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ *
+ * Other licenses:
+ * -----------------------------------------------------------------------------
+ * Commercial licenses for this work are available. These replace the above
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: http://www.jooq.org/licenses
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq;
+
+import java.sql.PreparedStatement;
+import java.util.List;
+import java.util.Map;
+
+import org.jooq.conf.ParamType;
+import org.jooq.conf.Settings;
+import org.jooq.conf.StatementType;
+import org.jooq.impl.DSL;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A type that is both {@link Attachable} and a {@link QueryPart}.
+ *
+ * In addition to being able to render SQL of possibly some unspecified dialect
+ * and with inlined bind values for debugging purposes via the
+ * {@link QueryPart#toString()} method, this type offers more fine-grained
+ * control over the SQL generation via {@link ParamType},
+ * {@link Configuration#dialect()} and various {@link Configuration#settings()}.
+ *
+ * @author Lukas Eder
+ */
+public interface AttachableQueryPart extends Attachable, QueryPart {
+
+ /**
+ * Retrieve the SQL code rendered by this Query.
+ *
+ * Use this method, when you want to use jOOQ for object oriented query
+ * creation, but execute the query with some other technology, such as
+ *
+ * JDBC
+ * Spring Templates
+ * JPA native queries
+ * etc...
+ *
+ *
+ * Note, this is the same as calling {@link #getSQL(ParamType)}. The
+ * parameter will depend on your {@link DSLContext}'s {@link Settings}:
+ *
+ *
+ * StatementType
+ * boolean parameter
+ * effect
+ *
+ *
+ * {@link StatementType#PREPARED_STATEMENT}
+ * false (default)
+ * This will render bind variables to be used with a JDBC
+ * {@link PreparedStatement}. You can extract bind values from this
+ * Query using {@link #getBindValues()}
+ *
+ *
+ * {@link StatementType#STATIC_STATEMENT}
+ * true
+ * This will inline all bind variables in a statement to be used with a
+ * JDBC {@link Statement}
+ *
+ *
+ *
+ * [#1520] Note that the query actually being executed might not contain any
+ * bind variables, in case the number of bind variables exceeds your SQL
+ * dialect's maximum number of supported bind variables. This is not
+ * reflected by this method, which will only use the {@link Settings} to
+ * decide whether to render bind values.
+ *
+ * @see #getSQL(ParamType)
+ */
+ @NotNull
+ String getSQL();
+
+ /**
+ * Retrieve the SQL code rendered by this Query.
+ *
+ * [#1520] Note that the query actually being executed might not contain any
+ * bind variables, in case the number of bind variables exceeds your SQL
+ * dialect's maximum number of supported bind variables. This is not
+ * reflected by this method, which will only use paramType
+ * argument to decide whether to render bind values.
+ *
+ * See {@link #getSQL()} for more details.
+ *
+ * @param paramType How to render parameters. This overrides values in
+ * {@link Settings#getStatementType()}
+ * @return The generated SQL
+ */
+ @NotNull
+ String getSQL(ParamType paramType);
+
+ /**
+ * Retrieve the bind values that will be bound by this Query.
+ *
+ * Unlike {@link #getParams()}, which returns also inlined parameters, this
+ * returns only actual bind values that will render an actual bind value as
+ * a question mark "?"
+ *
+ * @see DSLContext#extractBindValues(QueryPart)
+ */
+ @NotNull
+ List getBindValues();
+
+ /**
+ * Get a Map of named parameters. The Map itself
+ * cannot be modified, but the {@link Param} elements allow for modifying
+ * bind values on an existing {@link Query}.
+ *
+ * Bind values created with {@link DSL#val(Object)} will have their bind
+ * index as name.
+ *
+ * @see Param
+ * @see DSL#param(String, Object)
+ * @see DSLContext#extractParams(QueryPart)
+ */
+ @NotNull
+ Map> getParams();
+
+ /**
+ * Get a named parameter from the {@link Query}, provided its name.
+ *
+ * Bind values created with {@link DSL#val(Object)} will have their bind
+ * index as name.
+ *
+ * @see Param
+ * @see DSL#param(String, Object)
+ * @see DSLContext#extractParam(QueryPart, String)
+ */
+ @Nullable
+ Param> getParam(String name);
+
+}
diff --git a/jOOQ/src/main/java/org/jooq/Queries.java b/jOOQ/src/main/java/org/jooq/Queries.java
index 278d8868d6..06952554b6 100644
--- a/jOOQ/src/main/java/org/jooq/Queries.java
+++ b/jOOQ/src/main/java/org/jooq/Queries.java
@@ -52,7 +52,7 @@ import org.jetbrains.annotations.NotNull;
*
* @author Lukas Eder
*/
-public interface Queries extends QueryPart, Attachable, Iterable {
+public interface Queries extends AttachableQueryPart, Iterable {
// ------------------------------------------------------------------------
// Access API
diff --git a/jOOQ/src/main/java/org/jooq/Query.java b/jOOQ/src/main/java/org/jooq/Query.java
index 9ee09c4159..a7bc2627d3 100644
--- a/jOOQ/src/main/java/org/jooq/Query.java
+++ b/jOOQ/src/main/java/org/jooq/Query.java
@@ -39,20 +39,15 @@
package org.jooq;
import java.sql.PreparedStatement;
-import java.util.List;
-import java.util.Map;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
-import org.jooq.conf.ParamType;
-import org.jooq.conf.Settings;
import org.jooq.conf.StatementType;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.DataTypeException;
import org.jooq.impl.DSL;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* Any query.
@@ -62,7 +57,7 @@ import org.jetbrains.annotations.Nullable;
*
* @author Lukas Eder
*/
-public interface Query extends Statement, Attachable, AutoCloseable {
+public interface Query extends Statement, AttachableQueryPart, AutoCloseable {
/**
* Execute the query, if it has been created with a proper configuration.
@@ -129,112 +124,6 @@ public interface Query extends Statement, Attachable, AutoCloseable {
*/
boolean isExecutable();
- /**
- * Retrieve the SQL code rendered by this Query.
- *
- * Use this method, when you want to use jOOQ for object oriented query
- * creation, but execute the query with some other technology, such as
- *
- * JDBC
- * Spring Templates
- * JPA native queries
- * etc...
- *
- *
- * Note, this is the same as calling {@link #getSQL(boolean)}. The boolean
- * parameter will depend on your {@link DSLContext}'s {@link Settings}:
- *
- *
- * StatementType
- * boolean parameter
- * effect
- *
- *
- * {@link StatementType#PREPARED_STATEMENT}
- * false (default)
- * This will render bind variables to be used with a JDBC
- * {@link PreparedStatement}. You can extract bind values from this
- * Query using {@link #getBindValues()}
- *
- *
- * {@link StatementType#STATIC_STATEMENT}
- * true
- * This will inline all bind variables in a statement to be used with a
- * JDBC {@link Statement}
- *
- *
- *
- * [#1520] Note that the query actually being executed might not contain any
- * bind variables, in case the number of bind variables exceeds your SQL
- * dialect's maximum number of supported bind variables. This is not
- * reflected by this method, which will only use the {@link Settings} to
- * decide whether to render bind values.
- *
- * @see #getSQL(boolean)
- */
- @NotNull
- String getSQL();
-
- /**
- * Retrieve the SQL code rendered by this Query.
- *
- * [#1520] Note that the query actually being executed might not contain any
- * bind variables, in case the number of bind variables exceeds your SQL
- * dialect's maximum number of supported bind variables. This is not
- * reflected by this method, which will only use paramType
- * argument to decide whether to render bind values.
- *
- * See {@link #getSQL()} for more details.
- *
- * @param paramType How to render parameters. This overrides values in
- * {@link Settings#getStatementType()}
- * @return The generated SQL
- */
- @NotNull
- String getSQL(ParamType paramType);
-
- /**
- * Retrieve the bind values that will be bound by this Query. This
- * List cannot be modified. To modify bind values, use
- * {@link #getParams()} instead.
- *
- * Unlike {@link #getParams()}, which returns also inlined parameters, this
- * returns only actual bind values that will render an actual bind value as
- * a question mark "?"
- *
- * @see DSLContext#extractBindValues(QueryPart)
- */
- @NotNull
- List getBindValues();
-
- /**
- * Get a Map of named parameters. The Map itself
- * cannot be modified, but the {@link Param} elements allow for modifying
- * bind values on an existing {@link Query}.
- *
- * Bind values created with {@link DSL#val(Object)} will have their bind
- * index as name.
- *
- * @see Param
- * @see DSL#param(String, Object)
- * @see DSLContext#extractParams(QueryPart)
- */
- @NotNull
- Map> getParams();
-
- /**
- * Get a named parameter from the {@link Query}, provided its name.
- *
- * Bind values created with {@link DSL#val(Object)} will have their bind
- * index as name.
- *
- * @see Param
- * @see DSL#param(String, Object)
- * @see DSLContext#extractParam(QueryPart, String)
- */
- @Nullable
- Param> getParam(String name);
-
/**
* Bind a new value to a named parameter.
*
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractAttachableQueryPart.java b/jOOQ/src/main/java/org/jooq/impl/AbstractAttachableQueryPart.java
new file mode 100644
index 0000000000..ef89bd3223
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractAttachableQueryPart.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ *
+ * Other licenses:
+ * -----------------------------------------------------------------------------
+ * Commercial licenses for this work are available. These replace the above
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: http://www.jooq.org/licenses
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package org.jooq.impl;
+
+import static org.jooq.conf.SettingsTools.getParamType;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jooq.AttachableQueryPart;
+import org.jooq.Configuration;
+import org.jooq.Param;
+import org.jooq.conf.ParamType;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Lukas Eder
+ */
+abstract class AbstractAttachableQueryPart extends AbstractQueryPart implements AttachableQueryPart {
+
+ private static final long serialVersionUID = -8046199737354507547L;
+
+ private Configuration configuration;
+
+ AbstractAttachableQueryPart(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ // -------------------------------------------------------------------------
+ // The Attachable and Attachable internal API
+ // -------------------------------------------------------------------------
+
+ @Override
+ public final void attach(Configuration c) {
+ configuration = c;
+ }
+
+ @Override
+ public final void detach() {
+ attach(null);
+ }
+
+ @Override
+ public final Configuration configuration() {
+ return configuration;
+ }
+
+ @NotNull
+ final Configuration configurationOrDefault() {
+ return Tools.configuration(this);
+ }
+
+ @NotNull
+ final Configuration configurationOrThrow() {
+ return Tools.configurationOrThrow(this);
+ }
+
+ // -------------------------------------------------------------------------
+ // The AttachableQueryPart API
+ // -------------------------------------------------------------------------
+
+ @Override
+ public final List getBindValues() {
+ return create().extractBindValues(this);
+ }
+
+ @Override
+ public final Map> getParams() {
+ return create().extractParams(this);
+ }
+
+ @Override
+ public final Param> getParam(String name) {
+ return create().extractParam(this, name);
+ }
+
+ @Override
+ public final String getSQL() {
+ return getSQL(getParamType(Tools.settings(configuration())));
+ }
+
+ @Override
+ public final String getSQL(ParamType paramType) {
+ switch (paramType) {
+ case INDEXED:
+ return create().render(this);
+ case INLINED:
+ return create().renderInlined(this);
+ case NAMED:
+ return create().renderNamedParams(this);
+ case NAMED_OR_INLINED:
+ return create().renderNamedOrInlinedParams(this);
+ case FORCE_INDEXED:
+ return create().renderContext().paramType(paramType).visit(this).render();
+ }
+
+ throw new IllegalArgumentException("ParamType not supported: " + paramType);
+ }
+}
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
index f6d827bf4a..87e6258bd5 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
@@ -90,12 +90,11 @@ import org.jooq.tools.JooqLogger;
/**
* @author Lukas Eder
*/
-abstract class AbstractQuery extends AbstractQueryPart implements Query {
+abstract class AbstractQuery extends AbstractAttachableQueryPart implements Query {
private static final long serialVersionUID = -8046199737354507547L;
private static final JooqLogger log = JooqLogger.getLogger(AbstractQuery.class);
- private Configuration configuration;
private int timeout;
private QueryPoolable poolable = QueryPoolable.DEFAULT;
private boolean keepStatement;
@@ -104,26 +103,7 @@ abstract class AbstractQuery extends AbstractQueryPart impleme
transient Rendered rendered;
AbstractQuery(Configuration configuration) {
- this.configuration = configuration;
- }
-
- // -------------------------------------------------------------------------
- // The Attachable and Attachable internal API
- // -------------------------------------------------------------------------
-
- @Override
- public final void attach(Configuration c) {
- configuration = c;
- }
-
- @Override
- public final void detach() {
- attach(null);
- }
-
- @Override
- public final Configuration configuration() {
- return configuration;
+ super(configuration);
}
// -------------------------------------------------------------------------
@@ -142,21 +122,6 @@ abstract class AbstractQuery extends AbstractQueryPart impleme
// The Query API
// -------------------------------------------------------------------------
- @Override
- public final List getBindValues() {
- return create().extractBindValues(this);
- }
-
- @Override
- public final Map> getParams() {
- return create().extractParams(this);
- }
-
- @Override
- public final Param> getParam(String name) {
- return create().extractParam(this, name);
- }
-
/**
* Subclasses may override this for covariant result types
*
@@ -492,7 +457,7 @@ abstract class AbstractQuery extends AbstractQueryPart impleme
private final Rendered getSQL0(ExecuteContext ctx) {
Rendered result;
DefaultRenderContext render;
- Configuration c = configuration;
+ Configuration c = configurationOrThrow();
// [#3542] [#4977] Some dialects do not support bind values in DDL statements
// [#6474] [#6929] Can this be communicated in a leaner way?
@@ -574,27 +539,4 @@ abstract class AbstractQuery extends AbstractQueryPart impleme
-
- @Override
- public final String getSQL() {
- return getSQL(getParamType(Tools.settings(configuration())));
- }
-
- @Override
- public final String getSQL(ParamType paramType) {
- switch (paramType) {
- case INDEXED:
- return create().render(this);
- case INLINED:
- return create().renderInlined(this);
- case NAMED:
- return create().renderNamedParams(this);
- case NAMED_OR_INLINED:
- return create().renderNamedOrInlinedParams(this);
- case FORCE_INDEXED:
- return create().renderContext().paramType(paramType).visit(this).render();
- }
-
- throw new IllegalArgumentException("ParamType not supported: " + paramType);
- }
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/QueriesImpl.java b/jOOQ/src/main/java/org/jooq/impl/QueriesImpl.java
index a17efc8ed1..fc2b827518 100644
--- a/jOOQ/src/main/java/org/jooq/impl/QueriesImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/QueriesImpl.java
@@ -56,10 +56,12 @@ import org.jooq.ResultQuery;
import org.jooq.Results;
import org.jooq.impl.ResultsImpl.ResultOrRowsImpl;
+import org.jetbrains.annotations.NotNull;
+
/**
* @author Lukas Eder
*/
-final class QueriesImpl extends AbstractQueryPart implements Queries {
+final class QueriesImpl extends AbstractAttachableQueryPart implements Queries {
/**
* Generated UID
@@ -67,10 +69,10 @@ final class QueriesImpl extends AbstractQueryPart implements Queries {
private static final long serialVersionUID = 261452207127914269L;
private final Collection extends Query> queries;
- private Configuration configuration;
QueriesImpl(Configuration configuration, Collection extends Query> queries) {
- this.configuration = configuration;
+ super(configuration);
+
this.queries = queries;
}
@@ -84,7 +86,7 @@ final class QueriesImpl extends AbstractQueryPart implements Queries {
List list = new ArrayList<>(queries.size() + array.length);
list.addAll(queries);
list.addAll(Arrays.asList(array));
- return new QueriesImpl(configuration, list);
+ return new QueriesImpl(configuration(), list);
}
@Override
@@ -94,7 +96,7 @@ final class QueriesImpl extends AbstractQueryPart implements Queries {
@Override
public final Block block() {
- return configuration.dsl().begin(queries);
+ return configurationOrDefault().dsl().begin(queries);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@@ -120,8 +122,9 @@ final class QueriesImpl extends AbstractQueryPart implements Queries {
@Override
public final Results fetchMany() {
- ResultsImpl results = new ResultsImpl(configuration());
- DSLContext ctx = configuration().dsl();
+ Configuration c = configurationOrThrow();
+ ResultsImpl results = new ResultsImpl(c);
+ DSLContext ctx = c.dsl();
for (Query query : this)
if (query instanceof ResultQuery)
@@ -134,26 +137,7 @@ final class QueriesImpl extends AbstractQueryPart implements Queries {
@Override
public final int[] executeBatch() {
- return configuration().dsl().batch(this).execute();
- }
-
- // ------------------------------------------------------------------------
- // Attachable API
- // ------------------------------------------------------------------------
-
- @Override
- public final void attach(Configuration c) {
- configuration = c;
- }
-
- @Override
- public final void detach() {
- attach(null);
- }
-
- @Override
- public final Configuration configuration() {
- return configuration;
+ return configurationOrThrow().dsl().batch(this).execute();
}
// ------------------------------------------------------------------------
diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java
index 3e165feadb..c6aba7d656 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Tools.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java
@@ -74,10 +74,16 @@ import static org.jooq.conf.ParamType.NAMED_OR_INLINED;
import static org.jooq.conf.RenderDefaultNullability.IMPLICIT_NULL;
import static org.jooq.conf.RenderQuotedNames.EXPLICIT_DEFAULT_QUOTED;
import static org.jooq.conf.SettingsTools.getBackslashEscaping;
-import static org.jooq.conf.SettingsTools.reflectionCaching;
import static org.jooq.conf.SettingsTools.updatablePrimaryKeys;
import static org.jooq.conf.ThrowExceptions.THROW_FIRST;
import static org.jooq.conf.ThrowExceptions.THROW_NONE;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_GETTER;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_MEMBERS;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_SETTERS;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_GETTER;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_MEMBERS;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_SETTERS;
+import static org.jooq.impl.CacheType.REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS;
import static org.jooq.impl.DDLStatementType.ALTER_SCHEMA;
import static org.jooq.impl.DDLStatementType.ALTER_TABLE;
import static org.jooq.impl.DDLStatementType.ALTER_VIEW;
@@ -104,13 +110,6 @@ import static org.jooq.impl.DSL.noCondition;
import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.val;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_GETTER;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_MEMBERS;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_SETTERS;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_GETTER;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_MEMBERS;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_SETTERS;
-import static org.jooq.impl.CacheType.REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS;
import static org.jooq.impl.DefaultExecuteContext.localConnection;
import static org.jooq.impl.DefaultParseContext.SUPPORTS_HASH_COMMENT_SYNTAX;
import static org.jooq.impl.Identifiers.QUOTES;
@@ -291,6 +290,7 @@ import org.jooq.conf.SettingsTools;
import org.jooq.conf.ThrowExceptions;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.DataTypeException;
+import org.jooq.exception.DetachedException;
import org.jooq.exception.MappingException;
import org.jooq.exception.NoDataFoundException;
import org.jooq.exception.TemplatingException;
@@ -1103,10 +1103,14 @@ final class Tools {
}
/**
- * Extract the configuration from an attachable.
+ * Get an attachable's configuration or a new {@link DefaultConfiguration}
+ * if null.
*/
- static final Configuration getConfiguration(Attachable attachable) {
- return attachable.configuration();
+ static final Configuration configurationOrThrow(Attachable attachable) {
+ if (attachable.configuration() == null)
+ throw new DetachedException("No configuration attached: " + attachable);
+ else
+ return configuration(attachable.configuration());
}
/**