/*
* 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.RenderKeywordStyle;
import org.jooq.conf.Settings;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
/**
* 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 <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
*/
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).
*/
boolean declareFields();
/**
* Set the new context value for {@link #declareFields()}.
*/
C declareFields(boolean declareFields);
/**
* 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 {@link #declareTables()}.
*/
C declareTables(boolean declareTables);
/**
* 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
* {@link #declareTables()} or {@link #declareFields()} sections.
*/
C declareAliases(boolean declareTables);
/**
* 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 {@link #declareWindows()}.
*/
C declareWindows(boolean declareWindows);
/**
* 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 {@link #declareCTE()}.
*/
C declareCTE(boolean declareCTE);
/**
* Whether the current context is rendering a sub-query (nested query).
*/
boolean subquery();
/**
* Set the new context value for {@link #subquery()}.
*/
C subquery(boolean subquery);
/**
* whether the current context is rendering a string literal.
*/
boolean stringLiteral();
/**
* Set the new context value for {@link #stringLiteral()}.
*/
C stringLiteral(boolean stringLiteral);
/**
* 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 {@link #nextIndex()}.
*/
int peekIndex();
// ------------------------------------------------------------------------
// Methods used for variable binding
// ------------------------------------------------------------------------
/**
* Retrieve the context's underlying {@link PreparedStatement} if available,
* or <code>null</code> if this traversal does not operate on a
* <code>PreparedStatement</code>.
*/
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
*/
BindContext bindValue(Object value, Field<?> field) throws DataAccessException;
// ------------------------------------------------------------------------
// Methods used for SQL rendering
// ------------------------------------------------------------------------
/**
* Peek the next alias that will be generated by {@link #nextAlias()}.
*/
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.
*/
String nextAlias();
/**
* Render the context's underlying SQL statement.
*/
String render();
/**
* Render a query part in a new context derived from this one. The rendered
* SQL will not be appended to this context.
*/
String render(QueryPart part);
/**
* Append a SQL keyword to the context's contained {@link StringBuilder}.
* <p>
* Use this to have your SQL keyword rendered in {@link RenderKeywordStyle}.
*
* @deprecated - 3.10.0 - [#4990] - Use {@link DSL#keyword(String)} instead.
*/
@Deprecated
C keyword(String keyword);
/**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
C sql(String 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.
*/
C sql(String sql, boolean literal);
/**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
C sql(char sql);
/**
* Append some SQL to the context's contained {@link StringBuilder}.
*/
C sql(int sql);
/**
* Override the value of {@link Settings#isRenderFormatted()}.
*/
C format(boolean format);
/**
* The value of {@link Settings#isRenderFormatted()}.
*/
boolean format();
/**
* Render a new line character (only if {@link Settings#isRenderFormatted()}
* is set to <code>true</code>).
*/
C formatNewLine();
/**
* Render a new line character (only if {@link Settings#isRenderFormatted()}
* is set to <code>true</code>, and the {@link #formatPrintMargin(int)} has
* been exceeded).
*/
C formatNewLineAfterPrintMargin();
/**
* Render a new line character (only if {@link Settings#isRenderFormatted()}
* is set to <code>true</code>), or a whitespace separator character
* otherwise.
*/
C formatSeparator();
/**
* 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>
*/
C formatIndentStart();
/**
* Start indenting subsequent SQL by a number of characters, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*/
C formatIndentStart(int indent);
/**
* Start indenting subsequent SQL at the same level as the current line, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*/
C formatIndentLockStart();
/**
* 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>
*/
C formatIndentEnd();
/**
* Stop indenting subsequent SQL by a number of characters, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*/
C formatIndentEnd(int indent);
/**
* Stop indenting subsequent SQL at the same level as the current line, if
* {@link Settings#isRenderFormatted()} is set to <code>true</code>.
*/
C formatIndentLockEnd();
/**
* 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>
*/
C formatPrintMargin(int margin);
/**
* 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.
*/
@Deprecated
C literal(String literal);
/**
* Whether {@link Name} parts (and {@link #literal(String)}) should be quoted.
*/
boolean quote();
/**
* Set the new context value for {@link #quote()}.
*/
C quote(boolean quote);
/**
* Whether query parts should render qualified names or not.
*/
boolean qualify();
/**
* Set the new context value for {@link #qualify()}.
* <p>
* This is the same as {@link #qualifySchema(boolean)}.
*/
C qualify(boolean qualify);
/**
* 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 {@link #qualifySchema()}.
*/
C qualifySchema(boolean qualifySchema);
/**
* 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 {@link #qualifyCatalog()}.
* <p>
* The catalog can only be qualified when {@link #qualifySchema()} is
* <code>true</code> as well.
*/
C qualifyCatalog(boolean qualifyCatalog);
/**
* 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>
*/
ParamType paramType();
/**
* Set the new context value for {@link #paramType()}.
*/
C paramType(ParamType paramType);
/**
* The currently applied cast mode for bind values.
*/
CastMode castMode();
/**
* Set the new cast mode for {@link #castMode()}.
*/
C castMode(CastMode mode);
/**
* 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
*/
@Deprecated
Boolean cast();
/**
* 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
*/
@Deprecated
C castModeSome(SQLDialect... dialects);
}