/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
import java.sql.PreparedStatement;
import org.jooq.RenderContext.CastMode;
import org.jooq.conf.ParamType;
import org.jooq.conf.RenderKeywordCase;
import org.jooq.conf.Settings;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
A context type that is used for rendering SQL or for binding.
Author: Lukas Eder See Also:
/**
* A context type that is used for rendering SQL or for binding.
*
* @author Lukas Eder
* @see BindContext
* @see RenderContext
*/
public interface Context<C extends Context<C>> extends Scope {
// ------------------------------------------------------------------------
// Methods specifying the scope of the SQL being rendered
// ------------------------------------------------------------------------
Visit a QueryPart
in the current Context
.
This method is called by certain QueryPart
implementations
to recursively visit component QueryPart
s.
Params: - part – The component
QueryPart
Throws: - DataAccessException – If something went wrong while visiting the
component
QueryPart
, e.g. when binding a
variable
/**
* Visit a <code>QueryPart</code> in the current <code>Context</code>.
* <p>
* This method is called by certain <code>QueryPart</code> implementations
* to recursively visit component <code>QueryPart</code>s.
*
* @param part The component <code>QueryPart</code>
* @throws DataAccessException If something went wrong while visiting the
* component <code>QueryPart</code>, e.g. when binding a
* variable
*/
@NotNull
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!
/**
* TODO [#2667]
*
* Properties of these methods:
* - A clause is always started / ended, even if it isn't rendered or if it's empty!
*/
@NotNull
C start(Clause clause);
@NotNull
C end(Clause clause);
Whether the current context is rendering a SQL field declaration (e.g. a Field
in the SELECT
clause of the query).
/**
* Whether the current context is rendering a SQL field declaration (e.g. a
* {@link Field} in the <code>SELECT</code> clause of the query).
*/
boolean declareFields();
Set the new context value for declareFields()
. /**
* Set the new context value for {@link #declareFields()}.
*/
@NotNull
C declareFields(boolean declareFields);
Whether the current context is rendering a SQL table declaration (e.g. a Table
in the FROM
or JOIN
clause of the
query).
/**
* Whether the current context is rendering a SQL table declaration (e.g. a
* {@link Table} in the <code>FROM</code> or <code>JOIN</code> clause of the
* query).
*/
boolean declareTables();
Set the new context value for declareTables()
. /**
* Set the new context value for {@link #declareTables()}.
*/
@NotNull
C declareTables(boolean declareTables);
Whether the current context is rendering a SQL alias declarations in declareTables()
or declareFields()
sections. /**
* Whether the current context is rendering a SQL alias declarations in
* {@link #declareTables()} or {@link #declareFields()} sections.
*/
boolean declareAliases();
Whether the current context is rendering a SQL alias declarations in declareTables()
or declareFields()
sections. /**
* Whether the current context is rendering a SQL alias declarations in
* {@link #declareTables()} or {@link #declareFields()} sections.
*/
@NotNull
C declareAliases(boolean declareTables);
Whether the current context is rendering a SQL window declaration (e.g. a WindowDefinition
in the WINDOW
clause of the query).
/**
* Whether the current context is rendering a SQL window declaration (e.g. a
* {@link WindowDefinition} in the <code>WINDOW</code> clause of the query).
*/
boolean declareWindows();
Set the new context value for declareWindows()
. /**
* Set the new context value for {@link #declareWindows()}.
*/
@NotNull
C declareWindows(boolean declareWindows);
Whether the current context is rendering a common table expression (e.g. a CommonTableExpression
in the WITH
clause of the
query).
/**
* Whether the current context is rendering a common table expression (e.g.
* a {@link CommonTableExpression} in the <code>WITH</code> clause of the
* query).
*/
boolean declareCTE();
Set the new context value for declareCTE()
. /**
* Set the new context value for {@link #declareCTE()}.
*/
@NotNull
C declareCTE(boolean declareCTE);
Whether the current context is rendering a sub-query (nested query).
/**
* Whether the current context is rendering a sub-query (nested query).
*/
boolean subquery();
Set the new context value for subquery()
. /**
* Set the new context value for {@link #subquery()}.
*/
@NotNull
C subquery(boolean subquery);
Which level of subqueries we're currently in, starting with 0 for the top
level query.
/**
* Which level of subqueries we're currently in, starting with 0 for the top
* level query.
*/
int subqueryLevel();
Start a new SELECT scope.
/**
* Start a new SELECT scope.
*/
@NotNull
C scopeStart();
Mark the beginning of a scoped query part.
/**
* Mark the beginning of a scoped query part.
*/
@NotNull
C scopeMarkStart(QueryPart part);
Register a "special" query part in the scope, reusing the object from a
higher scope, if available.
/**
* Register a "special" query part in the scope, reusing the object from a
* higher scope, if available.
*/
@NotNull
C scopeRegister(QueryPart part);
Register a "special" query part in the scope, allowing to force
registering the object in the new scope, if a higher scope already has
the object.
[#10992] This is necessary to allow for hiding identifiers from nested
scopes.
/**
* Register a "special" query part in the scope, allowing to force
* registering the object in the new scope, if a higher scope already has
* the object.
* <p>
* [#10992] This is necessary to allow for hiding identifiers from nested
* scopes.
*/
@NotNull
C scopeRegister(QueryPart part, boolean forceNew);
Mark the end of a scoped query part.
/**
* Mark the end of a scoped query part.
*/
@NotNull
C scopeMarkEnd(QueryPart part);
End a previous SELECT scope.
/**
* End a previous SELECT scope.
*/
@NotNull
C scopeEnd();
whether the current context is rendering a string literal.
/**
* whether the current context is rendering a string literal.
*/
boolean stringLiteral();
Set the new context value for stringLiteral()
. /**
* Set the new context value for {@link #stringLiteral()}.
*/
@NotNull
C stringLiteral(boolean stringLiteral);
Get the next bind index. This increments an internal counter. This is
relevant for two use-cases:
- When binding variables to a
PreparedStatement
. Client code must assure that calling nextIndex()
is followed by setting a bind value to Context<BindContext>.statement()
- When rendering unnamed bind variables with
Context<RenderContext>.paramType()
being to NAMED
/**
* Get the next bind index. This increments an internal counter. This is
* relevant for two use-cases:
* <ul>
* <li>When binding variables to a {@link PreparedStatement}. Client code
* must assure that calling {@link #nextIndex()} is followed by setting a
* bind value to {@link BindContext#statement()}</li>
* <li>When rendering unnamed bind variables with
* {@link RenderContext#paramType()} being to <code>NAMED</code></li>
* </ul>
*/
int nextIndex();
Peek the next bind index. This won't increment the internal counter, unlike nextIndex()
. /**
* Peek the next bind index. This won't increment the internal counter,
* unlike {@link #nextIndex()}.
*/
int peekIndex();
// ------------------------------------------------------------------------
// Methods used for variable binding
// ------------------------------------------------------------------------
Retrieve the context's underlying PreparedStatement
if available, or null
if this traversal does not operate on a
PreparedStatement
.
/**
* Retrieve the context's underlying {@link PreparedStatement} if available,
* or <code>null</code> if this traversal does not operate on a
* <code>PreparedStatement</code>.
*/
@Nullable
PreparedStatement statement();
Bind a value using a specific type. This will also increment the internal
counter.
Throws: - DataAccessException – If something went wrong while binding a
variable
/**
* Bind a value using a specific type. This will also increment the internal
* counter.
*
* @throws DataAccessException If something went wrong while binding a
* variable
*/
@NotNull
BindContext bindValue(Object value, Field<?> field) throws DataAccessException;
// ------------------------------------------------------------------------
// Methods used for SQL rendering
// ------------------------------------------------------------------------
Peek the next alias that will be generated by nextAlias()
. /**
* Peek the next alias that will be generated by {@link #nextAlias()}.
*/
@NotNull
String peekAlias();
Return a new alias that is unique for the scope of one query. These
aliases are sometimes needed when unaliased projections are defined in
subqueries, which can lead to syntax errors.
/**
* Return a new alias that is unique for the scope of one query. These
* aliases are sometimes needed when unaliased projections are defined in
* subqueries, which can lead to syntax errors.
*/
@NotNull
String nextAlias();
Render the context's underlying SQL statement.
/**
* Render the context's underlying SQL statement.
*/
@NotNull
String render();
Render a query part in a new context derived from this one. The rendered
SQL will not be appended to this context.
/**
* Render a query part in a new context derived from this one. The rendered
* SQL will not be appended to this context.
*/
@NotNull
String render(QueryPart part);
Append a SQL keyword to the context's contained StringBuilder
. Use this to have your SQL keyword rendered in RenderKeywordCase
.
Deprecated: - 3.10.0 - [#4990] - Use DSL.keyword(String)
instead.
/**
* Append a SQL keyword to the context's contained {@link StringBuilder}.
* <p>
* Use this to have your SQL keyword rendered in {@link RenderKeywordCase}.
*
* @deprecated - 3.10.0 - [#4990] - Use {@link DSL#keyword(String)} instead.
*/
@NotNull
@Deprecated
C keyword(String keyword);
Append some SQL to the context's contained StringBuilder
. /**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
@NotNull
C sql(String sql);
Append some SQL to the context's contained StringBuilder
.
Set literal = true
to indicate that the
RenderContext
shall not format the argument SQL.
/**
* Append some SQL to the context's contained {@link StringBuilder}.
* <p>
* Set <code>literal = true</code> to indicate that the
* <code>RenderContext</code> shall not format the argument SQL.
*/
@NotNull
C sql(String sql, boolean literal);
Append some SQL to the context's contained StringBuilder
. /**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
@NotNull
C sql(char sql);
Append some SQL to the context's contained StringBuilder
. /**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
@NotNull
C sql(int sql);
Append some SQL to the context's contained StringBuilder
. /**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
@NotNull
C sql(long sql);
Append some SQL to the context's contained StringBuilder
. /**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
@NotNull
C sql(float sql);
Append some SQL to the context's contained StringBuilder
. /**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
@NotNull
C sql(double sql);
Override the value of Settings.isRenderFormatted()
. /**
* Override the value of {@link Settings#isRenderFormatted()}.
*/
@NotNull
C format(boolean format);
The value of Settings.isRenderFormatted()
. /**
* The value of {@link Settings#isRenderFormatted()}.
*/
boolean format();
Render a new line character (only if Settings.isRenderFormatted()
is set to true
).
/**
* Render a new line character (only if {@link Settings#isRenderFormatted()}
* is set to <code>true</code>).
*/
@NotNull
C formatNewLine();
Render a new line character (only if Settings.isRenderFormatted()
is set to true
, and the formatPrintMargin(int)
has been exceeded). /**
* Render a new line character (only if {@link Settings#isRenderFormatted()}
* is set to <code>true</code>, and the {@link #formatPrintMargin(int)} has
* been exceeded).
*/
@NotNull
C formatNewLineAfterPrintMargin();
Render a new line character (only if Settings.isRenderFormatted()
is set to true
), or a whitespace separator character
otherwise.
/**
* Render a new line character (only if {@link Settings#isRenderFormatted()}
* is set to <code>true</code>), or a whitespace separator character
* otherwise.
*/
@NotNull
C formatSeparator();
Specify that a separator will be required before the next visit(QueryPart)
call, but leave the decision whether to generate a formatSeparator()
or just a whitespace to that next QueryPart
. /**
* Specify that a separator will be required before the next
* {@link #visit(QueryPart)} call, but leave the decision whether to
* generate a {@link #formatSeparator()} or just a whitespace to that next
* {@link QueryPart}.
*/
@NotNull
C separatorRequired(boolean separatorRequired);
Whether some sort of separator is required before rendering the next QueryPart
. /**
* Whether some sort of separator is required before rendering the next
* {@link QueryPart}.
*/
boolean separatorRequired();
Start indenting subsequent SQL by one level (two characters), if Settings.isRenderFormatted()
is set to true
.
This is the same as calling formatIndentStart(int)
with a parameter of 2
/**
* Start indenting subsequent SQL by one level (two characters), if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
* <p>
* This is the same as calling {@link #formatIndentStart(int)} with a
* parameter of <code>2</code>
*/
@NotNull
C formatIndentStart();
Start indenting subsequent SQL by a number of characters, if Settings.isRenderFormatted()
is set to true
.
/**
* Start indenting subsequent SQL by a number of characters, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*/
@NotNull
C formatIndentStart(int indent);
Start indenting subsequent SQL at the same level as the current line, if Settings.isRenderFormatted()
is set to true
.
Deprecated: - [#10317] - 3.14.0 - Do not reuse this method. It will be
removed without replacement.
/**
* Start indenting subsequent SQL at the same level as the current line, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*
* @deprecated - [#10317] - 3.14.0 - Do not reuse this method. It will be
* removed without replacement.
*/
@Deprecated
@NotNull
C formatIndentLockStart();
Stop indenting subsequent SQL by one level (two characters), if Settings.isRenderFormatted()
is set to true
.
This is the same as calling formatIndentEnd(int)
with a parameter of 2
/**
* Stop indenting subsequent SQL by one level (two characters), if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
* <p>
* This is the same as calling {@link #formatIndentEnd(int)} with a
* parameter of <code>2</code>
*/
@NotNull
C formatIndentEnd();
Stop indenting subsequent SQL by a number of characters, if Settings.isRenderFormatted()
is set to true
.
/**
* Stop indenting subsequent SQL by a number of characters, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*/
@NotNull
C formatIndentEnd(int indent);
Stop indenting subsequent SQL at the same level as the current line, if Settings.isRenderFormatted()
is set to true
.
Deprecated: - [#10317] - 3.14.0 - Do not reuse this method. It will be
removed without replacement.
/**
* Stop indenting subsequent SQL at the same level as the current line, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*
* @deprecated - [#10317] - 3.14.0 - Do not reuse this method. It will be
* removed without replacement.
*/
@Deprecated
@NotNull
C formatIndentLockEnd();
Set a print margin that will be applied to formatted SQL, if Settings.isRenderFormatted()
is set to true
.
The default print margin is 80
. Setting this to zero or a
negative value means that no print margin will be applied.
The print margin is applied to any of these QueryParts
:
-
Field.in(Field...)
and related expressions
/**
* Set a print margin that will be applied to formatted SQL, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
* <p>
* The default print margin is <code>80</code>. Setting this to zero or a
* negative value means that no print margin will be applied.
* <p>
* The print margin is applied to any of these <code>QueryParts</code>:
* <ul>
* <li> {@link Field#in(Field...)} and related expressions</li>
*/
@NotNull
C formatPrintMargin(int margin);
Append some literal to the context's contained StringBuilder
. Deprecated: - 3.10.0 - [#4990] - Use any of DSL.name(String)
, DSL.quotedName(String)
or DSL.unquotedName(String)
instead.
/**
* Append some literal to the context's contained {@link StringBuilder}.
*
* @deprecated - 3.10.0 - [#4990] - Use any of {@link DSL#name(String)},
* {@link DSL#quotedName(String)} or
* {@link DSL#unquotedName(String)} instead.
*/
@NotNull
@Deprecated
C literal(String literal);
Whether Name
parts (and literal(String)
) should be quoted. /**
* Whether {@link Name} parts (and {@link #literal(String)}) should be quoted.
*/
boolean quote();
Set the new context value for quote()
. /**
* Set the new context value for {@link #quote()}.
*/
@NotNull
C quote(boolean quote);
Whether query parts should render qualified names or not.
/**
* Whether query parts should render qualified names or not.
*/
boolean qualify();
Set the new context value for qualify()
. This is the same as qualifySchema(boolean)
.
/**
* Set the new context value for {@link #qualify()}.
* <p>
* This is the same as {@link #qualifySchema(boolean)}.
*/
@NotNull
C qualify(boolean qualify);
Whether query parts should render qualified names or not.
This is the same as qualifySchema()
.
/**
* Whether query parts should render qualified names or not.
* <p>
* This is the same as {@link #qualifySchema()}.
*/
boolean qualifySchema();
Set the new context value for qualifySchema()
. /**
* Set the new context value for {@link #qualifySchema()}.
*/
@NotNull
C qualifySchema(boolean qualifySchema);
Whether query parts should render qualified names or not.
The catalog can only be qualified when qualifySchema()
is true
as well.
/**
* Whether query parts should render qualified names or not.
* <p>
* The catalog can only be qualified when {@link #qualifySchema()} is
* <code>true</code> as well.
*/
boolean qualifyCatalog();
Set the new context value for qualifyCatalog()
. The catalog can only be qualified when qualifySchema()
is true
as well.
/**
* Set the new context value for {@link #qualifyCatalog()}.
* <p>
* The catalog can only be qualified when {@link #qualifySchema()} is
* <code>true</code> as well.
*/
@NotNull
C qualifyCatalog(boolean qualifyCatalog);
Specify, how bind values should be rendered.
- As
ParamType.INDEXED
parameters:
?, ?, ?
- As
ParamType.NAMED
parameters:
:1, :2, :custom_name
- As
ParamType.INLINED
parameters:
1, 'A', null
/**
* Specify, how bind values should be rendered.
* <p>
* <ul>
* <li>As {@link ParamType#INDEXED} parameters: <br/>
* <code>  ?, ?, ?</code></li>
* <li>As {@link ParamType#NAMED} parameters: <br/>
* <code>  :1, :2, :custom_name</code></li>
* <li>As {@link ParamType#INLINED} parameters: <br/>
* <code>  1, 'A', null</code></li>
* </ul>
*/
@NotNull
ParamType paramType();
Set the new context value for paramType()
. /**
* Set the new context value for {@link #paramType()}.
*/
@NotNull
C paramType(ParamType paramType);
Set the new context value for paramType()
, if a condition is true. /**
* Set the new context value for {@link #paramType()}, if a condition is true.
*/
@NotNull
C paramTypeIf(ParamType paramType, boolean condition);
The currently applied cast mode for bind values.
/**
* The currently applied cast mode for bind values.
*/
@NotNull
CastMode castMode();
Set the new cast mode for castMode()
. /**
* Set the new cast mode for {@link #castMode()}.
*/
@NotNull
C castMode(CastMode mode);
Set the new cast mode for castMode()
, if a condition is true. /**
* Set the new cast mode for {@link #castMode()}, if a condition is true.
*/
@NotNull
C castModeIf(CastMode mode, boolean condition);
Whether casting must be applied. The result follows this logic:
CastMode
result
ALWAYS
true
NEVER
false
SOME
true
or false
depending on the dialect
DEFAULT
null
Deprecated: - [#3703] - 3.5.0 - Do not use this any longer
/**
* Whether casting must be applied. The result follows this logic:
* <table border="1">
* <tr>
* <th>CastMode</th>
* <th>result</th>
* </tr>
* <tr>
* <td><code>ALWAYS</code></td>
* <td><code>true</code></td>
* </tr>
* <tr>
* <td><code>NEVER</code></td>
* <td><code>false</code></td>
* </tr>
* <tr>
* <td><code>SOME</code></td>
* <td><code>true</code> or <code>false</code> depending on the dialect</td>
* </tr>
* <tr>
* <td><code>DEFAULT</code></td>
* <td><code>null</code></td>
* </tr>
* </table>
*
* @deprecated - [#3703] - 3.5.0 - Do not use this any longer
*/
@Nullable
@Deprecated
Boolean cast();
Set the new cast mode to CastMode.SOME
for a list of dialects. Deprecated: - [#3703] - 3.5.0 - Do not use this any longer
/**
* Set the new cast mode to {@link CastMode#SOME} for a list of dialects.
*
* @deprecated - [#3703] - 3.5.0 - Do not use this any longer
*/
@NotNull
@Deprecated
C castModeSome(SQLDialect... dialects);
}