diff --git a/jOOQ-test/src/org/jooq/test/_/PrettyPrinter.java b/jOOQ-test/src/org/jooq/test/_/PrettyPrinter.java index 1bc09af67d..ede8785746 100644 --- a/jOOQ-test/src/org/jooq/test/_/PrettyPrinter.java +++ b/jOOQ-test/src/org/jooq/test/_/PrettyPrinter.java @@ -35,6 +35,8 @@ */ package org.jooq.test._; +import static org.jooq.conf.ParamType.INLINED; + import java.util.concurrent.atomic.AtomicInteger; import org.jooq.DSLContext; @@ -84,7 +86,7 @@ public class PrettyPrinter extends DefaultExecuteListener { System.out.println(normal.renderInlined(ctx.query())); System.out.println(); System.out.println(pretty.renderContext() - .inline(true) + .paramType(INLINED) .render(ctx.query())); } @@ -93,7 +95,7 @@ public class PrettyPrinter extends DefaultExecuteListener { System.out.println(normal.renderInlined(ctx.routine())); System.out.println(); System.out.println(pretty.renderContext() - .inline(true) + .paramType(INLINED) .render(ctx.routine())); } diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/BenchmarkTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/BenchmarkTests.java index 698aab0620..6f30b4c901 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/BenchmarkTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/BenchmarkTests.java @@ -35,6 +35,8 @@ */ package org.jooq.test._.testcases; +import static org.jooq.conf.ParamType.INDEXED; + import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -151,7 +153,7 @@ extends BaseTest q = create().resultQuery(sql, "10"); Result fetch1 = q.fetch(); @@ -518,7 +520,7 @@ extends BaseTest "); - if (context.inline()) { + if (context.paramType() == INLINED) { context.sql("3"); } else { diff --git a/jOOQ/pom.xml b/jOOQ/pom.xml index a8eb13edf0..75a77c6955 100644 --- a/jOOQ/pom.xml +++ b/jOOQ/pom.xml @@ -39,7 +39,7 @@ src/main/resources/xsd src/main/resources/xjb - jooq-runtime-3.0.0.xsd + jooq-runtime-3.1.0.xsd org.jooq.conf diff --git a/jOOQ/src/main/java/org/jooq/Context.java b/jOOQ/src/main/java/org/jooq/Context.java index f41de23613..a45b9dba6d 100644 --- a/jOOQ/src/main/java/org/jooq/Context.java +++ b/jOOQ/src/main/java/org/jooq/Context.java @@ -146,7 +146,7 @@ public interface Context> { * must assure that calling {@link #nextIndex()} is followed by setting a * bind value to {@link BindContext#statement()} *
  • When rendering unnamed bind variables with - * {@link RenderContext#namedParams()} being to true
  • + * {@link RenderContext#paramType()} being to NAMED * */ int nextIndex(); diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java index 71574c561c..fec2731c54 100644 --- a/jOOQ/src/main/java/org/jooq/DSLContext.java +++ b/jOOQ/src/main/java/org/jooq/DSLContext.java @@ -61,6 +61,7 @@ import java.util.Map; import javax.annotation.Generated; +import org.jooq.conf.ParamType; import org.jooq.conf.Settings; import org.jooq.conf.StatementType; import org.jooq.exception.DataAccessException; @@ -165,8 +166,7 @@ public interface DSLContext { *
  • {@link RenderContext#declareFields()} == false
  • *
  • {@link RenderContext#declareTables()} == false
  • *
  • {@link RenderContext#format()} == false
  • - *
  • {@link RenderContext#inline()} == false
  • - *
  • {@link RenderContext#namedParams()} == false
  • + *
  • {@link RenderContext#paramType()} == {@link ParamType#INDEXED}
  • *
  • {@link RenderContext#qualify()} == true
  • *
  • {@link RenderContext#subquery()} == false
  • * diff --git a/jOOQ/src/main/java/org/jooq/Query.java b/jOOQ/src/main/java/org/jooq/Query.java index e8f675162b..5d093bb014 100644 --- a/jOOQ/src/main/java/org/jooq/Query.java +++ b/jOOQ/src/main/java/org/jooq/Query.java @@ -41,6 +41,7 @@ import java.sql.Statement; 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.exception.DataAccessException; @@ -139,9 +140,28 @@ public interface Query extends QueryPart, Attachable { * @param inline Whether to inline bind variables. This overrides values in * {@link Settings#getStatementType()} * @return The generated SQL + * @deprecated - [#2414] - 3.1.0 - Use {@link #getSQL(ParamType)} instead */ + @Deprecated String getSQL(boolean inline); + /** + * 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 + */ + 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 diff --git a/jOOQ/src/main/java/org/jooq/RenderContext.java b/jOOQ/src/main/java/org/jooq/RenderContext.java index cecd18f61b..b0fb41813a 100644 --- a/jOOQ/src/main/java/org/jooq/RenderContext.java +++ b/jOOQ/src/main/java/org/jooq/RenderContext.java @@ -35,6 +35,7 @@ */ package org.jooq; +import org.jooq.conf.ParamType; import org.jooq.conf.RenderKeywordStyle; import org.jooq.conf.Settings; @@ -50,7 +51,7 @@ import org.jooq.conf.Settings; public interface RenderContext extends Context { /** - * Peek the next alias that will be generated by {@link #nextAlias()} + * Peek the next alias that will be generated by {@link #nextAlias()}. */ String peekAlias(); @@ -62,7 +63,7 @@ public interface RenderContext extends Context { String nextAlias(); /** - * Render the context's underlying SQL statement + * Render the context's underlying SQL statement. */ String render(); @@ -73,7 +74,7 @@ public interface RenderContext extends Context { String render(QueryPart part); /** - * Append a SQL keyword to the context's contained {@link StringBuilder} + * Append a SQL keyword to the context's contained {@link StringBuilder}. *

    * Use this to have your SQL keyword rendered in {@link RenderKeywordStyle} * (upper or lower case) @@ -81,58 +82,58 @@ public interface RenderContext extends Context { RenderContext keyword(String keyword); /** - * Append some SQL to the context's contained {@link StringBuilder} + * Append some SQL to the context's contained {@link StringBuilder}. */ RenderContext sql(String sql); /** - * Append some SQL to the context's contained {@link StringBuilder} + * Append some SQL to the context's contained {@link StringBuilder}. */ RenderContext sql(char sql); /** - * Append some SQL to the context's contained {@link StringBuilder} + * Append some SQL to the context's contained {@link StringBuilder}. */ RenderContext sql(int sql); /** - * Recurse rendering + * Recurse rendering. */ RenderContext sql(QueryPart part); /** - * Override the value of {@link Settings#isRenderFormatted()} + * Override the value of {@link Settings#isRenderFormatted()}. */ RenderContext format(boolean format); /** - * The value of {@link Settings#isRenderFormatted()} + * The value of {@link Settings#isRenderFormatted()}. */ boolean format(); /** * Render a new line character (only if {@link Settings#isRenderFormatted()} - * is set to true) + * is set to true). */ RenderContext formatNewLine(); /** * Render a new line character (only if {@link Settings#isRenderFormatted()} * is set to true, and the {@link #formatPrintMargin(int)} has - * been exceeded) + * been exceeded). */ RenderContext formatNewLineAfterPrintMargin(); /** * Render a new line character (only if {@link Settings#isRenderFormatted()} * is set to true), or a whitespace separator character - * otherwise + * otherwise. */ RenderContext formatSeparator(); /** * Start indenting subsequent SQL by one level (two characters), if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. *

    * This is the same as calling {@link #formatIndentStart(int)} with a * parameter of 2 @@ -141,19 +142,19 @@ public interface RenderContext extends Context { /** * Start indenting subsequent SQL by a number of characters, if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. */ RenderContext formatIndentStart(int indent); /** * Start indenting subsequent SQL at the same level as the current line, if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. */ RenderContext formatIndentLockStart(); /** * Stop indenting subsequent SQL by one level (two characters), if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. *

    * This is the same as calling {@link #formatIndentEnd(int)} with a * parameter of 2 @@ -162,19 +163,19 @@ public interface RenderContext extends Context { /** * Stop indenting subsequent SQL by a number of characters, if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. */ RenderContext formatIndentEnd(int indent); /** * Stop indenting subsequent SQL at the same level as the current line, if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. */ RenderContext formatIndentLockEnd(); /** * Set a print margin that will be applied to formatted SQL, if - * {@link Settings#isRenderFormatted()} is set to true + * {@link Settings#isRenderFormatted()} is set to true. *

    * The default print margin is 80. Setting this to zero or a * negative value means that no print margin will be applied. @@ -187,28 +188,36 @@ public interface RenderContext extends Context { /** * Append some (quoted) literal to the context's contained - * {@link StringBuilder} + * {@link StringBuilder}. */ RenderContext literal(String literal); /** * Whether bind variables should be inlined, rather than rendered as - * '?' + * '?'. + * + * @deprecated - 3.1.0 - [#2414] - This method should no longer be used. Use + * {@link #paramType()} instead. */ + @Deprecated boolean inline(); /** - * Set the new context value for {@link #inline()} + * Set the new context value for {@link #inline()}. + * + * @deprecated - 3.1.0 - [#2414] - This method should no longer be used. Use + * {@link #paramType(ParamType)} instead. */ + @Deprecated RenderContext inline(boolean inline); /** - * Whether query parts should render qualified names or not + * Whether query parts should render qualified names or not. */ boolean qualify(); /** - * Sett the new context value for {@link #qualify()} + * Sett the new context value for {@link #qualify()}. */ RenderContext qualify(boolean qualify); @@ -218,21 +227,48 @@ public interface RenderContext extends Context { *

    * or as JDBC bind variables
    *   ? + * + * @deprecated - 3.1.0 - [#2414] - This method should no longer be used. Use + * {@link #paramType()} instead. */ + @Deprecated boolean namedParams(); /** - * Set the new context value for {@link #namedParams()} + * Set the new context value for {@link #namedParams()}. + * + * @deprecated - 3.1.0 - [#2414] - This method should no longer be used. Use + * {@link #paramType(ParamType)} instead. */ + @Deprecated RenderContext namedParams(boolean renderNamedParams); /** - * The currently applied cast mode for bind values + * Specify, how bind values should be rendered. + *

    + *

      + *
    • As {@link ParamType#INDEXED} parameters:
      + *   ?, ?, ?
    • + *
    • As {@link ParamType#NAMED} parameters:
      + *   :1, :2, :custom_name
    • + *
    • As {@link ParamType#INLINED} parameters:
      + *   1, 'A', null
    • + *
    + */ + ParamType paramType(); + + /** + * Set the new context value for {@link #paramType()}. + */ + RenderContext paramType(ParamType paramType); + + /** + * The currently applied cast mode for bind values. */ CastMode castMode(); /** - * Set the new cast mode for {@link #castMode()} + * Set the new cast mode for {@link #castMode()}. */ RenderContext castMode(CastMode mode); @@ -264,7 +300,7 @@ public interface RenderContext extends Context { Boolean cast(); /** - * Set the new cast mode to {@link CastMode#SOME} for a list of dialects + * Set the new cast mode to {@link CastMode#SOME} for a list of dialects. */ RenderContext castModeSome(SQLDialect... dialects); @@ -276,24 +312,25 @@ public interface RenderContext extends Context { enum CastMode { /** - * Cast all bind values to their respective type + * Cast all bind values to their respective type. */ ALWAYS, /** - * Cast no bind values to their respective type + * Cast no bind values to their respective type. */ NEVER, /** * Cast bind values only in some dialects. The specified dialects assume * {@link #ALWAYS} behaviour, all the other dialects assume - * {@link #NEVER} + * {@link #NEVER}. */ SOME, /** - * Cast when needed. This is the default mode if not specified otherwise + * Cast when needed. This is the default mode if not specified + * otherwise. */ DEFAULT } diff --git a/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java b/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java index 37b2b3a9f9..8db3a11ef2 100644 --- a/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java +++ b/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java @@ -35,6 +35,8 @@ */ package org.jooq.conf; +import static org.jooq.conf.ParamType.INDEXED; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.conf.StatementType.PREPARED_STATEMENT; import static org.jooq.conf.StatementType.STATIC_STATEMENT; @@ -85,6 +87,28 @@ public final class SettingsTools { DEFAULT_SETTINGS = settings; } + /** + * Get the parameter type from the settings. + *

    + * The {@link ParamType} can be overridden by the {@link StatementType}. + * If the latter is set to {@link StatementType#STATIC_STATEMENT}, then the + * former defaults to {@link ParamType#INLINED}. + */ + public static final ParamType getParamType(Settings settings) { + if (executeStaticStatements(settings)) { + return INLINED; + } + else if (settings != null) { + ParamType result = settings.getParamType(); + + if (result != null) { + return result; + } + } + + return INDEXED; + } + /** * Get the statement type from the settings. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingQuery.java index 68281bd3c7..2517e706a6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingQuery.java @@ -44,6 +44,7 @@ import org.jooq.Configuration; import org.jooq.Param; import org.jooq.Query; import org.jooq.RenderContext; +import org.jooq.conf.ParamType; /** * @author Lukas Eder @@ -100,10 +101,16 @@ abstract class AbstractDelegatingQuery extends AbstractQueryPar } @Override + @Deprecated public final String getSQL(boolean inline) { return delegate.getSQL(inline); } + @Override + public final String getSQL(ParamType paramType) { + return delegate.getSQL(paramType); + } + @Override public final void attach(Configuration configuration) { delegate.attach(configuration); diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractParam.java b/jOOQ/src/main/java/org/jooq/impl/AbstractParam.java index 1714e5236c..fd22867219 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractParam.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractParam.java @@ -35,6 +35,8 @@ */ package org.jooq.impl; +import static org.jooq.conf.ParamType.INLINED; + import org.jooq.DataType; import org.jooq.Param; import org.jooq.RenderContext; @@ -113,6 +115,6 @@ abstract class AbstractParam extends AbstractField implements Param { } final boolean isInline(RenderContext context) { - return isInline() || context.inline(); + return isInline() || context.paramType() == INLINED; } } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java index 15ac1f54c1..419ceb1579 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java @@ -36,7 +36,10 @@ package org.jooq.impl; +import static org.jooq.conf.ParamType.INDEXED; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.conf.SettingsTools.executePreparedStatements; +import static org.jooq.conf.SettingsTools.getParamType; import static org.jooq.impl.Utils.DATA_COUNT_BIND_VALUES; import static org.jooq.impl.Utils.DATA_FORCE_STATIC_STATEMENT; @@ -53,7 +56,7 @@ import org.jooq.ExecuteListener; import org.jooq.Param; import org.jooq.Query; import org.jooq.RenderContext; -import org.jooq.conf.SettingsTools; +import org.jooq.conf.ParamType; import org.jooq.conf.StatementType; import org.jooq.exception.DetachedException; import org.jooq.tools.JooqLogger; @@ -174,7 +177,7 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha // If all params are inlined, the previous statement always has to // be closed - else if (SettingsTools.executeStaticStatements(configuration().settings())) { + else if (getParamType(configuration().settings()) == INLINED) { close(); } } @@ -239,8 +242,9 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha Configuration c = configuration(); // [#1191] The following triggers a start event on all listeners. - // This may be used to provide jOOQ with a JDBC connection, in case - // this Query / Configuration was previously deserialised + // This may be used to provide jOOQ with a JDBC connection, + // in case this Query / Configuration was previously + // deserialised ExecuteContext ctx = new DefaultExecuteContext(c, this); ExecuteListener listener = new ExecuteListeners(ctx); @@ -279,6 +283,8 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha if ( // [#1145] Bind variables only for true prepared statements + // [#2414] Even if parameters are inlined here, child + // QueryParts may override this behaviour! executePreparedStatements(c.settings()) && // [#1520] Renderers may enforce static statements, too @@ -371,11 +377,11 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha } catch (DefaultRenderContext.ForceInlineSignal e) { ctx.data(DATA_FORCE_STATIC_STATEMENT, true); - return getSQL(true); + return getSQL(INLINED); } } else { - return getSQL(true); + return getSQL(INLINED); } } @@ -384,24 +390,32 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha */ @Override public final String getSQL() { - if (executePreparedStatements(configuration().settings())) { - return getSQL(false); - } - else { - return getSQL(true); - } + return getSQL(getParamType(configuration().settings())); } /** * {@inheritDoc} */ @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); + } + + throw new IllegalArgumentException("ParamType not supported: " + paramType); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated public final String getSQL(boolean inline) { - if (inline) { - return create().renderInlined(this); - } - else { - return create().render(this); - } + return getSQL(inline ? INLINED : INDEXED); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/ArrayConstant.java b/jOOQ/src/main/java/org/jooq/impl/ArrayConstant.java index 5fbd542e0a..81b5eb698d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ArrayConstant.java +++ b/jOOQ/src/main/java/org/jooq/impl/ArrayConstant.java @@ -35,6 +35,7 @@ */ package org.jooq.impl; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.val; import org.jooq.ArrayRecord; @@ -59,7 +60,7 @@ class ArrayConstant> extends AbstractParam { @Override public final void toSQL(RenderContext context) { - if (context.inline()) { + if (context.paramType() == INLINED) { context.sql(array.getName()); context.sql("("); diff --git a/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java b/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java index ffa2900126..f3ff3c5812 100644 --- a/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java +++ b/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java @@ -35,6 +35,7 @@ */ package org.jooq.impl; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.conf.SettingsTools.executeStaticStatements; import java.sql.Connection; @@ -172,7 +173,7 @@ class BatchSingle implements BatchBindStep { query.bind(i + 1, bindValues[i]); } - queries.add(create.query(query.getSQL(true))); + queries.add(create.query(query.getSQL(INLINED))); } return create.batch(queries).execute(); diff --git a/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java b/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java index 569a14e3ea..e589605f11 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSLContextImpl.java @@ -50,6 +50,8 @@ import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; import static org.jooq.SQLDialect.SYBASE; +import static org.jooq.conf.ParamType.INLINED; +import static org.jooq.conf.ParamType.NAMED; import static org.jooq.impl.DSL.field; import static org.jooq.impl.DSL.fieldByName; import static org.jooq.impl.DSL.trueCondition; @@ -296,12 +298,12 @@ class DSLContextImpl implements DSLContext, Serializable { @Override public final String renderNamedParams(QueryPart part) { - return renderContext().namedParams(true).render(part); + return renderContext().paramType(NAMED).render(part); } @Override public final String renderInlined(QueryPart part) { - return renderContext().inline(true).render(part); + return renderContext().paramType(INLINED).render(part); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java index f3a365ad05..d9d9b13a4b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultRenderContext.java @@ -36,6 +36,9 @@ package org.jooq.impl; import static java.util.Arrays.asList; +import static org.jooq.conf.ParamType.INDEXED; +import static org.jooq.conf.ParamType.INLINED; +import static org.jooq.conf.ParamType.NAMED; import static org.jooq.impl.Utils.DATA_COUNT_BIND_VALUES; import java.util.Arrays; @@ -50,6 +53,7 @@ import org.jooq.QueryPart; import org.jooq.QueryPartInternal; import org.jooq.RenderContext; import org.jooq.SQLDialect; +import org.jooq.conf.ParamType; import org.jooq.conf.RenderKeywordStyle; import org.jooq.conf.RenderNameStyle; import org.jooq.conf.Settings; @@ -69,9 +73,8 @@ class DefaultRenderContext extends AbstractContext implements Ren private static final Set SQLITE_KEYWORDS; private final StringBuilder sql; - private boolean inline; + private ParamType paramType; private int params; - private boolean renderNamedParams; private boolean qualify = true; private int alias; private CastMode castMode = CastMode.DEFAULT; @@ -99,8 +102,7 @@ class DefaultRenderContext extends AbstractContext implements Ren DefaultRenderContext(RenderContext context) { this(context.configuration()); - inline(context.inline()); - namedParams(context.namedParams()); + paramType(context.paramType()); qualify(context.qualify()); castMode(context.castMode()); declareFields(context.declareFields()); @@ -374,7 +376,7 @@ class DefaultRenderContext extends AbstractContext implements Ren } private final void checkForceInline(QueryPart part) throws ForceInlineSignal { - if (inline) + if (paramType == INLINED) return; if (part instanceof Param) { @@ -412,12 +414,24 @@ class DefaultRenderContext extends AbstractContext implements Ren @Override public final boolean inline() { - return inline; + return paramType == INLINED; } @Override + @Deprecated public final RenderContext inline(boolean i) { - this.inline = i; + this.paramType = i ? INLINED : INDEXED; + return this; + } + + @Override + public final ParamType paramType() { + return paramType; + } + + @Override + public final RenderContext paramType(ParamType p) { + paramType = p; return this; } @@ -434,12 +448,13 @@ class DefaultRenderContext extends AbstractContext implements Ren @Override public final boolean namedParams() { - return renderNamedParams; + return paramType == NAMED; } @Override + @Deprecated public final RenderContext namedParams(boolean r) { - this.renderNamedParams = r; + this.paramType = r ? NAMED : INDEXED; return this; } @@ -487,11 +502,8 @@ class DefaultRenderContext extends AbstractContext implements Ren sb.append("rendering ["); sb.append(render()); sb.append("]\n"); - sb.append("inlining ["); - sb.append(inline); - sb.append("]\n"); - sb.append("named params ["); - sb.append(renderNamedParams); + sb.append("parameters ["); + sb.append(paramType); sb.append("]\n"); toString(sb); diff --git a/jOOQ/src/main/java/org/jooq/impl/Limit.java b/jOOQ/src/main/java/org/jooq/impl/Limit.java index b855115e90..1559231808 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Limit.java +++ b/jOOQ/src/main/java/org/jooq/impl/Limit.java @@ -36,6 +36,7 @@ package org.jooq.impl; import static org.jooq.RenderContext.CastMode.NEVER; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.val; @@ -44,6 +45,7 @@ import org.jooq.Field; import org.jooq.Param; import org.jooq.RenderContext; import org.jooq.RenderContext.CastMode; +import org.jooq.conf.ParamType; import org.jooq.exception.DataAccessException; /** @@ -64,7 +66,7 @@ class Limit extends AbstractQueryPart { @Override public final void toSQL(RenderContext context) { - boolean inline = context.inline(); + ParamType paramType = context.paramType(); CastMode castMode = context.castMode(); switch (context.configuration().dialect()) { @@ -134,14 +136,14 @@ class Limit extends AbstractQueryPart { // INGRES doesn't allow bind variables in the // OFFSET m FETCH FIRST n ROWS ONLY clause - context.inline(true) + context.paramType(INLINED) .formatSeparator() .keyword("offset ") .sql(offsetOrZero) .keyword(" fetch first ") .sql(numberOfRows) .keyword(" rows only") - .inline(inline); + .paramType(paramType); break; } @@ -149,12 +151,12 @@ class Limit extends AbstractQueryPart { // Nice TOP .. START AT support // ---------------------------- case SYBASE: { - context.inline(true) + context.paramType(INLINED) .keyword("top ") .sql(numberOfRows) .keyword(" start at ") .sql(offsetPlusOne) - .inline(inline); + .paramType(paramType); break; } @@ -168,12 +170,12 @@ class Limit extends AbstractQueryPart { } // DB2 doesn't allow bind variables here. Casting is not needed. - context.inline(true) + context.paramType(INLINED) .formatSeparator() .keyword("fetch first ") .sql(numberOfRows) .keyword(" rows only") - .inline(inline); + .paramType(paramType); break; } @@ -185,10 +187,10 @@ class Limit extends AbstractQueryPart { } // SQL Server and Sybase don't allow bind variables in the TOP n clause - context.inline(true) + context.paramType(INLINED) .keyword("top ") .sql(numberOfRows) - .inline(inline); + .paramType(paramType); break; } diff --git a/jOOQ/src/main/java/org/jooq/impl/Pivot.java b/jOOQ/src/main/java/org/jooq/impl/Pivot.java index e1985a8375..a4ce3a2546 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Pivot.java +++ b/jOOQ/src/main/java/org/jooq/impl/Pivot.java @@ -35,6 +35,7 @@ */ package org.jooq.impl; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.trueCondition; import static org.jooq.impl.DSL.using; @@ -54,6 +55,7 @@ import org.jooq.RenderContext; import org.jooq.Select; import org.jooq.Support; import org.jooq.Table; +import org.jooq.conf.ParamType; import org.jooq.exception.DataAccessException; /** @@ -222,7 +224,7 @@ implements public void toSQL(RenderContext context) { // Bind variables are not allowed inside of PIVOT clause - boolean inline = context.inline(); + ParamType paramType = context.paramType(); boolean declareFields = context.declareFields(); boolean declareTables = context.declareTables(); @@ -231,7 +233,7 @@ implements .declareTables(declareTables) .formatSeparator() .keyword("pivot (") - .inline(true) + .paramType(INLINED) .declareFields(true) .formatIndentStart() .sql(aggregateFunctions) @@ -242,7 +244,7 @@ implements .keyword("in (") .sql(in) .declareFields(declareFields) - .inline(inline) + .paramType(paramType) .sql(")") .formatIndentEnd() .formatNewLine() diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index bc8a016393..26e131d154 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -47,6 +47,7 @@ import static org.jooq.SQLDialect.MYSQL; import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.one; @@ -75,6 +76,7 @@ import org.jooq.SortField; import org.jooq.Table; import org.jooq.TableField; import org.jooq.TableLike; +import org.jooq.conf.ParamType; import org.jooq.exception.DataAccessException; import org.jooq.tools.StringUtils; @@ -490,14 +492,14 @@ class SelectQueryImpl extends AbstractSelect implements Sel // toSQL()'s LIMIT .. OFFSET rendering and bind()'s "obliviousness" // thereof. This should be improved by delegating to composed Select // objects. - boolean inline = context.inline(); - context.inline(true) + ParamType paramType = context.paramType(); + context.paramType(INLINED) .sql(",") .formatIndentStart() .formatSeparator() .sql(limitOffsetRownumber) .formatIndentEnd() - .inline(inline); + .paramType(paramType); } context.declareFields(false); diff --git a/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java b/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java index 1cd7724e4e..111145e281 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java +++ b/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java @@ -36,6 +36,7 @@ package org.jooq.impl; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.val; import org.jooq.BindContext; @@ -64,7 +65,7 @@ class UDTConstant> extends AbstractParam { // Oracle supports java.sql.SQLData, hence the record can be bound // to the CallableStatement directly case ORACLE: { - if (context.inline()) { + if (context.paramType() == INLINED) { toSQLInline(context); } else { context.sql("?"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Utils.java b/jOOQ/src/main/java/org/jooq/impl/Utils.java index 6772da7c82..e704a65f19 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Utils.java +++ b/jOOQ/src/main/java/org/jooq/impl/Utils.java @@ -38,6 +38,7 @@ package org.jooq.impl; import static java.lang.Boolean.FALSE; import static org.jooq.SQLDialect.CUBRID; import static org.jooq.SQLDialect.POSTGRES; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.escape; import static org.jooq.impl.DSL.getDataType; import static org.jooq.impl.DSL.nullSafe; @@ -833,7 +834,7 @@ final class Utils { else if (sqlChars[i] == '?' && substituteIndex < substitutes.size()) { QueryPart substitute = substitutes.get(substituteIndex++); - if (render.inline()) { + if (render.paramType() == INLINED) { render.sql(substitute); } else { diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java index 288735219d..4398542122 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Val.java +++ b/jOOQ/src/main/java/org/jooq/impl/Val.java @@ -51,6 +51,7 @@ import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; import static org.jooq.SQLDialect.SYBASE; +import static org.jooq.conf.ParamType.NAMED; import static org.jooq.tools.StringUtils.leftPad; import java.math.BigDecimal; @@ -276,7 +277,7 @@ class Val extends AbstractParam { * {@link RenderContext#namedParams()} */ private final String getBindVariable(RenderContext context) { - if (context.namedParams()) { + if (context.paramType() == NAMED) { int index = context.nextIndex(); if (StringUtils.isBlank(getParamName())) { diff --git a/jOOQ/src/main/java/org/jooq/tools/LoggerListener.java b/jOOQ/src/main/java/org/jooq/tools/LoggerListener.java index b6f4fc9240..ddc28a8d37 100644 --- a/jOOQ/src/main/java/org/jooq/tools/LoggerListener.java +++ b/jOOQ/src/main/java/org/jooq/tools/LoggerListener.java @@ -35,6 +35,8 @@ */ package org.jooq.tools; +import static org.jooq.conf.ParamType.INLINED; + import java.util.logging.Level; import org.jooq.ExecuteContext; @@ -67,7 +69,7 @@ public class LoggerListener extends DefaultExecuteListener { // [#1278] DEBUG log also SQL with inlined bind values, if // that is not the same as the actual SQL passed to JDBC - String inlined = ctx.query().getSQL(true); + String inlined = ctx.query().getSQL(INLINED); if (!ctx.sql().equals(inlined)) { log.debug("-> with bind values", inlined); } diff --git a/jOOQ/src/main/resources/xjb/binding.xjb b/jOOQ/src/main/resources/xjb/binding.xjb index 6fe24ba378..b389034a65 100644 --- a/jOOQ/src/main/resources/xjb/binding.xjb +++ b/jOOQ/src/main/resources/xjb/binding.xjb @@ -12,12 +12,12 @@ - + - + org.jooq.conf.SettingsBase java.lang.Cloneable diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.1.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.1.0.xsd new file mode 100644 index 0000000000..2c32aea4b1 --- /dev/null +++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.1.0.xsd @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jOOQ/src/test/java/org/jooq/test/AbstractTest.java b/jOOQ/src/test/java/org/jooq/test/AbstractTest.java index e7a23f9c81..5c02f9054b 100644 --- a/jOOQ/src/test/java/org/jooq/test/AbstractTest.java +++ b/jOOQ/src/test/java/org/jooq/test/AbstractTest.java @@ -35,6 +35,8 @@ */ package org.jooq.test; +import static org.jooq.conf.ParamType.INLINED; +import static org.jooq.conf.ParamType.NAMED; import static org.jooq.test.data.Table1.FIELD_ID1; import static org.jooq.test.data.Table1.FIELD_NAME1; import static org.jooq.test.data.Table1.TABLE1; @@ -144,23 +146,23 @@ public abstract class AbstractTest { } protected final RenderContext r_refI() { - return r_ref().inline(true); + return r_ref().paramType(INLINED); } protected final RenderContext r_decI() { - return r_dec().inline(true); + return r_dec().paramType(INLINED); } protected final RenderContext r_decIF() { - return r_decF().inline(true); + return r_decF().paramType(INLINED); } protected final RenderContext r_decIT() { - return r_decT().inline(true); + return r_decT().paramType(INLINED); } protected final RenderContext r_refP() { - return r_ref().namedParams(true); + return r_ref().paramType(NAMED); } protected final String zeroDate() { diff --git a/jOOQ/src/test/java/org/jooq/test/BasicTest.java b/jOOQ/src/test/java/org/jooq/test/BasicTest.java index e91c0276f6..610b33da26 100644 --- a/jOOQ/src/test/java/org/jooq/test/BasicTest.java +++ b/jOOQ/src/test/java/org/jooq/test/BasicTest.java @@ -38,6 +38,7 @@ package org.jooq.test; import static junit.framework.Assert.assertEquals; import static org.jooq.JoinType.LEFT_OUTER_JOIN; +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.DSL.any; import static org.jooq.impl.DSL.avg; import static org.jooq.impl.DSL.condition; @@ -957,7 +958,7 @@ public class BasicTest extends AbstractTest { @Override public void toSQL(RenderContext ctx) { - if (ctx.inline()) { + if (ctx.paramType() == INLINED) { ctx.sql("1 = 1"); } else { ctx.sql("? = ?"); @@ -1050,7 +1051,7 @@ public class BasicTest extends AbstractTest { @Override public void toSQL(RenderContext ctx) { - if (ctx.inline()) { + if (ctx.paramType() == INLINED) { ctx.sql("1"); } else { ctx.sql("?"); diff --git a/jOOQ/src/test/java/org/jooq/test/RenderTest.java b/jOOQ/src/test/java/org/jooq/test/RenderTest.java new file mode 100644 index 0000000000..972f62210e --- /dev/null +++ b/jOOQ/src/test/java/org/jooq/test/RenderTest.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq.test; + +import static org.jooq.conf.ParamType.INDEXED; +import static org.jooq.conf.ParamType.INLINED; +import static org.jooq.conf.ParamType.NAMED; +import static org.jooq.conf.StatementType.STATIC_STATEMENT; +import static org.jooq.impl.DSL.val; +import static org.junit.Assert.assertEquals; + +import org.jooq.Query; +import org.jooq.SQLDialect; +import org.jooq.conf.Settings; +import org.jooq.impl.DSL; + +import org.junit.Test; + +/** + * Some common tests related to rendering. + * + * @author Lukas Eder + */ +public class RenderTest extends AbstractTest { + + @SuppressWarnings("deprecation") + private void testGetSQL0(Query q, String defaultSQL) { + assertEquals(defaultSQL, q.getSQL()); + assertEquals("select ?, ? from dual", q.getSQL(false)); + assertEquals("select 1, 'A' from dual", q.getSQL(true)); + assertEquals("select ?, ? from dual", q.getSQL(INDEXED)); + assertEquals("select :1, :2 from dual", q.getSQL(NAMED)); + assertEquals("select 1, 'A' from dual", q.getSQL(INLINED)); + } + + @Test + public void testGetSQL() { + Query q = create.select(val(1), val("A")); + testGetSQL0(q, "select ?, ? from dual"); + } + + @Test + public void testGetSQLWithParamTypeINDEXED() { + Query q = + DSL.using(SQLDialect.ORACLE, new Settings().withParamType(INDEXED)) + .select(val(1), val("A")); + + testGetSQL0(q, "select ?, ? from dual"); + } + + @Test + public void testGetSQLWithParamTypeINDEXEDandStatementTypeSTATIC() { + Query q = + DSL.using(SQLDialect.ORACLE, new Settings().withParamType(INDEXED) + .withStatementType(STATIC_STATEMENT)) + .select(val(1), val("A")); + + testGetSQL0(q, "select 1, 'A' from dual"); + } + + @Test + public void testGetSQLWithParamTypeNAMED() { + Query q = + DSL.using(SQLDialect.ORACLE, new Settings().withParamType(NAMED)) + .select(val(1), val("A")); + + testGetSQL0(q, "select :1, :2 from dual"); + } + + @Test + public void testGetSQLWithParamTypeNAMEDandStatementTypeSTATIC() { + Query q = + DSL.using(SQLDialect.ORACLE, new Settings().withParamType(NAMED) + .withStatementType(STATIC_STATEMENT)) + .select(val(1), val("A")); + + testGetSQL0(q, "select 1, 'A' from dual"); + } + + @Test + public void testGetSQLWithParamTypeINLINED() { + Query q = + DSL.using(SQLDialect.ORACLE, new Settings().withParamType(INLINED)) + .select(val(1), val("A")); + + testGetSQL0(q, "select 1, 'A' from dual"); + } + + @Test + public void testGetSQLWithParamTypeINLINEDandStatementTypeSTATIC() { + Query q = + DSL.using(SQLDialect.ORACLE, new Settings().withParamType(INLINED) + .withStatementType(STATIC_STATEMENT)) + .select(val(1), val("A")); + + testGetSQL0(q, "select 1, 'A' from dual"); + } +}