Skip to content

Commit

Permalink
[#3323] [#4650] [#4976] Various fixes
Browse files Browse the repository at this point in the history
- [#3323] Make QueryPartInternal.toSQL() and bind() final in favour of the new accept() method
- [#4650] Collect bind variables while generating SQL, instead of traversing the AST twice
- [#4976] jOOQ's internals should not call QueryPartInternal.accept(Context), but Context.visit(QueryPart) instead
  • Loading branch information
lukaseder committed Jan 23, 2016
1 parent 2285d55 commit e6f9368
Show file tree
Hide file tree
Showing 24 changed files with 151 additions and 208 deletions.
5 changes: 5 additions & 0 deletions jOOQ/src/main/java/org/jooq/QueryPartInternal.java
Expand Up @@ -55,7 +55,12 @@ public interface QueryPartInternal extends QueryPart {
/** /**
* This {@link QueryPart} can <code>accept</code> a {@link Context} object * This {@link QueryPart} can <code>accept</code> a {@link Context} object
* in order to render a SQL string or to bind its variables. * in order to render a SQL string or to bind its variables.
*
* @deprecated - Calling {@link #accept(Context)} directly on a
* {@link QueryPart} is almost always a mistake. Instead,
* {@link Context#visit(QueryPart)} should be called.
*/ */
@Deprecated
void accept(Context<?> ctx); void accept(Context<?> ctx);


/** /**
Expand Down
1 change: 1 addition & 0 deletions jOOQ/src/main/java/org/jooq/impl/AbstractBindContext.java
Expand Up @@ -252,6 +252,7 @@ public final BindContext literal(String literal) {
/** /**
* Subclasses may override this method to achieve different behaviour * Subclasses may override this method to achieve different behaviour
*/ */
@SuppressWarnings("deprecation")
protected void bindInternal(QueryPartInternal internal) { protected void bindInternal(QueryPartInternal internal) {
internal.accept(this); internal.accept(this);
} }
Expand Down
49 changes: 33 additions & 16 deletions jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
Expand Up @@ -42,6 +42,7 @@
package org.jooq.impl; package org.jooq.impl;


import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.jooq.Constants.FULL_VERSION;
import static org.jooq.ExecuteType.DDL; import static org.jooq.ExecuteType.DDL;
// ... // ...
// ... // ...
Expand All @@ -64,11 +65,11 @@


import org.jooq.AttachableInternal; import org.jooq.AttachableInternal;
import org.jooq.Configuration; import org.jooq.Configuration;
import org.jooq.Constants;
import org.jooq.ExecuteContext; import org.jooq.ExecuteContext;
import org.jooq.ExecuteListener; import org.jooq.ExecuteListener;
import org.jooq.Param; import org.jooq.Param;
import org.jooq.Query; import org.jooq.Query;
import org.jooq.QueryPart;
import org.jooq.RenderContext; import org.jooq.RenderContext;
import org.jooq.Select; import org.jooq.Select;
import org.jooq.conf.ParamType; import org.jooq.conf.ParamType;
Expand All @@ -90,7 +91,7 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha
private int timeout; private int timeout;
private boolean keepStatement; private boolean keepStatement;
private transient PreparedStatement statement; private transient PreparedStatement statement;
private transient String sql; private transient Rendered rendered;


AbstractQuery(Configuration configuration) { AbstractQuery(Configuration configuration) {
this.configuration = configuration; this.configuration = configuration;
Expand Down Expand Up @@ -255,7 +256,7 @@ public final void close() {
statement = null; statement = null;
} }
catch (SQLException e) { catch (SQLException e) {
throw Utils.translate(sql, e); throw Utils.translate(rendered.sql, e);
} }
} }
} }
Expand All @@ -267,7 +268,7 @@ public final void cancel() {
statement.cancel(); statement.cancel();
} }
catch (SQLException e) { catch (SQLException e) {
throw Utils.translate(sql, e); throw Utils.translate(rendered.sql, e);
} }
} }
} }
Expand All @@ -291,7 +292,7 @@ public final int execute() {


// [#385] If a statement was previously kept open // [#385] If a statement was previously kept open
if (keepStatement() && statement != null) { if (keepStatement() && statement != null) {
ctx.sql(sql); ctx.sql(rendered.sql);
ctx.statement(statement); ctx.statement(statement);


// [#3191] Pre-initialise the ExecuteContext with a previous connection, if available. // [#3191] Pre-initialise the ExecuteContext with a previous connection, if available.
Expand All @@ -301,10 +302,10 @@ public final int execute() {
// [#385] First time statement preparing // [#385] First time statement preparing
else { else {
listener.renderStart(ctx); listener.renderStart(ctx);
ctx.sql(getSQL0(ctx)); rendered = getSQL0(ctx);
ctx.sql(rendered.sql);
listener.renderEnd(ctx); listener.renderEnd(ctx);

rendered.sql = ctx.sql();
sql = ctx.sql();


// [#3234] Defer initialising of a connection until the prepare step // [#3234] Defer initialising of a connection until the prepare step
// This optimises unnecessary ConnectionProvider.acquire() calls when // This optimises unnecessary ConnectionProvider.acquire() calls when
Expand Down Expand Up @@ -337,7 +338,8 @@ public final int execute() {
!Boolean.TRUE.equals(ctx.data(DATA_FORCE_STATIC_STATEMENT))) { !Boolean.TRUE.equals(ctx.data(DATA_FORCE_STATIC_STATEMENT))) {


listener.bindStart(ctx); listener.bindStart(ctx);
using(c).bindContext(ctx.statement()).visit(this); if (rendered.bindValues != null)
using(c).bindContext(ctx.statement()).visit(rendered.bindValues);
listener.bindEnd(ctx); listener.bindEnd(ctx);
} }


Expand Down Expand Up @@ -368,7 +370,7 @@ public final int execute() {


if (!keepStatement()) { if (!keepStatement()) {
statement = null; statement = null;
sql = null; rendered = null;
} }
} }
} }
Expand Down Expand Up @@ -434,8 +436,22 @@ public boolean isExecutable() {
return true; return true;
} }


private final String getSQL0(ExecuteContext ctx) { private static class Rendered {
String result; String sql;
QueryPart bindValues;

Rendered(String sql) {
this(sql, null);
}

Rendered(String sql, QueryPart bindValues) {
this.sql = sql;
this.bindValues = bindValues;
}
}

private final Rendered getSQL0(ExecuteContext ctx) {
Rendered result;






Expand All @@ -449,17 +465,18 @@ private final String getSQL0(ExecuteContext ctx) {


if (executePreparedStatements(configuration().settings())) { if (executePreparedStatements(configuration().settings())) {
try { try {
RenderContext render = new DefaultRenderContext(configuration); DefaultRenderContext render = new DefaultRenderContext(configuration);
render.data(DATA_COUNT_BIND_VALUES, true); render.data(DATA_COUNT_BIND_VALUES, true);
result = render.visit(this).render(); render.visit(this);
result = new Rendered(render.render(), render.bindValues());
} }
catch (DefaultRenderContext.ForceInlineSignal e) { catch (DefaultRenderContext.ForceInlineSignal e) {
ctx.data(DATA_FORCE_STATIC_STATEMENT, true); ctx.data(DATA_FORCE_STATIC_STATEMENT, true);
result = getSQL(INLINED); result = new Rendered(getSQL(INLINED));
} }
} }
else { else {
result = getSQL(INLINED); result = new Rendered(getSQL(INLINED));
} }




Expand Down
30 changes: 15 additions & 15 deletions jOOQ/src/main/java/org/jooq/impl/AbstractQueryPart.java
Expand Up @@ -70,28 +70,28 @@ Configuration configuration() {
} }


// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// The QueryPart and QueryPart internal API // Deprecated API
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------


/**
* @deprecated - 3.4.0 - [#2694] - Use
* {@link QueryPartInternal#accept(Context)} instead.
*/
@Override @Override
@Deprecated @Deprecated
public void toSQL(RenderContext ctx) { public final void toSQL(RenderContext context) {}
accept(ctx);
}

@Override
public void accept(Context<?> ctx) {
if (ctx instanceof RenderContext)
toSQL((RenderContext) ctx);
else
bind((BindContext) ctx);
}


/**
* @deprecated - 3.4.0 - [#2694] - Use
* {@link QueryPartInternal#accept(Context)} instead.
*/
@Override @Override
@Deprecated @Deprecated
public void bind(BindContext ctx) throws DataAccessException { public final void bind(BindContext context) throws DataAccessException {}
accept(ctx);
} // -------------------------------------------------------------------------
// The QueryPart and QueryPart internal API
// -------------------------------------------------------------------------


/** /**
* Subclasses may override this * Subclasses may override this
Expand Down
4 changes: 2 additions & 2 deletions jOOQ/src/main/java/org/jooq/impl/BetweenCondition.java
Expand Up @@ -117,12 +117,12 @@ public final Condition and(Field f) {


@Override @Override
public final void accept(Context<?> ctx) { public final void accept(Context<?> ctx) {
delegate(ctx.configuration()).accept(ctx); ctx.visit(delegate(ctx.configuration()));
} }


@Override @Override
public final Clause[] clauses(Context<?> ctx) { public final Clause[] clauses(Context<?> ctx) {
return delegate(ctx.configuration()).clauses(ctx); return null;
} }


private final QueryPartInternal delegate(Configuration configuration) { private final QueryPartInternal delegate(Configuration configuration) {
Expand Down
49 changes: 6 additions & 43 deletions jOOQ/src/main/java/org/jooq/impl/CustomCondition.java
Expand Up @@ -42,25 +42,19 @@


import static org.jooq.Clause.CUSTOM; import static org.jooq.Clause.CUSTOM;


import org.jooq.BindContext;
import org.jooq.Clause; import org.jooq.Clause;
import org.jooq.Condition; import org.jooq.Condition;
import org.jooq.Context; import org.jooq.Context;
import org.jooq.RenderContext;
import org.jooq.exception.DataAccessException;


/** /**
* A base class for custom {@link Condition} implementations in client code. * A base class for custom {@link Condition} implementations in client code.
* <p> * <p>
* Client code may provide proper {@link Condition} implementations extending * Client code may provide proper {@link Condition} implementations extending
* this useful base class. All necessary parts of the {@link Condition} * this useful base class. All necessary parts of the {@link Condition}
* interface are already implemented. Only these two methods need further * interface are already implemented. Only this method needs further
* implementation: * implementation: {@link #accept(Context)}.
* <ul> * <p>
* <li>{@link #toSQL(org.jooq.RenderContext)}</li> * Refer to that methods' Javadoc for further details about their expected
* <li>{@link #bind(org.jooq.BindContext)}</li>
* </ul>
* Refer to those methods' Javadoc for further details about their expected
* behaviour. * behaviour.
* *
* @author Lukas Eder * @author Lukas Eder
Expand All @@ -80,43 +74,12 @@ protected CustomCondition() {}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------


/** /**
* Subclasses must implement this method * Subclasses must implement this method.
* <hr/>
* {@inheritDoc}
*
* @deprecated - 3.4.0 - [#2694] - Use {@link #accept(Context)} instead.
*/
@Override
@Deprecated
public void toSQL(RenderContext context) {}

// -------------------------------------------------------------------------
// Implementation optional
// -------------------------------------------------------------------------

/**
* Subclasses may implement this method.
* <hr/>
* {@inheritDoc}
*/
@Override
public void accept(Context<?> ctx) {
if (ctx instanceof RenderContext)
toSQL((RenderContext) ctx);
else
bind((BindContext) ctx);
}

/**
* Subclasses may implement this method
* <hr/> * <hr/>
* {@inheritDoc} * {@inheritDoc}
*
* @deprecated - 3.4.0 - [#2694] - Use {@link #accept(Context)} instead.
*/ */
@Override @Override
@Deprecated public abstract void accept(Context<?> ctx);
public void bind(BindContext context) throws DataAccessException {}


// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// No further overrides allowed // No further overrides allowed
Expand Down
50 changes: 8 additions & 42 deletions jOOQ/src/main/java/org/jooq/impl/CustomField.java
Expand Up @@ -42,25 +42,21 @@


import static org.jooq.Clause.CUSTOM; import static org.jooq.Clause.CUSTOM;


import org.jooq.BindContext;
import org.jooq.Clause; import org.jooq.Clause;
import org.jooq.Condition;
import org.jooq.Context; import org.jooq.Context;
import org.jooq.DataType; import org.jooq.DataType;
import org.jooq.Field; import org.jooq.Field;
import org.jooq.RenderContext;
import org.jooq.exception.DataAccessException;


/** /**
* A base class for custom {@link Field} implementations in client code. * A base class for custom {@link Field} implementations in client code.
* <p> * <p>
* Client code may provide proper {@link Field} implementations extending this * Client code may provide proper {@link Condition} implementations extending
* useful base class. All necessary parts of the {@link Field} interface are * this useful base class. All necessary parts of the {@link Condition}
* already implemented. Only these two methods need further implementation: * interface are already implemented. Only this method needs further
* <ul> * implementation: {@link #accept(Context)}.
* <li>{@link #toSQL(org.jooq.RenderContext)}</li> * <p>
* <li>{@link #bind(org.jooq.BindContext)}</li> * Refer to that methods' Javadoc for further details about their expected
* </ul>
* Refer to those methods' Javadoc for further details about their expected
* behaviour. * behaviour.
* *
* @author Lukas Eder * @author Lukas Eder
Expand All @@ -85,39 +81,9 @@ protected CustomField(String name, DataType<T> type) {
* Subclasses must implement this method. * Subclasses must implement this method.
* <hr/> * <hr/>
* {@inheritDoc} * {@inheritDoc}
* @deprecated - 3.4.0 - [#2694] - Use {@link #accept(Context)} instead.
*/
@Deprecated
@Override
public void toSQL(RenderContext context) {}

// -------------------------------------------------------------------------
// Implementation optional
// -------------------------------------------------------------------------

/**
* Subclasses may implement this method.
* <hr/>
* {@inheritDoc}
*/ */
@Override @Override
public void accept(Context<?> ctx) { public abstract void accept(Context<?> ctx);
if (ctx instanceof RenderContext)
toSQL((RenderContext) ctx);
else
bind((BindContext) ctx);
}

/**
* Subclasses may implement this method.
* <hr/>
* {@inheritDoc}
* @deprecated - 3.4.0 - [#2694] - Use {@link #accept(Context)} instead.
*/
@Deprecated
@Override
public void bind(BindContext context) throws DataAccessException {
}


// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// No further overrides allowed // No further overrides allowed
Expand Down

0 comments on commit e6f9368

Please sign in to comment.