* [#2665] Implement SPI for RenderContext and BindContext listening to allow for custom SQL transformation * [#2667] Add org.jooq.Clause and let org.jooq.Context listen on start(Clause) and end(Clause) events - First API and implementation draft * [#2676] Add QueryPartInternal.clause() to allow for QueryParts to return Clause information to org.jooq.Context
This commit is contained in:
parent
0f4297cc97
commit
1e5e4f5bf0
252
jOOQ/src/main/java/org/jooq/Clause.java
Normal file
252
jOOQ/src/main/java/org/jooq/Clause.java
Normal file
@ -0,0 +1,252 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* TODO [#2667]
|
||||
*/
|
||||
public enum Clause {
|
||||
|
||||
/**
|
||||
* A placeholder clause for cases where the behaviour was not yet specified.
|
||||
* This will not go public, and is meant to be a placeholder during
|
||||
* development.
|
||||
*/
|
||||
@Deprecated
|
||||
DUMMY,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses used in a any type of statement to model catalog references
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
CATALOG,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses used in a any type of statement to model schema references
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
SCHEMA,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses used in a any type of statement to model table references
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A complete table reference.
|
||||
* <p>
|
||||
* This "clause" surrounds a complete table reference as it can be encountered
|
||||
* in
|
||||
* <ul>
|
||||
* <li> {@link #SELECT_FROM}</li>
|
||||
* <li> {@link #INSERT_INSERT_INTO}</li>
|
||||
* <li> {@link #UPDATE_UPDATE}</li>
|
||||
* <li> {@link #DELETE_DELETE}</li>
|
||||
* <li> {@link #MERGE_MERGE_INTO}</li>
|
||||
* <li> {@link #TRUNCATE_TRUNCATE}</li>
|
||||
* </ul>
|
||||
*/
|
||||
TABLE,
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
TABLE_JOIN,
|
||||
TABLE_JOIN_INNER,
|
||||
TABLE_JOIN_CROSS,
|
||||
TABLE_JOIN_NATURAL,
|
||||
TABLE_JOIN_OUTER_LEFT,
|
||||
TABLE_JOIN_OUTER_RIGHT,
|
||||
TABLE_JOIN_OUTER_FULL,
|
||||
TABLE_JOIN_NATURAL_OUTER_LEFT,
|
||||
TABLE_JOIN_NATURAL_OUTER_RIGHT,
|
||||
TABLE_JOIN_ON,
|
||||
TABLE_JOIN_USING,
|
||||
TABLE_JOIN_PARTITION_BY,
|
||||
|
||||
TABLE_FLASHBACK,
|
||||
TABLE_PIVOT,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses used in a any type of statement to model column references
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
FIELD,
|
||||
FIELD_CASE,
|
||||
FIELD_ROW,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses used in a any type of statement to model condition references
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
CONDITION,
|
||||
|
||||
CONDITION_NULL,
|
||||
CONDITION_NULL_NOT,
|
||||
// TODO: Should operators be distinguished?
|
||||
// - LIKE predicate
|
||||
// - Subselect predicates
|
||||
// - RVE predicates
|
||||
// - Quantified predicates
|
||||
CONDITION_COMPARISON,
|
||||
CONDITION_BETWEEN,
|
||||
CONDITION_DISTINCT,
|
||||
CONDITION_DISTINCT_NOT,
|
||||
CONDITION_OVERLAPS,
|
||||
|
||||
CONDITION_AND,
|
||||
CONDITION_OR,
|
||||
CONDITION_NOT,
|
||||
|
||||
CONDITION_IN,
|
||||
CONDITION_IN_NOT,
|
||||
CONDITION_EXISTS,
|
||||
CONDITION_EXISTS_NOT,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses that are used in a SELECT statement
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A complete <code>SELECT</code> statement or a subselect.
|
||||
* <p>
|
||||
* This "clause" surrounds a complete <code>SELECT</code> statement, a
|
||||
* subselect, or a set operation, such as
|
||||
* <ul>
|
||||
* <li> {@link #SELECT_UNION}</li>
|
||||
* <li> {@link #SELECT_UNION_ALL}</li>
|
||||
* <li> {@link #SELECT_INTERSECT}</li>
|
||||
* <li> {@link #SELECT_EXCEPT}</li>
|
||||
* </ul>
|
||||
*/
|
||||
SELECT,
|
||||
|
||||
/**
|
||||
* A <code>UNION</code> set operation.
|
||||
* <p>
|
||||
* This clause surrounds two or more subselects (see {@link #SELECT})
|
||||
* concatenating them using a <code>UNION</code> set operation.
|
||||
*/
|
||||
SELECT_UNION,
|
||||
|
||||
/**
|
||||
* A <code>UNION ALL</code> set operation.
|
||||
* <p>
|
||||
* This clause surrounds two or more subselects (see {@link #SELECT})
|
||||
* concatenating them using a <code>UNION ALL</code> set operation.
|
||||
*/
|
||||
SELECT_UNION_ALL,
|
||||
|
||||
/**
|
||||
* A <code>INTERSECT</code> set operation.
|
||||
* <p>
|
||||
* This clause surrounds two or more subselects (see {@link #SELECT})
|
||||
* concatenating them using a <code>INTERSECT</code> set operation.
|
||||
*/
|
||||
SELECT_INTERSECT,
|
||||
|
||||
/**
|
||||
* A <code>EXCEPT</code> set operation.
|
||||
* <p>
|
||||
* This clause surrounds two or more subselects (see {@link #SELECT})
|
||||
* concatenating them using a <code>EXCEPT</code> set operation.
|
||||
*/
|
||||
SELECT_EXCEPT,
|
||||
|
||||
/**
|
||||
* A <code>SELECT</code> clause within a {@link #SELECT} statement or
|
||||
* subselect.
|
||||
* <p>
|
||||
* This clause surrounds
|
||||
* <ul>
|
||||
* <li>the <code>SELECT</code> keyword</li>
|
||||
* <li>Oracle style hints</li>
|
||||
* <li>the T-SQL style <code>TOP .. START AT</code> clause</li>
|
||||
* <li>the select field list</li>
|
||||
* </ul>
|
||||
*/
|
||||
SELECT_SELECT,
|
||||
|
||||
/**
|
||||
* A <code>FROM</code> clause within a {@link #SELECT} statement or
|
||||
* subselect.
|
||||
* <p>
|
||||
* This clause surrounds
|
||||
* <ul>
|
||||
* <li>the <code>FROM</code> keyword</li>
|
||||
* <li>the table reference list</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* See {@link #TABLE} and related clauses for possible table references.
|
||||
*
|
||||
* @see #TABLE
|
||||
*/
|
||||
SELECT_FROM,
|
||||
SELECT_WHERE,
|
||||
SELECT_START_WITH,
|
||||
SELECT_CONNECT_BY,
|
||||
SELECT_GROUP_BY,
|
||||
SELECT_HAVING,
|
||||
SELECT_ORDER_BY,
|
||||
|
||||
|
||||
|
||||
INSERT,
|
||||
INSERT_INSERT_INTO,
|
||||
INSERT_RETURNING,
|
||||
|
||||
|
||||
|
||||
UPDATE,
|
||||
UPDATE_UPDATE,
|
||||
UPDATE_SET,
|
||||
UPDATE_SET_ASSIGNMENT,
|
||||
UPDATE_WHERE,
|
||||
UPDATE_RETURNING,
|
||||
|
||||
|
||||
DELETE,
|
||||
DELETE_DELETE,
|
||||
DELETE_WHERE,
|
||||
|
||||
|
||||
MERGE,
|
||||
MERGE_MERGE_INTO,
|
||||
|
||||
|
||||
|
||||
TRUNCATE,
|
||||
TRUNCATE_TRUNCATE,
|
||||
}
|
||||
@ -194,6 +194,11 @@ public interface Configuration extends Serializable {
|
||||
*/
|
||||
ExecuteListenerProvider[] executeListenerProviders();
|
||||
|
||||
/**
|
||||
* TODO [#2667]
|
||||
*/
|
||||
VisitListenerProvider[] visitListenerProviders();
|
||||
|
||||
/**
|
||||
* Retrieve the configured schema mapping.
|
||||
*
|
||||
@ -264,6 +269,18 @@ public interface Configuration extends Serializable {
|
||||
*/
|
||||
Configuration set(ExecuteListenerProvider... newExecuteListenerProviders);
|
||||
|
||||
/**
|
||||
* Change this configuration to hold a new visit listener providers.
|
||||
* <p>
|
||||
* This method is not thread-safe and should not be used in globally
|
||||
* available <code>Configuration</code> objects.
|
||||
*
|
||||
* @param newVisitListenerProviders The new visit listener providers to
|
||||
* be contained in the changed configuration.
|
||||
* @return The changed configuration.
|
||||
*/
|
||||
Configuration set(VisitListenerProvider... newVisitListenerProviders);
|
||||
|
||||
/**
|
||||
* Change this configuration to hold a new dialect.
|
||||
* <p>
|
||||
@ -340,6 +357,16 @@ public interface Configuration extends Serializable {
|
||||
*/
|
||||
Configuration derive(ExecuteListenerProvider... newExecuteListenerProviders);
|
||||
|
||||
/**
|
||||
* Create a derived configuration from this one, with new visit listener
|
||||
* providers.
|
||||
*
|
||||
* @param newVisitListenerProviders The new visit listener providers to
|
||||
* be contained in the derived configuration.
|
||||
* @return The derived configuration.
|
||||
*/
|
||||
Configuration derive(VisitListenerProvider... newVisitListenerProviders);
|
||||
|
||||
/**
|
||||
* Create a derived configuration from this one, with a new dialect.
|
||||
*
|
||||
|
||||
@ -120,6 +120,15 @@ public interface Context<C extends Context<C>> {
|
||||
*/
|
||||
C visit(QueryPart part) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* TODO [#2667]
|
||||
*
|
||||
* Properties of these methods:
|
||||
* - A clause is always started / ended, even if it isn't rendered or if it's empty!
|
||||
*/
|
||||
C start(Clause clause);
|
||||
C end(Clause clause);
|
||||
|
||||
/**
|
||||
* Whether the current context is rendering a SQL field declaration (e.g. a
|
||||
* {@link Field} in the <code>SELECT</code> clause of the query).
|
||||
|
||||
@ -69,6 +69,21 @@ public interface QueryPartInternal extends QueryPart {
|
||||
*/
|
||||
void bind(BindContext ctx) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* The {@link Clause} that is represented by this query part.
|
||||
* <p>
|
||||
* {@link QueryPart}s can specify a <code>Clause</code> for which an event
|
||||
* will be emitted {@link Context#start(Clause) before} and
|
||||
* {@link Context#end(Clause) after} visiting the the query part through
|
||||
* {@link Context#visit(QueryPart)}
|
||||
* <p>
|
||||
* This method is for JOOQ INTERNAL USE only. Do not reference directly
|
||||
*
|
||||
* @return The <code>Clause</code> represented by this query part or
|
||||
* <code>null</code> if this query part does not represent a clause.
|
||||
*/
|
||||
Clause clause();
|
||||
|
||||
/**
|
||||
* Check whether this {@link QueryPart} is able to declare fields in a
|
||||
* <code>SELECT</code> clause.
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* A listener for manipulation events on {@link UpdatableRecord}s.
|
||||
* <p>
|
||||
@ -52,7 +54,7 @@ package org.jooq;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface RecordListener {
|
||||
public interface RecordListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Called before storing an <code>UpdatableRecord</code>.
|
||||
|
||||
@ -43,8 +43,8 @@ import org.jooq.impl.DefaultRecordListenerProvider;
|
||||
* In order to facilitate the lifecycle management of
|
||||
* <code>RecordListener</code> instances that are provided to a jOOQ
|
||||
* {@link Configuration}, clients can implement this API. To jOOQ, it is thus
|
||||
* irrelevant, if execute listeners are stateful or stateless, local to a
|
||||
* single record or record manipulation, or global to an application.
|
||||
* irrelevant, if execute listeners are stateful or stateless, local to a single
|
||||
* record or record manipulation, or global to an application.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* @see RecordListener
|
||||
|
||||
128
jOOQ/src/main/java/org/jooq/VisitContext.java
Normal file
128
jOOQ/src/main/java/org/jooq/VisitContext.java
Normal file
@ -0,0 +1,128 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A context object for {@link QueryPart} traversal passed to registered
|
||||
* {@link VisitListener}'s.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* @see VisitListener
|
||||
*/
|
||||
public interface VisitContext {
|
||||
|
||||
/**
|
||||
* Get all custom data from this <code>VisitContext</code>.
|
||||
* <p>
|
||||
* This corresponds to {@link Context#data()} returned from
|
||||
* {@link #context()}.
|
||||
*
|
||||
* @return The custom data. This is never <code>null</code>
|
||||
* @see VisitListener
|
||||
*/
|
||||
Map<Object, Object> data();
|
||||
|
||||
/**
|
||||
* Get some custom data from this <code>VisitContext</code>.
|
||||
* <p>
|
||||
* This corresponds to {@link Context#data(Object)} returned from
|
||||
* {@link #context()}.
|
||||
*
|
||||
* @param key A key to identify the custom data
|
||||
* @return The custom data or <code>null</code> if no such data is contained
|
||||
* in this <code>VisitListener</code>
|
||||
* @see VisitListener
|
||||
*/
|
||||
Object data(Object key);
|
||||
|
||||
/**
|
||||
* Set some custom data to this <code>VisitContext</code>.
|
||||
* <p>
|
||||
* This corresponds to {@link Context#data(Object, Object)} returned from
|
||||
* {@link #context()}.
|
||||
*
|
||||
* @param key A key to identify the custom data
|
||||
* @param value The custom data or <code>null</code> to unset the custom
|
||||
* data
|
||||
* @return The previously set custom data or <code>null</code> if no data
|
||||
* was previously set for the given key
|
||||
* @see VisitContext
|
||||
*/
|
||||
Object data(Object key, Object value);
|
||||
|
||||
/**
|
||||
* The configuration wrapped by this context.
|
||||
*/
|
||||
Configuration configuration();
|
||||
|
||||
/**
|
||||
* The most recent clause that was encountered through
|
||||
* {@link Context#start(Clause)}.
|
||||
*/
|
||||
Clause clause();
|
||||
|
||||
/**
|
||||
* All previous clauses.
|
||||
* <p>
|
||||
* This returns all previous clauses that were encountered through
|
||||
* {@link Context#start(Clause)} and that haven't been removed yet through
|
||||
* {@link Context#end(Clause)}. In other words, <code>VisitContext</code>
|
||||
* contains a stack of clauses.
|
||||
*/
|
||||
Clause[] clauses();
|
||||
|
||||
/**
|
||||
* The {@link QueryPart} that is being visited.
|
||||
*/
|
||||
QueryPart visiting();
|
||||
|
||||
/**
|
||||
* The underlying {@link RenderContext} or {@link BindContext} object.
|
||||
*/
|
||||
Context<?> context();
|
||||
|
||||
/**
|
||||
* The underlying {@link RenderContext} or <code>null</code>, if the underlying context is a {@link BindContext}.
|
||||
*/
|
||||
RenderContext renderContext();
|
||||
|
||||
/**
|
||||
* The underlying {@link BindContext} or <code>null</code>, if the underlying context is a {@link RenderContext}.
|
||||
*/
|
||||
BindContext bindContext();
|
||||
}
|
||||
111
jOOQ/src/main/java/org/jooq/VisitListener.java
Normal file
111
jOOQ/src/main/java/org/jooq/VisitListener.java
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* A listener for {@link QueryPart} traversal events.
|
||||
* <p>
|
||||
* Users may want to centrally inject custom behaviour when rendering their
|
||||
* {@link QueryPart} objects or when binding values to {@link PreparedStatement}
|
||||
* s. This service provider allows to hook in callback method implementations
|
||||
* before or after these events:
|
||||
* <ul>
|
||||
* <li>The visit of a {@link Clause}</li>
|
||||
* <li>The visit of a {@link QueryPart}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The following rules apply to visiting clauses and query parts:
|
||||
* <ul>
|
||||
* <li>Clauses may "surround" a query part. See an example below.</li>
|
||||
* <li>Not every query part is "surrounded" by a clause</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* An example is given here:
|
||||
* <code><pre>SELECT 1 FROM [A CROSS JOIN B]</pre></code>
|
||||
* <p>
|
||||
* The above example will create the following set of events:
|
||||
*
|
||||
* <pre>
|
||||
* {@link Clause#SELECT}
|
||||
* +-{@link Clause#SELECT_SELECT}
|
||||
* | +-{@link Clause#FIELD}
|
||||
* | +-val(1)
|
||||
* +-{@link Clause#SELECT_FROM}
|
||||
* +-{@link Clause#TABLE_JOIN}
|
||||
* +-{@link Clause#TABLE}
|
||||
* | +-table("A")
|
||||
* +-{@link Clause#TABLE_JOIN_CROSS}
|
||||
* +-{@link Clause#TABLE}
|
||||
* +-table("B")
|
||||
* </pre>
|
||||
* <p>
|
||||
* Whatever is not a {@link Clause} in the above example is a {@link QueryPart}.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface VisitListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Called before entering a {@link Clause}.
|
||||
*
|
||||
* @see Context#start(Clause)
|
||||
*/
|
||||
void clauseStart(VisitContext context);
|
||||
|
||||
/**
|
||||
* Called after leaving a {@link Clause}.
|
||||
*
|
||||
* @see Context#end(Clause)
|
||||
*/
|
||||
void clauseEnd(VisitContext context);
|
||||
|
||||
/**
|
||||
* Called before visiting a {@link QueryPart}.
|
||||
*
|
||||
* @see Context#visit(QueryPart)
|
||||
*/
|
||||
void visitStart(VisitContext context);
|
||||
|
||||
/**
|
||||
* Called after visiting a {@link QueryPart}.
|
||||
*
|
||||
* @see Context#visit(QueryPart)
|
||||
*/
|
||||
void visitEnd(VisitContext context);
|
||||
}
|
||||
72
jOOQ/src/main/java/org/jooq/VisitListenerProvider.java
Normal file
72
jOOQ/src/main/java/org/jooq/VisitListenerProvider.java
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.jooq.impl.DefaultVisitListenerProvider;
|
||||
|
||||
/**
|
||||
* A provider for {@link VisitListener} instances.
|
||||
* <p>
|
||||
* In order to facilitate the lifecycle management of <code>VisitListener</code>
|
||||
* instances that are provided to a jOOQ {@link Configuration}, clients can
|
||||
* implement this API. To jOOQ, it is thus irrelevant, if execute listeners are
|
||||
* stateful or stateless, local to a single record or record manipulation, or
|
||||
* global to an application.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* @see VisitListener
|
||||
* @see Configuration
|
||||
*/
|
||||
public interface VisitListenerProvider {
|
||||
|
||||
/**
|
||||
* Provide a <code>VisitListener</code> instance.
|
||||
* <p>
|
||||
* Implementations are free to choose whether this method returns new
|
||||
* instances at every call or whether the same instance is returned
|
||||
* repetitively.
|
||||
* <p>
|
||||
* A <code>VisitListener</code> shall be provided exactly once per
|
||||
* <code>Context</code> traversal, i.e. per <code>RenderContext</code> or
|
||||
* <code>BindContext</code>.
|
||||
*
|
||||
* @return A <code>VisitListener</code> instance.
|
||||
* @see VisitListener
|
||||
* @see VisitContext
|
||||
* @see DefaultVisitListenerProvider
|
||||
*/
|
||||
VisitListener provide();
|
||||
}
|
||||
@ -35,13 +35,22 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.VisitContext;
|
||||
import org.jooq.VisitListener;
|
||||
import org.jooq.VisitListenerProvider;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -49,16 +58,32 @@ import org.jooq.QueryPartInternal;
|
||||
@SuppressWarnings("unchecked")
|
||||
abstract class AbstractContext<C extends Context<C>> implements Context<C> {
|
||||
|
||||
final Configuration configuration;
|
||||
final Map<Object, Object> data;
|
||||
boolean declareFields;
|
||||
boolean declareTables;
|
||||
boolean subquery;
|
||||
int index;
|
||||
final Configuration configuration;
|
||||
final Map<Object, Object> data;
|
||||
final VisitListener[] visitListeners;
|
||||
|
||||
private final DefaultVisitContext visitContext;
|
||||
private final Deque<Clause> visitClauses;
|
||||
private final Deque<QueryPart> visitParts;
|
||||
|
||||
boolean declareFields;
|
||||
boolean declareTables;
|
||||
boolean subquery;
|
||||
int index;
|
||||
|
||||
AbstractContext(Configuration configuration) {
|
||||
VisitListenerProvider[] providers = configuration.visitListenerProviders();
|
||||
|
||||
this.configuration = configuration;
|
||||
this.data = new HashMap<Object, Object>();
|
||||
this.visitListeners = new VisitListener[providers.length];
|
||||
this.visitContext = new DefaultVisitContext();
|
||||
this.visitClauses = new ArrayDeque<Clause>();
|
||||
this.visitParts = new ArrayDeque<QueryPart>();
|
||||
|
||||
for (int i = 0; i < providers.length; i++) {
|
||||
this.visitListeners[i] = providers[i].provide();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -85,9 +110,112 @@ abstract class AbstractContext<C extends Context<C>> implements Context<C> {
|
||||
return data.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO [#2667] This is a draft implementation. The actual implementation
|
||||
* may change
|
||||
*/
|
||||
private class DefaultVisitContext implements VisitContext {
|
||||
|
||||
@Override
|
||||
public final Map<Object, Object> data() {
|
||||
return AbstractContext.this.data();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object data(Object key) {
|
||||
return AbstractContext.this.data(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object data(Object key, Object value) {
|
||||
return AbstractContext.this.data(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Configuration configuration() {
|
||||
return AbstractContext.this.configuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return visitClauses.peekLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause[] clauses() {
|
||||
return visitClauses.toArray(new Clause[visitClauses.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final QueryPart visiting() {
|
||||
return visitParts.peekLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Context<?> context() {
|
||||
return AbstractContext.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RenderContext renderContext() {
|
||||
return (RenderContext) (AbstractContext.this instanceof RenderContext ? AbstractContext.this : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BindContext bindContext() {
|
||||
return (BindContext) (AbstractContext.this instanceof BindContext ? AbstractContext.this : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final C start(Clause clause) {
|
||||
visitClauses.addLast(clause);
|
||||
|
||||
for (VisitListener listener : visitListeners) {
|
||||
listener.clauseStart(visitContext);
|
||||
}
|
||||
|
||||
return (C) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final C end(Clause clause) {
|
||||
for (VisitListener listener : visitListeners) {
|
||||
listener.clauseEnd(visitContext);
|
||||
}
|
||||
|
||||
if (visitClauses.removeLast() != clause)
|
||||
throw new IllegalStateException("Mismatch between visited clauses!");
|
||||
|
||||
return (C) this;
|
||||
}
|
||||
|
||||
private final void start(QueryPart part) {
|
||||
visitParts.addLast(part);
|
||||
|
||||
for (VisitListener listener : visitListeners) {
|
||||
listener.visitStart(visitContext);
|
||||
}
|
||||
}
|
||||
|
||||
private final void end(QueryPart part) {
|
||||
for (VisitListener listener : visitListeners) {
|
||||
listener.visitEnd(visitContext);
|
||||
}
|
||||
|
||||
if (visitParts.removeLast() != part)
|
||||
throw new RuntimeException("Mismatch between visited query parts");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final C visit(QueryPart part) {
|
||||
if (part != null) {
|
||||
Clause clause = visitListeners.length > 0 ? clause(part) : null;
|
||||
|
||||
if (clause != null)
|
||||
start(clause);
|
||||
|
||||
start(part);
|
||||
QueryPartInternal internal = (QueryPartInternal) part;
|
||||
|
||||
// If this is supposed to be a declaration section and the part isn't
|
||||
@ -111,11 +239,39 @@ abstract class AbstractContext<C extends Context<C>> implements Context<C> {
|
||||
else {
|
||||
visit0(internal);
|
||||
}
|
||||
|
||||
end(part);
|
||||
if (clause != null)
|
||||
end(clause);
|
||||
}
|
||||
|
||||
return (C) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a clause from a query part being visited.
|
||||
* <p>
|
||||
* This method returns a clause to emit as a surrounding event before /
|
||||
* after visiting a query part. This is needed for all reusable query parts,
|
||||
* whose clause type is ambiguous at the container site. An example:
|
||||
* <p>
|
||||
* <code><pre>SELECT * FROM [A CROSS JOIN B]</pre></code>
|
||||
* <p>
|
||||
* The type of the above <code>JoinTable</code> modelling
|
||||
* <code>A CROSS JOIN B</code> is not known to the surrounding
|
||||
* <code>SELECT</code> statement, which only knows {@link Table} types. The
|
||||
* {@link Clause#TABLE_JOIN} event that is required to be emitted around the
|
||||
* {@link Context#visit(QueryPart)} event has to be issued here in
|
||||
* <code>AbstractContext</code>.
|
||||
*/
|
||||
private final Clause clause(QueryPart part) {
|
||||
if (part instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) part).clause();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract void visit0(QueryPartInternal internal);
|
||||
|
||||
@Override
|
||||
|
||||
@ -40,9 +40,11 @@ import java.util.Map;
|
||||
|
||||
import org.jooq.AttachableInternal;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Param;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.conf.ParamType;
|
||||
|
||||
@ -95,6 +97,15 @@ abstract class AbstractDelegatingQuery<Q extends Query> extends AbstractQueryPar
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
if (delegate instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) delegate).clause();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSQL() {
|
||||
return delegate.getSQL();
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Comparator.EQUALS;
|
||||
import static org.jooq.Comparator.GREATER;
|
||||
import static org.jooq.Comparator.GREATER_OR_EQUAL;
|
||||
@ -72,6 +73,7 @@ import org.jooq.BetweenAndStep;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.CaseValueStep;
|
||||
import org.jooq.CaseWhenStep;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
@ -119,6 +121,11 @@ abstract class AbstractField<T> extends AbstractQueryPart implements Field<T> {
|
||||
@Override
|
||||
public abstract void bind(BindContext context);
|
||||
|
||||
@Override
|
||||
public /* non-final for now */ Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
@ -72,6 +75,11 @@ abstract class AbstractFunction<T> extends AbstractField<T> {
|
||||
ctx.visit(getFunction0(ctx.configuration()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
final Field<?>[] getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SQLSERVER;
|
||||
import static org.jooq.impl.DSL.function;
|
||||
@ -58,6 +59,7 @@ import org.jooq.AggregateFunction;
|
||||
import org.jooq.ArrayRecord;
|
||||
import org.jooq.AttachableInternal;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DataType;
|
||||
@ -290,6 +292,11 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
for (Parameter<?> parameter : getParameters()) {
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.Utils.fieldArray;
|
||||
import static org.jooq.util.sqlite.SQLiteDSL.rowid;
|
||||
|
||||
@ -49,6 +50,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.ExecuteContext;
|
||||
@ -83,7 +85,7 @@ abstract class AbstractStoreQuery<R extends Record> extends AbstractQuery implem
|
||||
super(configuration);
|
||||
|
||||
this.into = into;
|
||||
this.returning = new QueryPartList<Field<?>>();
|
||||
this.returning = new QueryPartList<Field<?>>(DUMMY);
|
||||
}
|
||||
|
||||
protected abstract Map<Field<?>, Field<?>> getValues();
|
||||
@ -147,14 +149,17 @@ abstract class AbstractStoreQuery<R extends Record> extends AbstractQuery implem
|
||||
return returned;
|
||||
}
|
||||
|
||||
final void toSQLReturning(RenderContext context) {
|
||||
final void toSQLReturning(RenderContext context, Clause clause) {
|
||||
if (!returning.isEmpty()) {
|
||||
switch (context.configuration().dialect()) {
|
||||
case FIREBIRD:
|
||||
case POSTGRES:
|
||||
context.formatSeparator()
|
||||
.keyword("returning ")
|
||||
.visit(returning);
|
||||
.start(clause)
|
||||
.keyword("returning")
|
||||
.sql(" ")
|
||||
.visit(returning)
|
||||
.end(clause);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DERBY;
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
@ -55,6 +56,7 @@ import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.Utils.list;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
@ -221,6 +223,11 @@ class Alias<Q extends QueryPart> extends AbstractQueryPart {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean declaresFields() {
|
||||
return true;
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.fieldByName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -42,6 +43,7 @@ import java.util.List;
|
||||
|
||||
import org.jooq.ArrayRecord;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Param;
|
||||
@ -173,6 +175,11 @@ class ArrayTable extends AbstractTable<Record> {
|
||||
ctx.visit(table(ctx.configuration()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final Table<Record> table(Configuration configuration) {
|
||||
switch (configuration.dialect().family()) {
|
||||
case ORACLE: {
|
||||
@ -296,6 +303,11 @@ class ArrayTable extends AbstractTable<Record> {
|
||||
context.visit(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<Record> fields0() {
|
||||
return ArrayTable.this.fields0();
|
||||
|
||||
@ -35,12 +35,14 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.falseCondition;
|
||||
import static org.jooq.impl.DSL.fieldByName;
|
||||
import static org.jooq.impl.DSL.one;
|
||||
import static org.jooq.impl.DSL.using;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
@ -126,6 +128,11 @@ class ArrayTableSimulation extends AbstractTable<Record> {
|
||||
ctx.visit(table(ctx.configuration()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<Record> fields0() {
|
||||
return field;
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_BETWEEN;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -53,6 +54,7 @@ import static org.jooq.impl.DSL.val;
|
||||
|
||||
import org.jooq.BetweenAndStep;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -106,6 +108,11 @@ class BetweenCondition<T> extends AbstractCondition implements BetweenAndStep<T>
|
||||
delegate(ctx.configuration()).toSQL(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_BETWEEN;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
if (symmetric && asList(ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, MARIADB, MYSQL, ORACLE, SQLSERVER, SQLITE, SYBASE).contains(configuration.dialect().family())) {
|
||||
if (not) {
|
||||
@ -142,5 +149,10 @@ class BetweenCondition<T> extends AbstractCondition implements BetweenAndStep<T>
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(field).visit(minValue).visit(maxValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_BETWEEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,11 +35,14 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.CaseConditionStep;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -137,4 +140,9 @@ class CaseConditionStepImpl<T> extends AbstractField<T> implements CaseCondition
|
||||
context.keyword("end")
|
||||
.formatIndentLockEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,11 +35,14 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CATALOG;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Catalog;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.tools.StringUtils;
|
||||
@ -78,6 +81,11 @@ public class CatalogImpl extends AbstractQueryPart implements Catalog {
|
||||
context.literal(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CATALOG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Schema getSchema(String name) {
|
||||
for (Schema schema : getSchemas()) {
|
||||
|
||||
@ -36,6 +36,9 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_AND;
|
||||
import static org.jooq.Clause.CONDITION_OR;
|
||||
import static org.jooq.Operator.AND;
|
||||
import static org.jooq.impl.DSL.trueCondition;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
@ -44,6 +47,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Operator;
|
||||
import org.jooq.RenderContext;
|
||||
@ -94,6 +98,11 @@ class CombinedCondition extends AbstractCondition {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return operator == AND ? CONDITION_AND : CONDITION_OR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
visitAll(context, conditions);
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
import static org.jooq.Comparator.LIKE;
|
||||
import static org.jooq.Comparator.LIKE_IGNORE_CASE;
|
||||
import static org.jooq.Comparator.NOT_LIKE;
|
||||
@ -47,6 +48,7 @@ import static org.jooq.SQLDialect.DERBY;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -127,4 +129,9 @@ class CompareCondition extends AbstractCondition {
|
||||
.sql("'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.ConditionProvider;
|
||||
import org.jooq.Field;
|
||||
@ -121,6 +122,11 @@ class ConditionProviderImpl extends AbstractQueryPart implements ConditionProvid
|
||||
context.visit(getWhere());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Condition API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -35,10 +35,12 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.val;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -82,6 +84,11 @@ class Contains<T> extends AbstractCondition {
|
||||
context.visit(condition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
|
||||
private final Condition condition() {
|
||||
|
||||
// [#1107] Some dialects support "contains" operations for ARRAYs
|
||||
@ -124,6 +131,11 @@ class Contains<T> extends AbstractCondition {
|
||||
context.visit(lhs).visit(rhs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
|
||||
private final Field<T> rhs() {
|
||||
return (rhs == null) ? val(value, lhs) : rhs;
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
@ -86,6 +87,20 @@ public abstract class CustomCondition extends AbstractCondition {
|
||||
@Override
|
||||
public abstract void bind(BindContext context) throws DataAccessException;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Implementation optional
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Subclasses may implement this method
|
||||
* <hr/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Clause clause() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// No further overrides allowed
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -88,9 +89,19 @@ public abstract class CustomField<T> extends AbstractField<T> {
|
||||
public abstract void bind(BindContext context) throws DataAccessException;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Further overrides allowed
|
||||
// Implementation optional
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Subclasses may implement this method
|
||||
* <hr/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Clause clause() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// No further overrides allowed
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
@ -97,6 +98,20 @@ public abstract class CustomQueryPart extends AbstractQueryPart {
|
||||
@Override
|
||||
public abstract void bind(BindContext context) throws DataAccessException;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Implementation optional
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Subclasses may implement this method
|
||||
* <hr/>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Clause clause() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// No further overrides allowed
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -7766,7 +7767,7 @@ public class DSL {
|
||||
WrappedList[] array = new WrappedList[fieldSets.length];
|
||||
|
||||
for (int i = 0; i < fieldSets.length; i++) {
|
||||
array[i] = new WrappedList(new QueryPartList<Field<?>>(fieldSets[i]));
|
||||
array[i] = new WrappedList(new QueryPartList<Field<?>>(DUMMY, fieldSets[i]));
|
||||
}
|
||||
|
||||
return new Function<Object>("grouping sets", SQLDataType.OTHER, array);
|
||||
|
||||
@ -55,6 +55,7 @@ import org.jooq.RecordListenerProvider;
|
||||
import org.jooq.RecordMapperProvider;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.SchemaMapping;
|
||||
import org.jooq.VisitListenerProvider;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.conf.SettingsTools;
|
||||
|
||||
@ -84,6 +85,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
private transient RecordMapperProvider recordMapperProvider;
|
||||
private transient RecordListenerProvider[] recordListenerProviders;
|
||||
private transient ExecuteListenerProvider[] executeListenerProviders;
|
||||
private transient VisitListenerProvider[] visitListenerProviders;
|
||||
|
||||
// Derived objects
|
||||
private org.jooq.SchemaMapping mapping;
|
||||
@ -100,14 +102,29 @@ public class DefaultConfiguration implements Configuration {
|
||||
* through the various <code>derive()</code> or <code>set()</code> methods.
|
||||
*/
|
||||
public DefaultConfiguration() {
|
||||
this(SQL99);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new "empty" configuration object given a {@link SQLDialect}.
|
||||
* <p>
|
||||
* This can be used as is, as a "dummy" configuration object, or as a base
|
||||
* implementation for creating more sophisticated "derived" configurations
|
||||
* through the various <code>derive()</code> or <code>set()</code> methods.
|
||||
*
|
||||
* @param dialect The pre-existing {@link SQLDialect}.
|
||||
*/
|
||||
DefaultConfiguration(SQLDialect dialect) {
|
||||
this(
|
||||
new NoConnectionProvider(),
|
||||
new DefaultRecordMapperProvider(),
|
||||
new RecordListenerProvider[0],
|
||||
new ExecuteListenerProvider[0],
|
||||
SQL99,
|
||||
new VisitListenerProvider[0],
|
||||
dialect,
|
||||
SettingsTools.defaultSettings(),
|
||||
null);
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,6 +141,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
configuration.recordMapperProvider(),
|
||||
configuration.recordListenerProviders(),
|
||||
configuration.executeListenerProviders(),
|
||||
configuration.visitListenerProviders(),
|
||||
configuration.dialect(),
|
||||
configuration.settings(),
|
||||
configuration.data()
|
||||
@ -143,6 +161,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
RecordMapperProvider recordMapperProvider,
|
||||
RecordListenerProvider[] recordListenerProviders,
|
||||
ExecuteListenerProvider[] executeListenerProviders,
|
||||
VisitListenerProvider[] visitListenerProviders,
|
||||
SQLDialect dialect,
|
||||
Settings settings,
|
||||
Map<Object, Object> data)
|
||||
@ -151,6 +170,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
set(recordMapperProvider);
|
||||
set(recordListenerProviders);
|
||||
set(executeListenerProviders);
|
||||
set(visitListenerProviders);
|
||||
set(dialect);
|
||||
set(settings);
|
||||
|
||||
@ -181,6 +201,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
recordMapperProvider,
|
||||
recordListenerProviders,
|
||||
executeListenerProviders,
|
||||
visitListenerProviders,
|
||||
dialect,
|
||||
settings,
|
||||
data
|
||||
@ -197,6 +218,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
newRecordMapperProvider,
|
||||
recordListenerProviders,
|
||||
executeListenerProviders,
|
||||
visitListenerProviders,
|
||||
dialect,
|
||||
settings,
|
||||
data
|
||||
@ -207,12 +229,13 @@ public class DefaultConfiguration implements Configuration {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Configuration derive(RecordListenerProvider... newRecordListenerProviders) {
|
||||
public final Configuration derive(RecordListenerProvider... newRecordListenerProviders) {
|
||||
return new DefaultConfiguration(
|
||||
connectionProvider,
|
||||
recordMapperProvider,
|
||||
newRecordListenerProviders,
|
||||
executeListenerProviders,
|
||||
visitListenerProviders,
|
||||
dialect,
|
||||
settings,
|
||||
data
|
||||
@ -229,6 +252,24 @@ public class DefaultConfiguration implements Configuration {
|
||||
recordMapperProvider,
|
||||
recordListenerProviders,
|
||||
newExecuteListenerProviders,
|
||||
visitListenerProviders,
|
||||
dialect,
|
||||
settings,
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final Configuration derive(VisitListenerProvider... newVisitListenerProviders) {
|
||||
return new DefaultConfiguration(
|
||||
connectionProvider,
|
||||
recordMapperProvider,
|
||||
recordListenerProviders,
|
||||
executeListenerProviders,
|
||||
newVisitListenerProviders,
|
||||
dialect,
|
||||
settings,
|
||||
data
|
||||
@ -245,6 +286,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
recordMapperProvider,
|
||||
recordListenerProviders,
|
||||
executeListenerProviders,
|
||||
visitListenerProviders,
|
||||
newDialect,
|
||||
settings,
|
||||
data
|
||||
@ -261,6 +303,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
recordMapperProvider,
|
||||
recordListenerProviders,
|
||||
executeListenerProviders,
|
||||
visitListenerProviders,
|
||||
dialect,
|
||||
newSettings,
|
||||
data
|
||||
@ -271,15 +314,6 @@ public class DefaultConfiguration implements Configuration {
|
||||
// XXX: Changing configurations
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final Configuration set(SQLDialect newDialect) {
|
||||
this.dialect = newDialect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -305,12 +339,11 @@ public class DefaultConfiguration implements Configuration {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final Configuration set(Settings newSettings) {
|
||||
this.settings = newSettings != null
|
||||
? SettingsTools.clone(newSettings)
|
||||
: SettingsTools.defaultSettings();
|
||||
public final Configuration set(RecordListenerProvider... newRecordListenerProviders) {
|
||||
this.recordListenerProviders = newRecordListenerProviders != null
|
||||
? newRecordListenerProviders
|
||||
: new RecordListenerProvider[0];
|
||||
|
||||
this.mapping = new SchemaMapping(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -330,26 +363,40 @@ public class DefaultConfiguration implements Configuration {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final Configuration set(RecordListenerProvider... newRecordListenerProviders) {
|
||||
this.recordListenerProviders = newRecordListenerProviders != null
|
||||
? newRecordListenerProviders
|
||||
: new RecordListenerProvider[0];
|
||||
public final Configuration set(VisitListenerProvider... newVisitListenerProviders) {
|
||||
this.visitListenerProviders = newVisitListenerProviders != null
|
||||
? newVisitListenerProviders
|
||||
: new VisitListenerProvider[0];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final Configuration set(SQLDialect newDialect) {
|
||||
this.dialect = newDialect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final Configuration set(Settings newSettings) {
|
||||
this.settings = newSettings != null
|
||||
? SettingsTools.clone(newSettings)
|
||||
: SettingsTools.defaultSettings();
|
||||
|
||||
this.mapping = new SchemaMapping(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: Getters
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final SQLDialect dialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -362,7 +409,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public RecordMapperProvider recordMapperProvider() {
|
||||
public final RecordMapperProvider recordMapperProvider() {
|
||||
return recordMapperProvider;
|
||||
}
|
||||
|
||||
@ -370,9 +417,32 @@ public class DefaultConfiguration implements Configuration {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public final org.jooq.SchemaMapping schemaMapping() {
|
||||
return mapping;
|
||||
public final RecordListenerProvider[] recordListenerProviders() {
|
||||
return recordListenerProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final ExecuteListenerProvider[] executeListenerProviders() {
|
||||
return executeListenerProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final VisitListenerProvider[] visitListenerProviders() {
|
||||
return visitListenerProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final SQLDialect dialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -411,16 +481,9 @@ public class DefaultConfiguration implements Configuration {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final ExecuteListenerProvider[] executeListenerProviders() {
|
||||
return executeListenerProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public RecordListenerProvider[] recordListenerProviders() {
|
||||
return recordListenerProviders;
|
||||
@Deprecated
|
||||
public final org.jooq.SchemaMapping schemaMapping() {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -452,6 +515,7 @@ public class DefaultConfiguration implements Configuration {
|
||||
|
||||
oos.writeObject(cloneSerializables(executeListenerProviders));
|
||||
oos.writeObject(cloneSerializables(recordListenerProviders));
|
||||
oos.writeObject(cloneSerializables(visitListenerProviders));
|
||||
}
|
||||
|
||||
private <E> E[] cloneSerializables(E[] array) {
|
||||
@ -473,5 +537,6 @@ public class DefaultConfiguration implements Configuration {
|
||||
recordMapperProvider = (RecordMapperProvider) ois.readObject();
|
||||
executeListenerProviders = (ExecuteListenerProvider[]) ois.readObject();
|
||||
recordListenerProviders = (RecordListenerProvider[]) ois.readObject();
|
||||
visitListenerProviders = (VisitListenerProvider[]) ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
|
||||
}
|
||||
|
||||
public DefaultDSLContext(SQLDialect dialect, Settings settings) {
|
||||
this(new DefaultConfiguration(new NoConnectionProvider(), null, null, null, dialect, settings, null));
|
||||
this(new DefaultConfiguration(new NoConnectionProvider(), null, null, null, null, dialect, settings, null));
|
||||
}
|
||||
|
||||
public DefaultDSLContext(Connection connection, SQLDialect dialect) {
|
||||
@ -210,7 +210,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
|
||||
}
|
||||
|
||||
public DefaultDSLContext(Connection connection, SQLDialect dialect, Settings settings) {
|
||||
this(new DefaultConfiguration(new DefaultConnectionProvider(connection), null, null, null, dialect, settings, null));
|
||||
this(new DefaultConfiguration(new DefaultConnectionProvider(connection), null, null, null, null, dialect, settings, null));
|
||||
}
|
||||
|
||||
public DefaultDSLContext(DataSource datasource, SQLDialect dialect) {
|
||||
@ -218,7 +218,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
|
||||
}
|
||||
|
||||
public DefaultDSLContext(DataSource datasource, SQLDialect dialect, Settings settings) {
|
||||
this(new DefaultConfiguration(new DataSourceConnectionProvider(datasource), null, null, null, dialect, settings, null));
|
||||
this(new DefaultConfiguration(new DataSourceConnectionProvider(datasource), null, null, null, null, dialect, settings, null));
|
||||
}
|
||||
|
||||
public DefaultDSLContext(ConnectionProvider connectionProvider, SQLDialect dialect) {
|
||||
@ -226,7 +226,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
|
||||
}
|
||||
|
||||
public DefaultDSLContext(ConnectionProvider connectionProvider, SQLDialect dialect, Settings settings) {
|
||||
this(new DefaultConfiguration(connectionProvider, null, null, null, dialect, settings, null));
|
||||
this(new DefaultConfiguration(connectionProvider, null, null, null, null, dialect, settings, null));
|
||||
}
|
||||
|
||||
public DefaultDSLContext(Configuration configuration) {
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.jooq.VisitListener;
|
||||
import org.jooq.VisitListenerProvider;
|
||||
|
||||
/**
|
||||
* A default implementation for {@link VisitListenerProvider}.
|
||||
* <p>
|
||||
* This implementation just wraps an instance of {@link VisitListener}, always
|
||||
* providing the same.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultVisitListenerProvider implements VisitListenerProvider, Serializable {
|
||||
|
||||
/**
|
||||
* Generated UID.
|
||||
*/
|
||||
private static final long serialVersionUID = -2122007794302549679L;
|
||||
|
||||
/**
|
||||
* The delegate listener.
|
||||
*/
|
||||
private final VisitListener listener;
|
||||
|
||||
/**
|
||||
* Convenience method to construct an array of
|
||||
* <code>DefaultVisitListenerProvider</code> from an array of
|
||||
* <code>VisitListener</code> instances.
|
||||
*/
|
||||
public static VisitListenerProvider[] providers(VisitListener... listeners) {
|
||||
VisitListenerProvider[] result = new VisitListenerProvider[listeners.length];
|
||||
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
result[i] = new DefaultVisitListenerProvider(listeners[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new provider instance from an argument listener.
|
||||
*
|
||||
* @param listener The argument listener.
|
||||
*/
|
||||
public DefaultVisitListenerProvider(VisitListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public final VisitListener provide() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return listener.toString();
|
||||
}
|
||||
}
|
||||
@ -37,12 +37,14 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DELETE;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DeleteQuery;
|
||||
@ -131,4 +133,9 @@ class DeleteQueryImpl<R extends Record> extends AbstractQuery implements DeleteQ
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(getFrom()).visit(getWhere());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DELETE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.condition;
|
||||
import static org.jooq.impl.DSL.exists;
|
||||
import static org.jooq.impl.DSL.notExists;
|
||||
@ -74,7 +75,7 @@ implements
|
||||
this.divisor = divisor;
|
||||
|
||||
this.condition = new ConditionProviderImpl();
|
||||
this.returning = new QueryPartList<Field<?>>();
|
||||
this.returning = new QueryPartList<Field<?>>(DUMMY);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.TABLE;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Schema;
|
||||
@ -124,6 +127,11 @@ class Dual extends AbstractTable<Record> {
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return TABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<Record> fields0() {
|
||||
return new Fields<Record>();
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -99,7 +100,7 @@ class Expression<T> extends AbstractFunction<T> {
|
||||
|
||||
this.operator = operator;
|
||||
this.lhs = lhs;
|
||||
this.rhs = new QueryPartList<Field<?>>(rhs);
|
||||
this.rhs = new QueryPartList<Field<?>>(DUMMY, rhs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
/**
|
||||
@ -54,5 +57,10 @@ class FalseCondition extends AbstractCondition {
|
||||
context.sql("1 = 0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
|
||||
FalseCondition() {}
|
||||
}
|
||||
|
||||
@ -35,10 +35,12 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.condition;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QueryPartInternal;
|
||||
@ -69,6 +71,11 @@ class FieldCondition extends AbstractCondition {
|
||||
delegate(ctx.configuration()).bind(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
switch (configuration.dialect().family()) {
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -42,6 +43,7 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -136,6 +138,11 @@ class FieldMapForInsert extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
visitAll(context, values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
final void putFields(Collection<? extends Field<?>> fields) {
|
||||
for (Field<?> field : fields) {
|
||||
put(field, null);
|
||||
|
||||
@ -36,12 +36,15 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Clause.UPDATE_SET_ASSIGNMENT;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SQLITE;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -79,11 +82,13 @@ class FieldMapForUpdate extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
context.formatNewLine();
|
||||
}
|
||||
|
||||
context.qualify(supportsQualify)
|
||||
context.start(UPDATE_SET_ASSIGNMENT)
|
||||
.qualify(supportsQualify)
|
||||
.visit(entry.getKey())
|
||||
.qualify(restoreQualify)
|
||||
.sql(" = ")
|
||||
.visit(entry.getValue());
|
||||
.visit(entry.getValue())
|
||||
.end(UPDATE_SET_ASSIGNMENT);
|
||||
|
||||
separator = ", ";
|
||||
}
|
||||
@ -101,6 +106,11 @@ class FieldMapForUpdate extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
final void set(Map<? extends Field<?>, ?> map) {
|
||||
for (Entry<? extends Field<?>, ?> entry : map.entrySet()) {
|
||||
Field<?> field = entry.getKey();
|
||||
|
||||
@ -35,12 +35,14 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Select;
|
||||
@ -137,6 +139,11 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
visitAll(context, insertMaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The FieldMapsForInsert API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -36,14 +36,17 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.RecordType;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
/**
|
||||
* A simple wrapper for <code>Field[]</code>, providing some useful lookup
|
||||
@ -246,12 +249,17 @@ class Fields<R extends Record> extends AbstractQueryPart implements RecordType<R
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
new QueryPartList<Field<?>>(fields).toSQL(context);
|
||||
new QueryPartList<Field<?>>(DUMMY, fields).toSQL(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
new QueryPartList<Field<?>>(fields).bind(context);
|
||||
new QueryPartList<Field<?>>(DUMMY, fields).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -35,10 +35,12 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.keyword;
|
||||
import static org.jooq.impl.DSL.val;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
@ -143,6 +145,11 @@ implements VersionsBetweenAndStep<R, T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean declaresTables() {
|
||||
return true;
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
@ -54,6 +55,7 @@ import java.util.Collection;
|
||||
|
||||
import org.jooq.AggregateFunction;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Name;
|
||||
@ -136,10 +138,10 @@ class Function<T> extends AbstractField<T> implements
|
||||
this.term = null;
|
||||
this.name = null;
|
||||
this.distinct = distinct;
|
||||
this.arguments = new QueryPartList<QueryPart>(arguments);
|
||||
this.arguments = new QueryPartList<QueryPart>(DUMMY, arguments);
|
||||
this.keepDenseRankOrderBy = new SortFieldList();
|
||||
this.withinGroupOrderBy = new SortFieldList();
|
||||
this.partitionBy = new QueryPartList<Field<?>>();
|
||||
this.partitionBy = new QueryPartList<Field<?>>(DUMMY);
|
||||
this.orderBy = new SortFieldList();
|
||||
}
|
||||
|
||||
@ -149,10 +151,10 @@ class Function<T> extends AbstractField<T> implements
|
||||
this.term = term;
|
||||
this.name = null;
|
||||
this.distinct = distinct;
|
||||
this.arguments = new QueryPartList<QueryPart>(arguments);
|
||||
this.arguments = new QueryPartList<QueryPart>(DUMMY, arguments);
|
||||
this.keepDenseRankOrderBy = new SortFieldList();
|
||||
this.withinGroupOrderBy = new SortFieldList();
|
||||
this.partitionBy = new QueryPartList<Field<?>>();
|
||||
this.partitionBy = new QueryPartList<Field<?>>(DUMMY);
|
||||
this.orderBy = new SortFieldList();
|
||||
}
|
||||
|
||||
@ -162,10 +164,10 @@ class Function<T> extends AbstractField<T> implements
|
||||
this.term = null;
|
||||
this.name = name;
|
||||
this.distinct = distinct;
|
||||
this.arguments = new QueryPartList<QueryPart>(arguments);
|
||||
this.arguments = new QueryPartList<QueryPart>(DUMMY, arguments);
|
||||
this.keepDenseRankOrderBy = new SortFieldList();
|
||||
this.withinGroupOrderBy = new SortFieldList();
|
||||
this.partitionBy = new QueryPartList<Field<?>>();
|
||||
this.partitionBy = new QueryPartList<Field<?>>(DUMMY);
|
||||
this.orderBy = new SortFieldList();
|
||||
}
|
||||
|
||||
@ -182,8 +184,12 @@ class Function<T> extends AbstractField<T> implements
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
if (term == LIST_AGG && asList(CUBRID, H2, HSQLDB, MARIADB, MYSQL).contains(context.configuration().dialect())) {
|
||||
context.visit(arguments.get(0));
|
||||
context.visit(withinGroupOrderBy);
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
@ -101,6 +104,11 @@ class FunctionTable<R extends Record> extends AbstractTable<R> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<R> fields0() {
|
||||
return new Fields<R>();
|
||||
|
||||
@ -36,12 +36,16 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_IN;
|
||||
import static org.jooq.Clause.CONDITION_IN_NOT;
|
||||
import static org.jooq.Comparator.IN;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -64,6 +68,11 @@ class InCondition<T> extends AbstractCondition {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return comparator == IN ? CONDITION_IN : CONDITION_IN_NOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(field);
|
||||
@ -93,11 +102,13 @@ class InCondition<T> extends AbstractCondition {
|
||||
// operator
|
||||
if (comparator == Comparator.IN) {
|
||||
context.formatSeparator()
|
||||
.keyword("or ");
|
||||
.keyword("or")
|
||||
.sql(" ");
|
||||
}
|
||||
else {
|
||||
context.formatSeparator()
|
||||
.keyword("and ");
|
||||
.keyword("and")
|
||||
.sql(" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.INSERT;
|
||||
import static org.jooq.Clause.INSERT_RETURNING;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
|
||||
@ -45,6 +47,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -313,16 +316,23 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return INSERT;
|
||||
}
|
||||
|
||||
private final void toSQLInsert(RenderContext context) {
|
||||
context.keyword("insert ")
|
||||
context.keyword("insert")
|
||||
.sql(" ")
|
||||
// [#1295] MySQL natively supports the IGNORE keyword
|
||||
.keyword((onDuplicateKeyIgnore && asList(MARIADB, MYSQL).contains(context.configuration().dialect())) ? "ignore " : "")
|
||||
.keyword("into ")
|
||||
.keyword("into")
|
||||
.sql(" ")
|
||||
.visit(getInto())
|
||||
.sql(" ")
|
||||
.visit(insertMaps);
|
||||
|
||||
toSQLReturning(context);
|
||||
toSQLReturning(context, INSERT_RETURNING);
|
||||
}
|
||||
|
||||
private final void bindInsert(BindContext context) {
|
||||
|
||||
@ -35,9 +35,11 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.INSERT;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Insert;
|
||||
@ -70,7 +72,8 @@ class InsertSelectQueryImpl<R extends Record> extends AbstractQuery implements I
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.keyword("insert into ")
|
||||
context.keyword("insert into")
|
||||
.sql(" ")
|
||||
.visit(into)
|
||||
.sql(" (");
|
||||
|
||||
@ -93,4 +96,9 @@ class InsertSelectQueryImpl<R extends Record> extends AbstractQuery implements I
|
||||
visitAll(context, fields);
|
||||
context.visit(select);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return INSERT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -53,6 +54,7 @@ import static org.jooq.impl.DSL.one;
|
||||
import static org.jooq.impl.DSL.zero;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -94,6 +96,11 @@ class IsDistinctFrom<T> extends AbstractCondition {
|
||||
delegate(context.configuration()).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a delegate <code>CompareCondition</code>, in case the context
|
||||
* {@link SQLDialect} natively supports the <code>IS DISTINCT FROM</code>
|
||||
|
||||
@ -36,7 +36,11 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_NULL;
|
||||
import static org.jooq.Clause.CONDITION_NULL_NOT;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -62,6 +66,11 @@ class IsNull extends AbstractCondition {
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.visit(field).keyword(isNull ? " is null" : " is not null");
|
||||
context.visit(field).sql(" ").keyword(isNull ? "is null" : "is not null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return isNull ? CONDITION_NULL : CONDITION_NULL_NOT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,19 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Clause.TABLE_JOIN;
|
||||
import static org.jooq.Clause.TABLE_JOIN_CROSS;
|
||||
import static org.jooq.Clause.TABLE_JOIN_INNER;
|
||||
import static org.jooq.Clause.TABLE_JOIN_NATURAL;
|
||||
import static org.jooq.Clause.TABLE_JOIN_NATURAL_OUTER_LEFT;
|
||||
import static org.jooq.Clause.TABLE_JOIN_NATURAL_OUTER_RIGHT;
|
||||
import static org.jooq.Clause.TABLE_JOIN_ON;
|
||||
import static org.jooq.Clause.TABLE_JOIN_OUTER_FULL;
|
||||
import static org.jooq.Clause.TABLE_JOIN_OUTER_LEFT;
|
||||
import static org.jooq.Clause.TABLE_JOIN_OUTER_RIGHT;
|
||||
import static org.jooq.Clause.TABLE_JOIN_PARTITION_BY;
|
||||
import static org.jooq.Clause.TABLE_JOIN_USING;
|
||||
import static org.jooq.JoinType.CROSS_JOIN;
|
||||
import static org.jooq.JoinType.JOIN;
|
||||
import static org.jooq.JoinType.LEFT_OUTER_JOIN;
|
||||
@ -59,6 +72,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
@ -101,11 +115,11 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
|
||||
|
||||
this.lhs = lhs.asTable();
|
||||
this.rhs = rhs.asTable();
|
||||
this.rhsPartitionBy = new QueryPartList<Field<?>>();
|
||||
this.rhsPartitionBy = new QueryPartList<Field<?>>(DUMMY);
|
||||
this.type = type;
|
||||
|
||||
this.condition = new ConditionProviderImpl();
|
||||
this.using = new QueryPartList<Field<?>>();
|
||||
this.using = new QueryPartList<Field<?>>(DUMMY);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -125,10 +139,14 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
JoinType translatedType = translateType(context);
|
||||
Clause translatedClause = translateClause(translatedType);
|
||||
|
||||
context.visit(lhs)
|
||||
.formatIndentStart()
|
||||
.formatSeparator()
|
||||
.keyword(translateType(context).toSQL())
|
||||
.start(translatedClause)
|
||||
.keyword(translatedType.toSQL())
|
||||
.sql(" ");
|
||||
|
||||
// [#671] Some databases formally require nested JOINS to be
|
||||
@ -151,20 +169,41 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
|
||||
// OUTER JOINed table
|
||||
if (!rhsPartitionBy.isEmpty()) {
|
||||
context.formatSeparator()
|
||||
.keyword("partition by (")
|
||||
.start(TABLE_JOIN_PARTITION_BY)
|
||||
.keyword("partition by")
|
||||
.sql(" (")
|
||||
.visit(rhsPartitionBy)
|
||||
.sql(")");
|
||||
.sql(")")
|
||||
.end(TABLE_JOIN_PARTITION_BY);
|
||||
}
|
||||
|
||||
// CROSS JOIN and NATURAL JOIN do not have any condition clauses
|
||||
if (!asList(CROSS_JOIN,
|
||||
NATURAL_JOIN,
|
||||
NATURAL_LEFT_OUTER_JOIN,
|
||||
NATURAL_RIGHT_OUTER_JOIN).contains(translateType(context))) {
|
||||
NATURAL_RIGHT_OUTER_JOIN).contains(translatedType)) {
|
||||
toSQLJoinCondition(context);
|
||||
}
|
||||
|
||||
context.formatIndentEnd();
|
||||
context.end(translatedClause)
|
||||
.formatIndentEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the join type into a join clause
|
||||
*/
|
||||
final Clause translateClause(JoinType translatedType) {
|
||||
switch (translatedType) {
|
||||
case JOIN: return TABLE_JOIN_INNER;
|
||||
case CROSS_JOIN: return TABLE_JOIN_CROSS;
|
||||
case NATURAL_JOIN: return TABLE_JOIN_NATURAL;
|
||||
case LEFT_OUTER_JOIN: return TABLE_JOIN_OUTER_LEFT;
|
||||
case RIGHT_OUTER_JOIN: return TABLE_JOIN_OUTER_RIGHT;
|
||||
case FULL_OUTER_JOIN: return TABLE_JOIN_OUTER_FULL;
|
||||
case NATURAL_LEFT_OUTER_JOIN: return TABLE_JOIN_NATURAL_OUTER_LEFT;
|
||||
case NATURAL_RIGHT_OUTER_JOIN: return TABLE_JOIN_NATURAL_OUTER_RIGHT;
|
||||
default: throw new IllegalArgumentException("Bad join type: " + translatedType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,24 +249,38 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
|
||||
// [#582] Some dialects don't explicitly support a JOIN .. USING
|
||||
// syntax. This can be simulated with JOIN .. ON
|
||||
if (asList(ASE, CUBRID, DB2, H2, SQLSERVER, SYBASE).contains(context.configuration().dialect().family())) {
|
||||
String glue = "on ";
|
||||
boolean first = true;
|
||||
for (Field<?> field : using) {
|
||||
context.formatSeparator()
|
||||
.keyword(glue)
|
||||
context.formatSeparator();
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
|
||||
context.start(TABLE_JOIN_ON)
|
||||
.keyword("on");
|
||||
}
|
||||
else {
|
||||
context.keyword("and");
|
||||
}
|
||||
|
||||
context.sql(" ")
|
||||
.visit(lhs.field(field))
|
||||
.sql(" = ")
|
||||
.visit(rhs.field(field));
|
||||
|
||||
glue = "and ";
|
||||
}
|
||||
|
||||
context.end(TABLE_JOIN_ON);
|
||||
}
|
||||
|
||||
// Native supporters of JOIN .. USING
|
||||
else {
|
||||
context.formatSeparator()
|
||||
.keyword("using (");
|
||||
.start(TABLE_JOIN_USING)
|
||||
.keyword("using")
|
||||
.sql("( ");
|
||||
Utils.fieldNames(context, using);
|
||||
context.sql(")");
|
||||
context.sql(")")
|
||||
.end(TABLE_JOIN_USING);
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,27 +290,41 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
|
||||
simulateNaturalLeftOuterJoin(context) ||
|
||||
simulateNaturalRightOuterJoin(context)) {
|
||||
|
||||
String glue = "on ";
|
||||
boolean first = true;
|
||||
for (Field<?> field : lhs.fields()) {
|
||||
Field<?> other = rhs.field(field);
|
||||
|
||||
if (other != null) {
|
||||
context.formatSeparator()
|
||||
.keyword(glue)
|
||||
context.formatSeparator();
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
|
||||
context.start(TABLE_JOIN_ON)
|
||||
.keyword("on");
|
||||
}
|
||||
else {
|
||||
context.keyword("and");
|
||||
}
|
||||
|
||||
context.sql(" ")
|
||||
.visit(field)
|
||||
.sql(" = ")
|
||||
.visit(other);
|
||||
|
||||
glue = "and ";
|
||||
}
|
||||
}
|
||||
|
||||
context.end(TABLE_JOIN_ON);
|
||||
}
|
||||
|
||||
// Regular JOIN condition
|
||||
else {
|
||||
context.formatSeparator()
|
||||
.keyword("on ")
|
||||
.visit(condition);
|
||||
.start(TABLE_JOIN_ON)
|
||||
.keyword("on")
|
||||
.sql(" ")
|
||||
.visit(condition)
|
||||
.end(TABLE_JOIN_ON);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,6 +340,11 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return TABLE_JOIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<Record> as(String alias) {
|
||||
return new TableAlias<Record>(this, alias, true);
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Keyword;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -64,4 +65,9 @@ public class KeywordImpl extends AbstractQueryPart implements Keyword {
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext ctx) {}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,12 +35,14 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
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;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Param;
|
||||
import org.jooq.RenderContext;
|
||||
@ -320,6 +322,11 @@ class Limit extends AbstractQueryPart {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this limit has an offset of zero
|
||||
*/
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Clause.MERGE;
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.impl.DSL.condition;
|
||||
import static org.jooq.impl.DSL.exists;
|
||||
@ -52,6 +54,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -230,7 +233,7 @@ implements
|
||||
|
||||
if (fields != null) {
|
||||
h2Style = true;
|
||||
h2Fields = new QueryPartList<Field<?>>(fields);
|
||||
h2Fields = new QueryPartList<Field<?>>(DUMMY, fields);
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,7 +243,7 @@ implements
|
||||
|
||||
QueryPartList<Field<?>> getH2Fields() {
|
||||
if (h2Fields == null) {
|
||||
h2Fields = new QueryPartList<Field<?>>(table.fields());
|
||||
h2Fields = new QueryPartList<Field<?>>(DUMMY, table.fields());
|
||||
}
|
||||
|
||||
return h2Fields;
|
||||
@ -248,7 +251,7 @@ implements
|
||||
|
||||
QueryPartList<Field<?>> getH2Keys() {
|
||||
if (h2Keys == null) {
|
||||
h2Keys = new QueryPartList<Field<?>>();
|
||||
h2Keys = new QueryPartList<Field<?>>(DUMMY);
|
||||
}
|
||||
|
||||
return h2Keys;
|
||||
@ -256,7 +259,7 @@ implements
|
||||
|
||||
QueryPartList<Field<?>> getH2Values() {
|
||||
if (h2Values == null) {
|
||||
h2Values = new QueryPartList<Field<?>>();
|
||||
h2Values = new QueryPartList<Field<?>>(DUMMY);
|
||||
}
|
||||
|
||||
return h2Values;
|
||||
@ -1194,4 +1197,9 @@ implements
|
||||
.visit(notMatchedInsert)
|
||||
.visit(notMatchedWhere);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return MERGE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,9 +35,12 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -72,6 +75,11 @@ class NameImpl extends AbstractQueryPart implements Name {
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String[] getName() {
|
||||
return qualifiedName;
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_NOT;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -58,4 +61,9 @@ class NotCondition extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_NOT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Package;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.SQLDialect;
|
||||
@ -85,6 +88,11 @@ public class PackageImpl extends AbstractQueryPart implements Package {
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: Object API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Parameter;
|
||||
@ -82,12 +85,17 @@ class ParameterImpl<T> extends AbstractQueryPart implements Parameter<T> {
|
||||
return type.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.literal(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.literal(getName());
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.conf.ParamType.INLINED;
|
||||
import static org.jooq.impl.DSL.trueCondition;
|
||||
import static org.jooq.impl.DSL.using;
|
||||
@ -44,6 +45,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -145,6 +147,11 @@ implements
|
||||
.declareTables(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private Table<Record> select(Configuration configuration) {
|
||||
List<Field<?>> groupingFields = new ArrayList<Field<?>>();
|
||||
List<Field<?>> aliasedGroupingFields = new ArrayList<Field<?>>();
|
||||
@ -261,6 +268,11 @@ implements
|
||||
.visit(table)
|
||||
.declareTables(declareTables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -317,6 +329,11 @@ implements
|
||||
context.visit(pivot(context.configuration()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<Record> as(String alias) {
|
||||
return new TableAlias<Record>(this, alias, true);
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.TABLE;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Table;
|
||||
@ -79,6 +82,11 @@ class QualifiedTable extends AbstractTable<Record> {
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return TABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Class<? extends Record> getRecordType() {
|
||||
return RecordImpl.class;
|
||||
|
||||
@ -37,7 +37,10 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QuantifiedSelect;
|
||||
@ -73,4 +76,9 @@ class QuantifiedComparisonCondition extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(field).visit(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,9 +35,11 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.table;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QuantifiedSelect;
|
||||
@ -114,6 +116,11 @@ class QuantifiedSelectImpl<R extends Record> extends AbstractQueryPart implement
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPart part(Configuration context) {
|
||||
if (query != null) {
|
||||
return query;
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -46,6 +47,7 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -55,22 +57,26 @@ import org.jooq.RenderContext;
|
||||
class QueryPartList<T extends QueryPart> extends AbstractQueryPart implements List<T> {
|
||||
|
||||
private static final long serialVersionUID = -2936922742534009564L;
|
||||
private final List<T> wrappedList = new ArrayList<T>();
|
||||
private final List<T> wrappedList;
|
||||
private final Clause clause;
|
||||
|
||||
QueryPartList() {
|
||||
this((Collection<T>) null);
|
||||
QueryPartList(Clause clause) {
|
||||
this(clause, (Collection<T>) null);
|
||||
}
|
||||
|
||||
QueryPartList(Collection<? extends T> wrappedList) {
|
||||
QueryPartList(Clause clause, Collection<? extends T> wrappedList) {
|
||||
super();
|
||||
|
||||
this.clause = clause;
|
||||
this.wrappedList = new ArrayList<T>();
|
||||
|
||||
if (wrappedList != null) {
|
||||
addAll(wrappedList);
|
||||
}
|
||||
}
|
||||
|
||||
QueryPartList(T... wrappedList) {
|
||||
this(Arrays.asList(wrappedList));
|
||||
QueryPartList(Clause clause, T... wrappedList) {
|
||||
this(clause, Arrays.asList(wrappedList));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -78,7 +84,13 @@ class QueryPartList<T extends QueryPart> extends AbstractQueryPart implements Li
|
||||
|
||||
// Some lists render different SQL when empty
|
||||
if (isEmpty()) {
|
||||
// if (clause != null && clause != DUMMY)
|
||||
// context.start(clause);
|
||||
|
||||
toSQLEmptyList(context);
|
||||
|
||||
// if (clause != null && clause != DUMMY)
|
||||
// context.end(clause);
|
||||
}
|
||||
|
||||
else {
|
||||
@ -94,7 +106,14 @@ class QueryPartList<T extends QueryPart> extends AbstractQueryPart implements Li
|
||||
if (indent)
|
||||
context.formatNewLine();
|
||||
|
||||
// if (clause != null && clause != DUMMY)
|
||||
// context.start(clause);
|
||||
|
||||
context.visit(queryPart);
|
||||
|
||||
// if (clause != null && clause != DUMMY)
|
||||
// context.end(clause);
|
||||
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
@ -108,6 +127,11 @@ class QueryPartList<T extends QueryPart> extends AbstractQueryPart implements Li
|
||||
visitAll(context, wrappedList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method
|
||||
*/
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -69,7 +72,9 @@ class RegexpLike extends AbstractCondition {
|
||||
case SQLITE:
|
||||
case SYBASE: {
|
||||
context.visit(search)
|
||||
.keyword(" regexp ")
|
||||
.sql(" ")
|
||||
.keyword("regexp")
|
||||
.sql(" ")
|
||||
.visit(pattern);
|
||||
|
||||
break;
|
||||
@ -109,7 +114,9 @@ class RegexpLike extends AbstractCondition {
|
||||
case SQLSERVER:
|
||||
default: {
|
||||
context.visit(search)
|
||||
.keyword(" like_regex ")
|
||||
.sql(" ")
|
||||
.keyword("like_regex")
|
||||
.sql(" ")
|
||||
.visit(pattern);
|
||||
|
||||
break;
|
||||
@ -121,4 +128,9 @@ class RegexpLike extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(search).visit(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.field;
|
||||
import static org.jooq.impl.DSL.function;
|
||||
|
||||
@ -61,7 +62,7 @@ class Rollup extends AbstractFunction<Object> {
|
||||
case CUBRID:
|
||||
case MARIADB:
|
||||
case MYSQL:
|
||||
return field("{0} {with rollup}", new QueryPartList<Field<?>>(getArguments()));
|
||||
return field("{0} {with rollup}", new QueryPartList<Field<?>>(DUMMY, getArguments()));
|
||||
|
||||
default:
|
||||
return function("rollup", Object.class, getArguments());
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_BETWEEN;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -76,6 +78,7 @@ import org.jooq.BetweenAndStep8;
|
||||
import org.jooq.BetweenAndStep9;
|
||||
import org.jooq.BetweenAndStepN;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -685,6 +688,11 @@ implements
|
||||
delegate(context.configuration()).toSQL(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
// These casts are safe for RowImpl
|
||||
RowN r = (RowN) row;
|
||||
@ -727,11 +735,17 @@ implements
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.visit(row)
|
||||
.keyword(not ? " not" : "")
|
||||
.keyword(" between ")
|
||||
.keyword(symmetric ? "symmetric " : "")
|
||||
.sql(not ? " " : "")
|
||||
.keyword(not ? "not" : "")
|
||||
.sql(" ")
|
||||
.keyword("between")
|
||||
.sql(" ")
|
||||
.keyword(symmetric ? "symmetric" : "")
|
||||
.sql(symmetric ? " " : "")
|
||||
.visit(minValue)
|
||||
.keyword(" and ")
|
||||
.sql(" ")
|
||||
.keyword("and")
|
||||
.sql(" ")
|
||||
.visit(maxValue);
|
||||
}
|
||||
|
||||
@ -739,5 +753,10 @@ implements
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(row).visit(minValue).visit(maxValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_BETWEEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Comparator.EQUALS;
|
||||
import static org.jooq.Comparator.GREATER;
|
||||
import static org.jooq.Comparator.GREATER_OR_EQUAL;
|
||||
@ -57,6 +59,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
@ -98,6 +101,11 @@ class RowCondition extends AbstractCondition {
|
||||
delegate(context.configuration()).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
SQLDialect dialect = configuration.dialect();
|
||||
|
||||
@ -206,5 +214,10 @@ class RowCondition extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(left).visit(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -66,6 +67,7 @@ import org.jooq.BetweenAndStep8;
|
||||
import org.jooq.BetweenAndStep9;
|
||||
import org.jooq.BetweenAndStepN;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.DataType;
|
||||
@ -200,6 +202,11 @@ implements
|
||||
context.visit(fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: Row accessor API
|
||||
// ------------------------------------------------------------------------
|
||||
@ -9910,13 +9917,13 @@ implements
|
||||
|
||||
@Override
|
||||
public final Condition in(Collection rows) {
|
||||
QueryPartList<Row> list = new QueryPartList<Row>(rows);
|
||||
QueryPartList<Row> list = new QueryPartList<Row>(DUMMY, rows);
|
||||
return new RowInCondition(this, list, Comparator.IN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Condition notIn(Collection rows) {
|
||||
QueryPartList<Row> list = new QueryPartList<Row>(rows);
|
||||
QueryPartList<Row> list = new QueryPartList<Row>(DUMMY, rows);
|
||||
return new RowInCondition(this, list, Comparator.NOT_IN);
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,11 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_IN;
|
||||
import static org.jooq.Clause.CONDITION_IN_NOT;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Comparator.EQUALS;
|
||||
import static org.jooq.Comparator.IN;
|
||||
import static org.jooq.Comparator.NOT_IN;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -51,6 +55,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
@ -89,6 +94,11 @@ class RowInCondition extends AbstractCondition {
|
||||
delegate(context.configuration()).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
if (asList(ASE, DB2, DERBY, FIREBIRD, INGRES, SQLSERVER, SQLITE, SYBASE).contains(configuration.dialect().family())) {
|
||||
List<Condition> conditions = new ArrayList<Condition>();
|
||||
@ -131,5 +141,10 @@ class RowInCondition extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(left).visit(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return comparator == IN ? CONDITION_IN : CONDITION_IN_NOT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,9 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_NULL;
|
||||
import static org.jooq.Clause.CONDITION_NULL_NOT;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
import static org.jooq.SQLDialect.DERBY;
|
||||
@ -53,6 +56,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -89,6 +93,11 @@ class RowIsNull extends AbstractCondition {
|
||||
delegate(context.configuration()).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
|
||||
// CUBRID 9.0.0 and HSQLDB have buggy implementations of the NULL predicate.
|
||||
@ -125,5 +134,10 @@ class RowIsNull extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return isNull ? CONDITION_NULL : CONDITION_NULL_NOT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_OVERLAPS;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -51,6 +53,7 @@ import static org.jooq.SQLDialect.SQLSERVER;
|
||||
import static org.jooq.SQLDialect.SYBASE;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
@ -86,6 +89,11 @@ class RowOverlapsCondition<T1, T2> extends AbstractCondition {
|
||||
delegate(context.configuration()).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration) {
|
||||
Field<T1> left1 = left.field1();
|
||||
Field<T2> left2 = left.field2();
|
||||
@ -152,5 +160,10 @@ class RowOverlapsCondition<T1, T2> extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(left).visit(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_OVERLAPS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Comparator.EQUALS;
|
||||
import static org.jooq.Comparator.IN;
|
||||
import static org.jooq.Comparator.NOT_EQUALS;
|
||||
@ -58,6 +60,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
@ -100,6 +103,11 @@ class RowSubqueryCondition extends AbstractCondition {
|
||||
delegate(context.configuration(), null).bind(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
private final QueryPartInternal delegate(Configuration configuration, RenderContext context) {
|
||||
SQLDialect family = configuration.dialect().family();
|
||||
|
||||
@ -214,5 +222,10 @@ class RowSubqueryCondition extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(left).visit(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,8 +35,12 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
class SQLCondition extends AbstractCondition {
|
||||
@ -70,4 +74,13 @@ class SQLCondition extends AbstractCondition {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
if (delegate instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) delegate).clause();
|
||||
}
|
||||
|
||||
return CONDITION;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,9 +35,13 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.FIELD;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
class SQLField<T> extends AbstractField<T> {
|
||||
@ -68,4 +72,13 @@ class SQLField<T> extends AbstractField<T> {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
if (delegate instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) delegate).clause();
|
||||
}
|
||||
|
||||
return FIELD;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,8 +36,10 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
/**
|
||||
@ -71,4 +73,13 @@ class SQLQuery extends AbstractQuery {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
if (delegate instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) delegate).clause();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,9 +38,11 @@ package org.jooq.impl;
|
||||
import java.sql.ResultSetMetaData;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
@ -78,6 +80,15 @@ class SQLResultQuery extends AbstractResultQuery<Record> {
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
if (delegate instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) delegate).clause();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Class<? extends Record> getRecordType() {
|
||||
return RecordImpl.class;
|
||||
|
||||
@ -35,8 +35,12 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.TABLE;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Table;
|
||||
@ -85,6 +89,15 @@ class SQLTable extends AbstractTable<Record> {
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
if (delegate instanceof QueryPartInternal) {
|
||||
return ((QueryPartInternal) delegate).clause();
|
||||
}
|
||||
|
||||
return TABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<Record> fields0() {
|
||||
return new Fields<Record>();
|
||||
|
||||
@ -38,6 +38,7 @@ package org.jooq.impl;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Template;
|
||||
@ -79,5 +80,10 @@ class SQLTemplate implements Template {
|
||||
public final void bind(BindContext context) {
|
||||
Utils.renderAndBind(null, context, sql, substitutes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,10 +36,13 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.SCHEMA;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Sequence;
|
||||
@ -70,12 +73,17 @@ public class SchemaImpl extends AbstractQueryPart implements Schema {
|
||||
return schemaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.literal(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.literal(getName());
|
||||
public final Clause clause() {
|
||||
return SCHEMA;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.FIELD;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jooq.Field;
|
||||
@ -49,15 +51,15 @@ class SelectFieldList extends QueryPartList<Field<?>> {
|
||||
private static final long serialVersionUID = 8850104968428500798L;
|
||||
|
||||
SelectFieldList() {
|
||||
super();
|
||||
super(FIELD);
|
||||
}
|
||||
|
||||
SelectFieldList(Collection<? extends Field<?>> wrappedList) {
|
||||
super(wrappedList);
|
||||
super(FIELD, wrappedList);
|
||||
}
|
||||
|
||||
SelectFieldList(Field<?>... wrappedList) {
|
||||
super(wrappedList);
|
||||
super(FIELD, wrappedList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,7 +36,12 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_EXISTS;
|
||||
import static org.jooq.Clause.CONDITION_EXISTS_NOT;
|
||||
import static org.jooq.impl.ExistsOperator.EXISTS;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Select;
|
||||
|
||||
@ -96,4 +101,9 @@ class SelectQueryAsExistsCondition extends AbstractCondition {
|
||||
.subquery(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return operator == EXISTS ? CONDITION_EXISTS : CONDITION_EXISTS_NOT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -101,4 +102,9 @@ class SelectQueryAsField<T> extends AbstractField<T> {
|
||||
.sql(")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comparator;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
@ -105,4 +108,9 @@ class SelectQueryAsSubQueryCondition extends AbstractCondition {
|
||||
.subquery(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Select;
|
||||
@ -112,4 +113,9 @@ class SelectQueryAsTable<R extends Record> extends AbstractTable<R> {
|
||||
.subquery(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,16 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Clause.SELECT;
|
||||
import static org.jooq.Clause.SELECT_CONNECT_BY;
|
||||
import static org.jooq.Clause.SELECT_FROM;
|
||||
import static org.jooq.Clause.SELECT_GROUP_BY;
|
||||
import static org.jooq.Clause.SELECT_HAVING;
|
||||
import static org.jooq.Clause.SELECT_ORDER_BY;
|
||||
import static org.jooq.Clause.SELECT_SELECT;
|
||||
import static org.jooq.Clause.SELECT_START_WITH;
|
||||
import static org.jooq.Clause.SELECT_WHERE;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DERBY;
|
||||
@ -62,6 +72,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -140,7 +151,7 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
this.condition = new ConditionProviderImpl();
|
||||
this.connectBy = new ConditionProviderImpl();
|
||||
this.connectByStartWith = new ConditionProviderImpl();
|
||||
this.groupBy = new QueryPartList<GroupField>();
|
||||
this.groupBy = new QueryPartList<GroupField>(DUMMY);
|
||||
this.having = new ConditionProviderImpl();
|
||||
this.orderBy = new SortFieldList();
|
||||
this.limit = new Limit();
|
||||
@ -149,10 +160,15 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
this.from.add(from.asTable());
|
||||
}
|
||||
|
||||
this.forUpdateOf = new QueryPartList<Field<?>>();
|
||||
this.forUpdateOf = new QueryPartList<Field<?>>(DUMMY);
|
||||
this.forUpdateOfTables = new TableList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
context.declareFields(true)
|
||||
@ -323,7 +339,6 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
context.formatSeparator()
|
||||
.sql(option);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -434,7 +449,9 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
|
||||
// SELECT clause
|
||||
// -------------
|
||||
context.keyword("select ");
|
||||
context.start(SELECT_SELECT)
|
||||
.keyword("select")
|
||||
.sql(" ");
|
||||
|
||||
// [#1493] Oracle hints come directly after the SELECT keyword
|
||||
if (!StringUtils.isBlank(hint)) {
|
||||
@ -442,7 +459,7 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
}
|
||||
|
||||
if (distinct) {
|
||||
context.keyword("distinct ");
|
||||
context.keyword("distinct").sql(" ");
|
||||
}
|
||||
|
||||
// Sybase and SQL Server have leading TOP clauses
|
||||
@ -527,15 +544,24 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
.paramType(paramType);
|
||||
}
|
||||
|
||||
context.declareFields(false);
|
||||
context.declareFields(false)
|
||||
.end(SELECT_SELECT);
|
||||
|
||||
// FROM and JOIN clauses
|
||||
// ---------------------
|
||||
context.declareTables(true);
|
||||
context.start(SELECT_FROM)
|
||||
.declareTables(true);
|
||||
|
||||
if (!context.render(getFrom()).isEmpty()) {
|
||||
// The simplest way to see if no FROM clause needs to be rendered is to
|
||||
// render it. But use a new RenderContext (without any VisitListeners)
|
||||
// for that purpose!
|
||||
DefaultConfiguration c = new DefaultConfiguration(context.configuration().dialect());
|
||||
String renderedFrom = new DefaultRenderContext(c).render(getFrom());
|
||||
|
||||
if (!renderedFrom.isEmpty()) {
|
||||
context.formatSeparator()
|
||||
.keyword("from ")
|
||||
.keyword("from")
|
||||
.sql(" ")
|
||||
.visit(getFrom());
|
||||
|
||||
// [#1681] Sybase ASE and Ingres need a cross-joined dummy table
|
||||
@ -545,32 +571,61 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
}
|
||||
}
|
||||
|
||||
context.declareTables(false);
|
||||
context.declareTables(false)
|
||||
.end(SELECT_FROM);
|
||||
|
||||
// WHERE clause
|
||||
// ------------
|
||||
context.start(SELECT_WHERE);
|
||||
|
||||
if (!(getWhere().getWhere() instanceof TrueCondition)) {
|
||||
context.formatSeparator()
|
||||
.keyword("where ")
|
||||
.keyword("where")
|
||||
.sql(" ")
|
||||
.visit(getWhere());
|
||||
}
|
||||
|
||||
context.end(SELECT_WHERE);
|
||||
|
||||
// CONNECT BY clause
|
||||
// -----------------
|
||||
if (!(getConnectBy().getWhere() instanceof TrueCondition)) {
|
||||
|
||||
// CUBRID supports this clause only as [ START WITH .. ] CONNECT BY
|
||||
// Oracle also knows the CONNECT BY .. [ START WITH ] alternative
|
||||
// syntax
|
||||
toSQLStartWith(context);
|
||||
toSQLConnectBy(context);
|
||||
// CUBRID supports this clause only as [ START WITH .. ] CONNECT BY
|
||||
// Oracle also knows the CONNECT BY .. [ START WITH ] alternative
|
||||
// syntax
|
||||
context.start(SELECT_START_WITH);
|
||||
|
||||
if (!(getConnectByStartWith().getWhere() instanceof TrueCondition)) {
|
||||
context.formatSeparator()
|
||||
.keyword("start with")
|
||||
.sql(" ")
|
||||
.visit(getConnectByStartWith());
|
||||
}
|
||||
|
||||
context.end(SELECT_START_WITH);
|
||||
context.start(SELECT_CONNECT_BY);
|
||||
|
||||
if (!(getConnectBy().getWhere() instanceof TrueCondition)) {
|
||||
context.formatSeparator()
|
||||
.keyword("connect by");
|
||||
|
||||
if (connectByNoCycle) {
|
||||
context.keyword(" nocycle");
|
||||
}
|
||||
|
||||
context.sql(" ").visit(getConnectBy());
|
||||
}
|
||||
|
||||
context.end(SELECT_CONNECT_BY);
|
||||
|
||||
// GROUP BY and HAVING clause
|
||||
// --------------------------
|
||||
context.start(SELECT_GROUP_BY);
|
||||
|
||||
if (grouping) {
|
||||
context.formatSeparator()
|
||||
.keyword("group by ");
|
||||
.keyword("group by")
|
||||
.sql(" ");
|
||||
|
||||
// [#1665] Empty GROUP BY () clauses need parentheses
|
||||
if (getGroupBy().isEmpty()) {
|
||||
@ -595,19 +650,33 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
}
|
||||
}
|
||||
|
||||
context.end(SELECT_GROUP_BY);
|
||||
|
||||
// HAVING clause
|
||||
// -------------
|
||||
context.start(SELECT_HAVING);
|
||||
|
||||
if (!(getHaving().getWhere() instanceof TrueCondition)) {
|
||||
context.formatSeparator()
|
||||
.keyword("having ")
|
||||
.keyword("having")
|
||||
.sql(" ")
|
||||
.visit(getHaving());
|
||||
}
|
||||
|
||||
context.end(SELECT_HAVING);
|
||||
|
||||
// ORDER BY clause
|
||||
// ---------------
|
||||
context.start(SELECT_ORDER_BY);
|
||||
|
||||
if (!getOrderBy().isEmpty()) {
|
||||
context.formatSeparator()
|
||||
.keyword("order ")
|
||||
.keyword(orderBySiblings ? "siblings " : "")
|
||||
.keyword("by ")
|
||||
.keyword("order")
|
||||
.sql(orderBySiblings ? " " : "")
|
||||
.keyword(orderBySiblings ? "siblings" : "")
|
||||
.sql(" ")
|
||||
.keyword("by")
|
||||
.sql(" ")
|
||||
.visit(getOrderBy());
|
||||
}
|
||||
|
||||
@ -615,27 +684,11 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
// OFFSET .. FETCH
|
||||
else if (getLimit().isApplicable() && asList(SQLSERVER, SQLSERVER2012).contains(dialect)){
|
||||
context.formatSeparator()
|
||||
.keyword("order by 1");
|
||||
}
|
||||
}
|
||||
|
||||
private void toSQLStartWith(RenderContext context) {
|
||||
if (!(getConnectByStartWith().getWhere() instanceof TrueCondition)) {
|
||||
context.formatSeparator()
|
||||
.keyword("start with ")
|
||||
.visit(getConnectByStartWith());
|
||||
}
|
||||
}
|
||||
|
||||
private void toSQLConnectBy(RenderContext context) {
|
||||
context.formatSeparator()
|
||||
.keyword("connect by");
|
||||
|
||||
if (connectByNoCycle) {
|
||||
context.keyword(" nocycle");
|
||||
.keyword("order by")
|
||||
.sql(" 1");
|
||||
}
|
||||
|
||||
context.sql(" ").visit(getConnectBy());
|
||||
context.end(SELECT_ORDER_BY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -35,11 +35,13 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.DSL.nvl2;
|
||||
import static org.jooq.impl.DSL.one;
|
||||
import static org.jooq.impl.DSL.zero;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.SortField;
|
||||
@ -122,10 +124,10 @@ class SortFieldImpl<T> extends AbstractQueryPart implements SortField<T> {
|
||||
.keyword(order.toSQL());
|
||||
|
||||
if (nullsFirst) {
|
||||
context.keyword(" nulls first");
|
||||
context.sql(" ").keyword("nulls first");
|
||||
}
|
||||
else {
|
||||
context.keyword(" nulls last");
|
||||
context.sql(" ").keyword("nulls last");
|
||||
}
|
||||
|
||||
break;
|
||||
@ -162,4 +164,9 @@ class SortFieldImpl<T> extends AbstractQueryPart implements SortField<T> {
|
||||
|
||||
context.visit(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -55,7 +57,7 @@ class SortFieldList extends QueryPartList<SortField<?>> {
|
||||
}
|
||||
|
||||
SortFieldList(List<SortField<?>> wrappedList) {
|
||||
super(wrappedList);
|
||||
super(DUMMY, wrappedList);
|
||||
}
|
||||
|
||||
void addAll(Field<?>... fields) {
|
||||
|
||||
@ -36,10 +36,13 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Record;
|
||||
@ -125,6 +128,11 @@ class TableAlias<R extends Record> extends AbstractTable<R> {
|
||||
context.visit(alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<R> as(String as) {
|
||||
return alias.wrapped().as(as);
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.FIELD;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
@ -79,6 +82,11 @@ class TableFieldImpl<R extends Record, T> extends AbstractField<T> implements Ta
|
||||
@Override
|
||||
public final void bind(BindContext context) {}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return FIELD;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: Object API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.TABLE;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Schema;
|
||||
@ -89,6 +92,16 @@ public class TableImpl<R extends Record> extends AbstractTable<R> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<R> fields0() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return TABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
if (alias != null) {
|
||||
@ -96,11 +109,6 @@ public class TableImpl<R extends Record> extends AbstractTable<R> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<R> fields0() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
if (alias != null) {
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.TABLE;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.Field;
|
||||
@ -50,11 +52,11 @@ class TableList extends QueryPartList<Table<?>> {
|
||||
private static final long serialVersionUID = -8545559185481762229L;
|
||||
|
||||
TableList() {
|
||||
super();
|
||||
super(TABLE);
|
||||
}
|
||||
|
||||
TableList(List<? extends Table<?>> wrappedList) {
|
||||
super(wrappedList);
|
||||
super(TABLE, wrappedList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,7 +36,10 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
/**
|
||||
@ -54,5 +57,10 @@ class TrueCondition extends AbstractCondition {
|
||||
context.sql("1 = 1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return CONDITION_COMPARISON;
|
||||
}
|
||||
|
||||
TrueCondition() {}
|
||||
}
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.TRUNCATE;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
@ -132,4 +135,9 @@ class TruncateImpl<R extends Record> extends AbstractQuery implements
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return TRUNCATE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
@ -136,6 +139,11 @@ public class UDTImpl<R extends UDTRecord<R>> extends AbstractQueryPart implement
|
||||
context.visit(fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may call this method to create {@link UDTField} objects that
|
||||
* are linked to this table.
|
||||
|
||||
@ -35,12 +35,17 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.SELECT_EXCEPT;
|
||||
import static org.jooq.Clause.SELECT_INTERSECT;
|
||||
import static org.jooq.Clause.SELECT_UNION;
|
||||
import static org.jooq.Clause.SELECT_UNION_ALL;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
@ -63,10 +68,10 @@ class Union<R extends Record> extends AbstractSelect<R> {
|
||||
Union(Configuration configuration, Select<R> query1, Select<? extends R> query2, CombineOperator operator) {
|
||||
super(configuration);
|
||||
|
||||
this.operator = operator;
|
||||
this.queries = new ArrayList<Select<? extends R>>();
|
||||
this.queries.add(query1);
|
||||
this.queries.add(query2);
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,6 +133,17 @@ class Union<R extends Record> extends AbstractSelect<R> {
|
||||
visitAll(context, queries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
switch (operator) {
|
||||
case EXCEPT: return SELECT_EXCEPT;
|
||||
case INTERSECT: return SELECT_INTERSECT;
|
||||
case UNION: return SELECT_UNION;
|
||||
case UNION_ALL: return SELECT_UNION_ALL;
|
||||
default: throw new IllegalArgumentException("Operator not supported : " + operator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final boolean isForUpdate() {
|
||||
return false;
|
||||
|
||||
@ -37,6 +37,12 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.UPDATE;
|
||||
import static org.jooq.Clause.UPDATE_RETURNING;
|
||||
import static org.jooq.Clause.UPDATE_SET;
|
||||
import static org.jooq.Clause.UPDATE_SET_ASSIGNMENT;
|
||||
import static org.jooq.Clause.UPDATE_UPDATE;
|
||||
import static org.jooq.Clause.UPDATE_WHERE;
|
||||
import static org.jooq.SQLDialect.INGRES;
|
||||
import static org.jooq.SQLDialect.ORACLE;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
@ -47,6 +53,7 @@ import java.util.Map;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
@ -445,18 +452,24 @@ class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.keyword("update ")
|
||||
context.start(UPDATE_UPDATE)
|
||||
.keyword("update")
|
||||
.sql(" ")
|
||||
.declareTables(true)
|
||||
.visit(getInto())
|
||||
.declareTables(false)
|
||||
.end(UPDATE_UPDATE)
|
||||
.formatSeparator()
|
||||
.keyword("set ");
|
||||
.start(UPDATE_SET)
|
||||
.keyword("set")
|
||||
.sql(" ");
|
||||
|
||||
// A multi-row update was specified
|
||||
if (multiRow != null) {
|
||||
boolean qualify = context.qualify();
|
||||
|
||||
context.qualify(false)
|
||||
context.start(UPDATE_SET_ASSIGNMENT)
|
||||
.qualify(false)
|
||||
.visit(multiRow)
|
||||
.qualify(qualify)
|
||||
.sql(" = ");
|
||||
@ -467,7 +480,7 @@ class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
context.visit(multiValue);
|
||||
}
|
||||
|
||||
// Subselects or subselect simulatinos of row value expressions
|
||||
// Subselects or subselect simulations of row value expressions
|
||||
else {
|
||||
Select<?> select = multiSelect;
|
||||
|
||||
@ -485,6 +498,8 @@ class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
.formatNewLine()
|
||||
.sql(")");
|
||||
}
|
||||
|
||||
context.end(UPDATE_SET_ASSIGNMENT);
|
||||
}
|
||||
|
||||
// A regular (non-multi-row) update was specified
|
||||
@ -494,13 +509,17 @@ class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
.formatIndentLockEnd();
|
||||
}
|
||||
|
||||
context.end(UPDATE_SET);
|
||||
|
||||
if (!(getWhere() instanceof TrueCondition)) {
|
||||
context.formatSeparator()
|
||||
.start(UPDATE_WHERE)
|
||||
.keyword("where ")
|
||||
.visit(getWhere());
|
||||
.visit(getWhere())
|
||||
.end(UPDATE_WHERE);
|
||||
}
|
||||
|
||||
toSQLReturning(context);
|
||||
toSQLReturning(context, UPDATE_RETURNING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -530,6 +549,11 @@ class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
bindReturning(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isExecutable() {
|
||||
return updateMap.size() > 0 || multiRow != null;
|
||||
|
||||
@ -35,9 +35,11 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Row;
|
||||
@ -158,6 +160,11 @@ class Values<R extends Record> extends AbstractTable<R> {
|
||||
visitAll(context, rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Fields<R> fields0() {
|
||||
return new Fields<R>(rows[0].fields());
|
||||
|
||||
@ -35,7 +35,10 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Table;
|
||||
@ -79,6 +82,11 @@ class WithTable<R extends Record> extends AbstractTable<R> {
|
||||
context.visit(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Class<? extends R> getRecordType() {
|
||||
return delegate.getRecordType();
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
/**
|
||||
@ -65,4 +66,9 @@ class WrappedList extends AbstractQueryPart {
|
||||
public final void bind(BindContext context) {
|
||||
context.visit(wrapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause clause() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
133
jOOQ/src/test/java/org/jooq/test/VisitContextTest.java
Normal file
133
jOOQ/src/test/java/org/jooq/test/VisitContextTest.java
Normal file
@ -0,0 +1,133 @@
|
||||
/**
|
||||
* 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.Clause.SELECT_WHERE;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.using;
|
||||
import static org.jooq.impl.DefaultVisitListenerProvider.providers;
|
||||
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;
|
||||
import static org.jooq.tools.StringUtils.leftPad;
|
||||
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.VisitContext;
|
||||
import org.jooq.VisitListener;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Some common tests related to {@link VisitContext}
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class VisitContextTest extends AbstractTest {
|
||||
|
||||
@Test
|
||||
public void testClauses() {
|
||||
Configuration c = create.configuration().derive(providers(new ClausesListener()));
|
||||
|
||||
// String sql =
|
||||
// using(c)
|
||||
// .select(FIELD_ID1, FIELD_NAME1)
|
||||
// .from(select(FIELD_NAME1).from(
|
||||
// TABLE1,
|
||||
// TABLE2.join(TABLE3).on("1 = 2")
|
||||
// .leftOuterJoin(TABLE3).on("1 = 1")))
|
||||
// .where(FIELD_ID1.eq(1))
|
||||
// .and(FIELD_NAME1.ne("3"))
|
||||
// .and("x = y")
|
||||
// .having(FIELD_ID1.eq(1))
|
||||
// .getSQL();
|
||||
String sql =
|
||||
using(c)
|
||||
.select(FIELD_ID1, FIELD_NAME1)
|
||||
.from(select(FIELD_NAME1).from(TABLE1))
|
||||
.getSQL();
|
||||
|
||||
System.out.println();
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
private static class ClausesListener implements VisitListener {
|
||||
|
||||
Clause clause;
|
||||
String where = "where";
|
||||
int indent = 0;
|
||||
|
||||
@Override
|
||||
public void clauseStart(VisitContext context) {
|
||||
if (context.clause() == Clause.DUMMY)
|
||||
return;
|
||||
|
||||
clause = context.clause();
|
||||
indent += 2;
|
||||
System.out.println(leftPad("+-", indent, "| ") + context.clause());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clauseEnd(VisitContext context) {
|
||||
if (context.clause() == Clause.DUMMY)
|
||||
return;
|
||||
|
||||
if (clause == SELECT_WHERE) {
|
||||
if (context.renderContext() != null) {
|
||||
context.renderContext()
|
||||
.sql(" ")
|
||||
.keyword(where)
|
||||
.sql(" ")
|
||||
.sql("SecurityCode IN (1, 2, 3)");
|
||||
}
|
||||
}
|
||||
|
||||
clause = null;
|
||||
indent -= 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitStart(VisitContext context) {
|
||||
if (clause == SELECT_WHERE) {
|
||||
where = "and";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd(VisitContext context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user