[#2060] Remove redundant SimpleSelectXXX API

- Removed API elements
- Clean up SELECT type hierarchy
This commit is contained in:
Lukas Eder 2012-12-28 11:31:12 +01:00
parent caaafad41c
commit 01dfb38317
35 changed files with 1663 additions and 3394 deletions

View File

@ -245,7 +245,7 @@ public class DB2Database extends AbstractDatabase {
protected List<TableDefinition> getTables0() throws SQLException {
List<TableDefinition> result = new ArrayList<TableDefinition>();
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
q.addFrom(TABLES);
q.addSelect(Tables.TABSCHEMA.trim());
q.addSelect(Tables.TABNAME);

View File

@ -90,7 +90,7 @@ public class Library {
*/
public static void firstRun() throws Exception {
// Create the query
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
q.addFrom(T_AUTHOR);
q.addJoin(T_BOOK, TAuthor.ID.equal(TBook.AUTHOR_ID));
q.addConditions(TAuthor.YEAR_OF_BIRTH.greaterThan(1920));

View File

@ -364,7 +364,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
@Test
public void testFetch() throws Exception {
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
q.addFrom(TAuthor());
q.addSelect(TAuthor().getFields());
q.addOrderBy(TAuthor_LAST_NAME());

View File

@ -180,7 +180,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
return;
}
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
q.addFrom(VLibrary());
Field<Integer> position = position(VLibrary_AUTHOR(), "o").as("p");
@ -360,13 +360,13 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
.when(2, "B")
.otherwise("C");
SelectQuery query = create().selectQuery();
SelectQuery<?> query = create().selectQuery();
query.addSelect(case1, case2, case3);
query.addFrom(TBook());
query.addOrderBy(TBook_PUBLISHED_IN());
query.execute();
Result<Record> result = query.getResult();
Result<?> result = query.getResult();
assertEquals(null, result.getValue(0, case1));
assertEquals(null, result.getValue(1, case1));
assertEquals(null, result.getValue(2, case1));
@ -440,7 +440,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
public void testFunctionsOnStrings_REPLACE() throws Exception {
// Standard String functions
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
Field<String> constant = val("abc");
switch (getDialect()) {
@ -855,7 +855,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
// Some checks on current_timestamp functions
// ------------------------------------------
SelectQuery q1 = create().selectQuery();
SelectQuery<?> q1 = create().selectQuery();
Field<Timestamp> now = currentTimestamp();
Field<Timestamp> ts = now.as("ts");
Field<Date> date = currentDate().as("d");
@ -982,7 +982,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
Field<Integer> f2 = val(10).div(5).add(val(3).sub(2));
Field<Integer> f3 = val(10).mod(3);
SelectQuery q1 = create().selectQuery();
SelectQuery<?> q1 = create().selectQuery();
q1.addSelect(f1, f2, f3);
q1.execute();
@ -995,7 +995,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
Field<Integer> f4 = TBook_PUBLISHED_IN().add(3).div(7);
Field<Integer> f5 = TBook_PUBLISHED_IN().sub(4).mul(8).neg();
SelectQuery q2 = create().selectQuery();
SelectQuery<?> q2 = create().selectQuery();
q2.addSelect(f4);
q2.addSelect(f5);
q2.addFrom(TBook());

View File

@ -168,7 +168,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
@Test
public void testAccessInternalRepresentation() throws Exception {
SelectQuery query =
SelectQuery<Record> query =
create().select(TBook_ID())
.from(TBook())
.where(TBook_ID().in(1, 2, 3))

View File

@ -68,7 +68,6 @@ import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.SelectQuery;
import org.jooq.SimpleSelectQuery;
import org.jooq.Table;
import org.jooq.TableRecord;
import org.jooq.UpdatableRecord;
@ -128,7 +127,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
@Test
public void testJoinQuery() throws Exception {
SimpleSelectQuery<L> q1 = create().selectQuery(VLibrary());
SelectQuery<L> q1 = create().selectQuery(VLibrary());
// TODO: Fix this when funny issue is fixed in Derby:
// https://sourceforge.net/apps/trac/jooq/ticket/238
@ -144,7 +143,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
Field<Integer> b_authorID = b.getField(TBook_AUTHOR_ID());
Field<String> b_title = b.getField(TBook_TITLE());
SelectQuery q2 = create().selectQuery();
SelectQuery<?> q2 = create().selectQuery();
q2.addFrom(a);
q2.addJoin(b, b_authorID.equal(a_authorID));
q2.addConditions(b_title.notEqual("1984"));

View File

@ -316,7 +316,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
// Null argument checks
Field<Integer> f10 = FAuthorExistsField(null).cast(Integer.class);
SelectQuery q = create().selectQuery();
SelectQuery<Record> q = create().selectQuery();
q.addSelect(
f1a, f2a, f3a, f4a, f5a, f6a, f7a, f8a, f9a,
f1b, f2b, f3b, f4b, f5b, f6b, f7b, f8b, f9b, f10);

View File

@ -96,7 +96,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
@Test
public void testSelectSimpleQuery() throws Exception {
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
Field<Integer> f1 = val(1).as("f1");
Field<Double> f2 = val(2d).as("f2");
Field<String> f3 = val("test").as("f3");
@ -127,7 +127,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
@Test
public void testSelectQuery() throws Exception {
SelectQuery q = create().selectQuery();
SelectQuery<?> q = create().selectQuery();
q.addFrom(TAuthor());
q.addSelect(TAuthor().getFields());
q.addOrderBy(TAuthor_LAST_NAME());
@ -301,11 +301,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
@Test
public void testCombinedSelectQuery() throws Exception {
SelectQuery q1 = create().selectQuery();
SelectQuery q2 = create().selectQuery();
q1.addFrom(TBook());
q2.addFrom(TBook());
SelectQuery<B> q1 = create().selectQuery(TBook());
SelectQuery<B> q2 = create().selectQuery(TBook());
q1.addConditions(TBook_AUTHOR_ID().equal(1));
q2.addConditions(TBook_TITLE().equal("Brida"));

View File

@ -9190,6 +9190,7 @@ for (Record record : create().select(
<li>Result&lt;Record> might change incompatibly</li>
</ul>
<h3>SimpleSelectQuery and SimpleSelectXXXStep API were removed</h3>
<h3>Separation of query building and query execution, removed FactoryOperations</h3>
<h3>No sub-factories anymore (no deprecation yet)</h3>
<h3>Quantified comparison predicates (no deprecation yet)</h3>

View File

@ -82,6 +82,6 @@ public interface SelectFinalStep<R extends Record> extends Select<R> {
/**
* Get the underlying {@link Query} that is being constructed.
*/
SelectQuery getQuery();
SelectQuery<R> getQuery();
}

View File

@ -95,7 +95,7 @@ public interface SelectForUpdateOfStep<R extends Record> extends SelectForUpdate
* Add an <code>OF</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateOf(Field...) see LockProvider for more
* @see SelectQuery#setForUpdateOf(Field...) see LockProvider for more
* details
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
@ -105,7 +105,7 @@ public interface SelectForUpdateOfStep<R extends Record> extends SelectForUpdate
* Add an <code>OF</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateOf(Collection) see LockProvider for
* @see SelectQuery#setForUpdateOf(Collection) see LockProvider for
* more details
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
@ -115,7 +115,7 @@ public interface SelectForUpdateOfStep<R extends Record> extends SelectForUpdate
* Add an <code>OF</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateOf(Table...) see LockProvider for more
* @see SelectQuery#setForUpdateOf(Table...) see LockProvider for more
* details
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, POSTGRES, ORACLE, SYBASE })

View File

@ -102,7 +102,7 @@ public interface SelectForUpdateStep<R extends Record> extends SelectFinalStep<R
* {@link SQLDialect#ORACLE}. These incompatibilities are not reflected by
* the jOOQ API.
*
* @see SimpleSelectQuery#setForUpdate(boolean) see LockProvider for more
* @see SelectQuery#setForUpdate(boolean) see LockProvider for more
* details
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -111,7 +111,7 @@ public interface SelectForUpdateStep<R extends Record> extends SelectFinalStep<R
/**
* Add a <code>FOR SHARE</code> clause to the end of the query.
*
* @see SimpleSelectQuery#setForShare(boolean) see LockProvider for more
* @see SelectQuery#setForShare(boolean) see LockProvider for more
* details
*/
@Support({ MYSQL, POSTGRES })

View File

@ -87,7 +87,7 @@ public interface SelectForUpdateWaitStep<R extends Record> extends SelectFinalSt
* <p>
* Be careful not to confuse this with {@link Object#wait(long)} !
*
* @see SimpleSelectQuery#setForUpdateWait(int) see LockProvider for more
* @see SelectQuery#setForUpdateWait(int) see LockProvider for more
* details
*/
@Support(ORACLE)
@ -97,7 +97,7 @@ public interface SelectForUpdateWaitStep<R extends Record> extends SelectFinalSt
* Add a <code>WAIT</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateNoWait() see LockProvider for more
* @see SelectQuery#setForUpdateNoWait() see LockProvider for more
* details
*/
@Support(ORACLE)
@ -107,7 +107,7 @@ public interface SelectForUpdateWaitStep<R extends Record> extends SelectFinalSt
* Add a <code>WAIT</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateSkipLocked() see LockProvider for more
* @see SelectQuery#setForUpdateSkipLocked() see LockProvider for more
* details
*/
@Support(ORACLE)

View File

@ -36,9 +36,24 @@
package org.jooq;
import static org.jooq.SQLDialect.ASE;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.ORACLE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.SQLDialect.SYBASE;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collection;
import org.jooq.exception.DataAccessException;
@ -48,7 +63,8 @@ import org.jooq.exception.DataAccessException;
*
* @author Lukas Eder
*/
public interface SelectQuery extends SimpleSelectQuery<Record> {
@SuppressWarnings("deprecation")
public interface SelectQuery<R extends Record> extends Select<R>, ConditionProvider {
/**
* Add a list of select fields
@ -299,4 +315,386 @@ public interface SelectQuery extends SimpleSelectQuery<Record> {
@Support({ CUBRID, ORACLE })
void setConnectByStartWith(Condition condition);
// ------------------------------------------------------------------------
// Methods from ConditionProvider, OrderProvider, LockProvider
// ------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Condition... conditions);
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Collection<Condition> conditions);
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Operator operator, Condition... conditions);
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Operator operator, Collection<Condition> conditions);
/**
* Adds ordering fields, ordering by the default sort order
*
* @param fields The ordering fields
*/
@Support
void addOrderBy(Field<?>... fields);
/**
* Adds ordering fields
*
* @param fields The ordering fields
*/
@Support
void addOrderBy(SortField<?>... fields);
/**
* Adds ordering fields
*
* @param fields The ordering fields
*/
@Support
void addOrderBy(Collection<SortField<?>> fields);
/**
* Adds ordering fields
* <p>
* Indexes start at <code>1</code> in SQL!
* <p>
* Note, you can use <code>addOrderBy(Factory.val(1).desc())</code> or
* <code>addOrderBy(Factory.literal(1).desc())</code> to apply descending
* ordering
*
* @param fieldIndexes The ordering fields
*/
@Support
void addOrderBy(int... fieldIndexes);
/**
* Indicate whether the <code>SIBLINGS</code> keyword should be used in an
* <code>ORDER BY</code> clause to form an <code>ORDER SIBLINGS BY</code>
* clause.
* <p>
* This clause can be used only along with Oracle's <code>CONNECT BY</code>
* clause, to indicate that the hierarchical ordering should be preserved
* and elements of each hierarchy should be ordered among themselves.
*
* @param orderBySiblings
*/
@Support({ CUBRID, ORACLE })
void setOrderBySiblings(boolean orderBySiblings);
/**
* Limit the results of this select
* <p>
* This is the same as calling {@link #addLimit(int, int)} with offset = 0
*
* @param numberOfRows The number of rows to return
*/
@Support
void addLimit(int numberOfRows);
/**
* Limit the results of this select using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, this may be simulated with a
* <code>ROW_NUMBER()</code> window function and nested <code>SELECT</code>
* statements.
* <p>
* This is the same as calling {@link #addLimit(int, int)} with offset = 0
*
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(Param<Integer> numberOfRows);
/**
* Limit the results of this select
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or if your RDBMS does not natively support offsets, this is
* simulated with a <code>ROW_NUMBER()</code> window function and nested
* <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(int offset, int numberOfRows);
/**
* Limit the results of this select
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(Param<Integer> offset, int numberOfRows);
/**
* Limit the results of this select using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(int offset, Param<Integer> numberOfRows);
/**
* Limit the results of this select using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(Param<Integer> offset, Param<Integer> numberOfRows);
/**
* Sets the "FOR UPDATE" flag onto the query
* <p>
* <h3>Native implementation</h3> This has been observed to be supported by
* any of these dialects:
* <ul>
* <li><a href=
* "http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=/com.ibm.db2.luw.sql.ref.doc/doc/r0000879.html"
* >DB2 FOR UPDATE and similar clauses</a></li>
* <li><a
* href="http://db.apache.org/derby/docs/10.7/ref/rrefsqlj31783.html">
* Derby's FOR UPDATE clause</a></li>
* <li><a href="http://www.h2database.com/html/grammar.html#select">H2's FOR
* UPDATE clause</a></li>
* <li><a
* href="http://www.hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#N11DA9"
* >HSQLDB's FOR UPDATE clause</a></li>
* <li><a
* href="http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html"
* >MySQL's InnoDB locking reads</a></li>
* <li><a
* href="http://www.techonthenet.com/oracle/cursors/for_update.php">Oracle's
* PL/SQL FOR UPDATE clause</a></li>
* <li><a href=
* "http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE"
* >Postgres FOR UPDATE / FOR SHARE</a></li>
* </ul>
* <h3>Simulation</h3> These dialects can simulate the
* <code>FOR UPDATE</code> clause using a cursor. The cursor is handled by
* the JDBC driver, at {@link PreparedStatement} construction time, when
* calling {@link Connection#prepareStatement(String, int, int)} with
* {@link ResultSet#CONCUR_UPDATABLE}. jOOQ handles simulation of a
* <code>FOR UPDATE</code> clause using <code>CONCUR_UPDATABLE</code> for
* these dialects:
* <ul>
* <li> {@link SQLDialect#CUBRID}</li>
* <li> {@link SQLDialect#SQLSERVER}</li>
* </ul>
* <p>
* Note: This simulation may not be efficient for large result sets!
* <h3>Not supported</h3> These dialects are known not to support the
* <code>FOR UPDATE</code> clause in regular SQL:
* <ul>
* <li> {@link SQLDialect#SQLITE}</li>
* </ul>
* <p>
* If your dialect does not support this clause, jOOQ will still render it,
* if you apply it to your query. This might then cause syntax errors
* reported either by your database or your JDBC driver.
* <p>
* You shouldn't combine this with {@link #setForShare(boolean)}
*
* @param forUpdate The flag's value
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
void setForUpdate(boolean forUpdate);
/**
* Some RDBMS allow for specifying the fields that should be locked by the
* <code>FOR UPDATE</code> clause, instead of the full row.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be natively supported by any of these dialects:
* <ul>
* <li>DB2</li>
* <li>Derby</li>
* <li>H2</li>
* <li>HSQLDB</li>
* <li>Ingres</li>
* <li>Oracle</li>
* <li>Sybase</li>
* </ul>
* <p>
* Note, that {@link SQLDialect#DB2} has some stricter requirements
* regarding the updatability of fields. Refer to the DB2 documentation for
* further details
*
* @param fields The fields that should be locked
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
void setForUpdateOf(Field<?>... fields);
/**
* Some RDBMS allow for specifying the fields that should be locked by the
* <code>FOR UPDATE</code> clause, instead of the full row.
* <p>
*
* @see #setForUpdateOf(Field...)
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
void setForUpdateOf(Collection<? extends Field<?>> fields);
/**
* Some RDBMS allow for specifying the tables that should be locked by the
* <code>FOR UPDATE</code> clause, instead of the full row.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be natively supported by any of these dialects:
* <ul>
* <li>Postgres</li>
* <li>H2</li>
* <li>HSQLDB</li>
* <li>Sybase</li>
* </ul>
* <p>
* jOOQ simulates this by locking all known fields of [<code>tables</code>]
* for any of these dialects:
* <ul>
* <li>DB2</li>
* <li>Derby</li>
* <li>Ingres</li>
* <li>Oracle</li>
* </ul>
*
* @param tables The tables that should be locked
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, POSTGRES, ORACLE, SYBASE })
void setForUpdateOf(Table<?>... tables);
/**
* Some RDBMS allow for specifying the locking mode for the applied
* <code>FOR UPDATE</code> clause. In this case, the session will wait for
* some <code>seconds</code>, before aborting the lock acquirement if the
* lock is not available.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li>Oracle</li>
* </ul>
*
* @param seconds The number of seconds to wait for a lock
*/
@Support(ORACLE)
void setForUpdateWait(int seconds);
/**
* Some RDBMS allow for specifying the locking mode for the applied
* <code>FOR UPDATE</code> clause. In this case, the session will not wait
* before aborting the lock acquirement if the lock is not available.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li>Oracle</li>
* </ul>
*/
@Support(ORACLE)
void setForUpdateNoWait();
/**
* Some RDBMS allow for specifying the locking mode for the applied
* <code>FOR UPDATE</code> clause. In this case, the session will skip all
* locked rows from the select statement, whose lock is not available.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li>Oracle</li>
* </ul>
*/
@Support(ORACLE)
void setForUpdateSkipLocked();
/**
* Sets the "FOR SHARE" flag onto the query
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li><a
* href="http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html"
* >MySQL's InnoDB locking reads</a></li>
* <li><a href=
* "http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE"
* >Postgres FOR UPDATE / FOR SHARE</a></li>
* </ul>
* <p>
* If your dialect does not support this clause, jOOQ will still render it,
* if you apply it to your query. This might then cause syntax errors
* reported either by your database or your JDBC driver.
* <p>
* You shouldn't combine this with {@link #setForUpdate(boolean)}
*
* @param forShare The flag's value
*/
@Support({ MYSQL, POSTGRES })
void setForShare(boolean forShare);
}

View File

@ -1,201 +0,0 @@
/**
* Copyright (c) 2009-2012, 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.Factory;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectConditionStep<R extends Record> extends SimpleSelectOrderByStep<R> {
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#AND} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> and(Condition condition);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#AND} operator and proceed to the next step.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String)
*/
@Support
SimpleSelectConditionStep<R> and(String sql);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#AND} operator and proceed to the next step.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String, Object...)
*/
@Support
SimpleSelectConditionStep<R> and(String sql, Object... bindings);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#AND} operator and proceed to the next step.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String, QueryPart...)
*/
@Support
SimpleSelectConditionStep<R> and(String sql, QueryPart... parts);
/**
* Combine the currently assembled conditions with a negated other one using
* the {@link Operator#AND} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> andNot(Condition condition);
/**
* Combine the currently assembled conditions with an EXISTS clause using
* the {@link Operator#AND} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> andExists(Select<?> select);
/**
* Combine the currently assembled conditions with a NOT EXISTS clause using
* the {@link Operator#AND} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> andNotExists(Select<?> select);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#OR} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> or(Condition condition);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#OR} operator and proceed to the next step.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String)
*/
@Support
SimpleSelectConditionStep<R> or(String sql);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#OR} operator and proceed to the next step.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String, Object...)
*/
@Support
SimpleSelectConditionStep<R> or(String sql, Object... bindings);
/**
* Combine the currently assembled conditions with another one using the
* {@link Operator#OR} operator and proceed to the next step.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String, QueryPart...)
*/
@Support
SimpleSelectConditionStep<R> or(String sql, QueryPart... parts);
/**
* Combine the currently assembled conditions with a negated other one using
* the {@link Operator#OR} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> orNot(Condition condition);
/**
* Combine the currently assembled conditions with an EXISTS clause using
* the {@link Operator#OR} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> orExists(Select<?> select);
/**
* Combine the currently assembled conditions with a NOT EXISTS clause using
* the {@link Operator#OR} operator and proceed to the next step.
*/
@Support
SimpleSelectConditionStep<R> orNotExists(Select<?> select);
}

View File

@ -1,64 +0,0 @@
/**
* Copyright (c) 2009-2012, 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;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectFinalStep<R extends Record> extends Select<R> {
/**
* Get the underlying {@link Query} that is being constructed.
*/
SimpleSelectQuery<R> getQuery();
}

View File

@ -1,101 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.ORACLE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SYBASE;
import java.util.Collection;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectForUpdateOfStep<R extends Record> extends SimpleSelectForUpdateWaitStep<R> {
/**
* Add an <code>OF</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateOf(Field...) see LockProvider for more
* details
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
SimpleSelectForUpdateWaitStep<R> of(Field<?>... fields);
/**
* Add an <code>OF</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateOf(Collection) see LockProvider for
* more details
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
SimpleSelectForUpdateWaitStep<R> of(Collection<Field<?>> fields);
/**
* Add an <code>OF</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateOf(Table...) see LockProvider for more
* details
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, POSTGRES, ORACLE, SYBASE })
SimpleSelectForUpdateWaitStep<R> of(Table<?>... tables);
}

View File

@ -1,93 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.ASE;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.ORACLE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SYBASE;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectForUpdateStep<R extends Record> extends SimpleSelectFinalStep<R> {
/**
* Add a <code>FOR UPDATE</code> clause to the end of the query.
* <p>
* Note: not all SQL dialects allow for combining a <code>FOR UPDATE</code>
* clause with <code>LIMIT .. OFFSET</code>, or with <code>GROUP BY</code>.
* This essentially includes {@link SQLDialect#INGRES} and
* {@link SQLDialect#ORACLE}. These incompatibilities are not reflected by
* the jOOQ API.
*
* @see SimpleSelectQuery#setForUpdate(boolean) see LockProvider for more details
*/
@Support({ ASE, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SYBASE })
SimpleSelectForUpdateOfStep<R> forUpdate();
/**
* Add a <code>FOR SHARE</code> clause to the end of the query.
*
* @see SimpleSelectQuery#setForShare(boolean) see LockProvider for more details
*/
@Support({ MYSQL, POSTGRES })
SimpleSelectFinalStep<R> forShare();
}

View File

@ -1,90 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.ORACLE;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectForUpdateWaitStep<R extends Record> extends SimpleSelectFinalStep<R> {
/**
* Add a <code>WAIT</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
* <p>
* Be careful not to confuse this with {@link Object#wait(long)} !
*
* @see SimpleSelectQuery#setForUpdateWait(int) see LockProvider for more details
*/
@Support(ORACLE)
SimpleSelectFinalStep<R> wait(int seconds);
/**
* Add a <code>WAIT</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateNoWait() see LockProvider for more details
*/
@Support(ORACLE)
SimpleSelectFinalStep<R> noWait();
/**
* Add a <code>WAIT</code> clause to the <code>FOR UPDATE</code> clause at
* the end of the query.
*
* @see SimpleSelectQuery#setForUpdateSkipLocked() see LockProvider for more
* details
*/
@Support(ORACLE)
SimpleSelectFinalStep<R> skipLocked();
}

View File

@ -1,161 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.ORACLE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.SQLDialect.SYBASE;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectLimitStep<R extends Record> extends SimpleSelectForUpdateStep<R> {
/**
* Add a <code>LIMIT</code> clause to the query
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
* <p>
* This is the same as calling {@link #limit(int, int)} with offset = 0, or
* calling <code>.limit(numberOfRows).offset(0)</code>
*/
@Support
SimpleSelectOffsetStep<R> limit(int numberOfRows);
/**
* Add a <code>LIMIT</code> clause to the query using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, this may be simulated with a <code>ROW_NUMBER()</code>
* window function and nested <code>SELECT</code> statements.
* <p>
* This is the same as calling {@link #limit(int, int)} with offset = 0, or
* calling <code>.limit(numberOfRows).offset(0)</code>
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectOffsetStep<R> limit(Param<Integer> numberOfRows);
/**
* Add a <code>LIMIT</code> clause to the query
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or if your RDBMS does not natively support offsets, this is
* simulated with a <code>ROW_NUMBER()</code> window function and nested
* <code>SELECT</code> statements.
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectForUpdateStep<R> limit(int offset, int numberOfRows);
/**
* Add a <code>LIMIT</code> clause to the query using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function and
* nested <code>SELECT</code> statements.
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectForUpdateStep<R> limit(int offset, Param<Integer> numberOfRows);
/**
* Add a <code>LIMIT</code> clause to the query using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function and
* nested <code>SELECT</code> statements.
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectForUpdateStep<R> limit(Param<Integer> offset, int numberOfRows);
/**
* Add a <code>LIMIT</code> clause to the query using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectForUpdateStep<R> limit(Param<Integer> offset, Param<Integer> numberOfRows);
}

View File

@ -1,94 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.ORACLE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.SQLDialect.SYBASE;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectOffsetStep<R extends Record> extends SimpleSelectForUpdateStep<R> {
/**
* Add an <code>OFFSET</code> clause to the query
* <p>
* If there is no <code>LIMIT .. OFFSET</code> or <code>TOP</code> clause in
* your RDBMS, or if your RDBMS does not natively support offsets, this is
* simulated with a <code>ROW_NUMBER()</code> window function and nested
* <code>SELECT</code> statements.
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectForUpdateStep<R> offset(int offset);
/**
* Add an <code>OFFSET</code> clause to the query using a named parameter
* <p>
* If there is no <code>LIMIT .. OFFSET</code> or <code>TOP</code> clause in
* your RDBMS, or if your RDBMS does not natively support offsets, this is
* simulated with a <code>ROW_NUMBER()</code> window function and nested
* <code>SELECT</code> statements.
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
SimpleSelectForUpdateStep<R> offset(Param<Integer> offset);
}

View File

@ -1,139 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.ORACLE;
import java.util.Collection;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectOrderByStep<R extends Record> extends SimpleSelectLimitStep<R> {
/**
* Add an <code>ORDER BY</code> clause to the query
*/
@Support
SimpleSelectLimitStep<R> orderBy(Field<?>... fields);
/**
* Add an <code>ORDER BY</code> clause to the query
*/
@Support
SimpleSelectLimitStep<R> orderBy(SortField<?>... fields);
/**
* Add an <code>ORDER BY</code> clause to the query
*/
@Support
SimpleSelectLimitStep<R> orderBy(Collection<SortField<?>> fields);
/**
* Add an <code>ORDER BY</code> clause to the query
* <p>
* Indexes start at <code>1</code> in SQL!
* <p>
* Note, you can use <code>orderBy(Factory.val(1).desc())</code> or
* <code>orderBy(Factory.literal(1).desc())</code> to apply descending
* ordering
*/
@Support
SimpleSelectLimitStep<R> orderBy(int... fieldIndexes);
/**
* Add an <code>ORDER SIBLINGS BY</code> clause to the query
* <p>
* This clause can be used only along with Oracle's <code>CONNECT BY</code>
* clause, to indicate that the hierarchical ordering should be preserved
* and elements of each hierarchy should be ordered among themselves.
*/
@Support({ CUBRID, ORACLE })
SimpleSelectLimitStep<R> orderSiblingsBy(Field<?>... fields);
/**
* Add an <code>ORDER SIBLINGS BY</code> clause to the query
* <p>
* This clause can be used only along with Oracle's <code>CONNECT BY</code>
* clause, to indicate that the hierarchical ordering should be preserved
* and elements of each hierarchy should be ordered among themselves.
*/
@Support({ CUBRID, ORACLE })
SimpleSelectLimitStep<R> orderSiblingsBy(SortField<?>... fields);
/**
* Add an <code>ORDER SIBLINGS BY</code> clause to the query
* <p>
* This clause can be used only along with Oracle's <code>CONNECT BY</code>
* clause, to indicate that the hierarchical ordering should be preserved
* and elements of each hierarchy should be ordered among themselves.
*/
@Support({ CUBRID, ORACLE })
SimpleSelectLimitStep<R> orderSiblingsBy(Collection<SortField<?>> fields);
/**
* Add an <code>ORDER SIBLINGS BY</code> clause to the query
* <p>
* This clause can be used only along with Oracle's <code>CONNECT BY</code>
* clause, to indicate that the hierarchical ordering should be preserved
* and elements of each hierarchy should be ordered among themselves.
* <p>
* Indexes start at <code>1</code> in SQL!
* <p>
* Note, you can use <code>orderSiblingsBy(Factory.val(1).desc())</code> or
* <code>orderBy(Factory.literal(1).desc())</code> to apply descending
* ordering
*/
@Support({ CUBRID, ORACLE })
SimpleSelectLimitStep<R> orderSiblingsBy(int... fieldIndexes);
}

View File

@ -1,457 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.SQLDialect.ASE;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.ORACLE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.SQLDialect.SYBASE;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collection;
/**
* A simple select query that provides Records from a single table, with no
* joins allowed.
* <p>
* This is the type of query that is possible with a {@link SimpleSelectQuery}:
* <p>
* <code>
* SELECT * FROM [table] WHERE [conditions] ORDER BY [ordering] LIMIT [limit clause]
* </code>
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
* @see SelectQuery
*/
@SuppressWarnings("deprecation")
public interface SimpleSelectQuery<R extends Record> extends Select<R>, ConditionProvider {
// ------------------------------------------------------------------------
// Methods from ConditionProvider, OrderProvider, LockProvider
// ------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Condition... conditions);
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Collection<Condition> conditions);
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Operator operator, Condition... conditions);
/**
* {@inheritDoc}
*/
@Override
@Support
void addConditions(Operator operator, Collection<Condition> conditions);
/**
* Adds ordering fields, ordering by the default sort order
*
* @param fields The ordering fields
*/
@Support
void addOrderBy(Field<?>... fields);
/**
* Adds ordering fields
*
* @param fields The ordering fields
*/
@Support
void addOrderBy(SortField<?>... fields);
/**
* Adds ordering fields
*
* @param fields The ordering fields
*/
@Support
void addOrderBy(Collection<SortField<?>> fields);
/**
* Adds ordering fields
* <p>
* Indexes start at <code>1</code> in SQL!
* <p>
* Note, you can use <code>addOrderBy(Factory.val(1).desc())</code> or
* <code>addOrderBy(Factory.literal(1).desc())</code> to apply descending
* ordering
*
* @param fieldIndexes The ordering fields
*/
@Support
void addOrderBy(int... fieldIndexes);
/**
* Indicate whether the <code>SIBLINGS</code> keyword should be used in an
* <code>ORDER BY</code> clause to form an <code>ORDER SIBLINGS BY</code>
* clause.
* <p>
* This clause can be used only along with Oracle's <code>CONNECT BY</code>
* clause, to indicate that the hierarchical ordering should be preserved
* and elements of each hierarchy should be ordered among themselves.
*
* @param orderBySiblings
*/
@Support({ CUBRID, ORACLE })
void setOrderBySiblings(boolean orderBySiblings);
/**
* Limit the results of this select
* <p>
* This is the same as calling {@link #addLimit(int, int)} with offset = 0
*
* @param numberOfRows The number of rows to return
*/
@Support
void addLimit(int numberOfRows);
/**
* Limit the results of this select using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, this may be simulated with a
* <code>ROW_NUMBER()</code> window function and nested <code>SELECT</code>
* statements.
* <p>
* This is the same as calling {@link #addLimit(int, int)} with offset = 0
*
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(Param<Integer> numberOfRows);
/**
* Limit the results of this select
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or if your RDBMS does not natively support offsets, this is
* simulated with a <code>ROW_NUMBER()</code> window function and nested
* <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(int offset, int numberOfRows);
/**
* Limit the results of this select
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(Param<Integer> offset, int numberOfRows);
/**
* Limit the results of this select using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(int offset, Param<Integer> numberOfRows);
/**
* Limit the results of this select using named parameters
* <p>
* Note that some dialects do not support bind values at all in
* <code>LIMIT</code> or <code>TOP</code> clauses!
* <p>
* If there is no <code>LIMIT</code> or <code>TOP</code> clause in your
* RDBMS, or the <code>LIMIT</code> or <code>TOP</code> clause does not
* support bind values, or if your RDBMS does not natively support offsets,
* this may be simulated with a <code>ROW_NUMBER()</code> window function
* and nested <code>SELECT</code> statements.
*
* @param offset The lowest offset starting at 0
* @param numberOfRows The number of rows to return
*/
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SQLITE, SQLSERVER, SYBASE })
void addLimit(Param<Integer> offset, Param<Integer> numberOfRows);
/**
* Sets the "FOR UPDATE" flag onto the query
* <p>
* <h3>Native implementation</h3> This has been observed to be supported by
* any of these dialects:
* <ul>
* <li><a href=
* "http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=/com.ibm.db2.luw.sql.ref.doc/doc/r0000879.html"
* >DB2 FOR UPDATE and similar clauses</a></li>
* <li><a
* href="http://db.apache.org/derby/docs/10.7/ref/rrefsqlj31783.html">
* Derby's FOR UPDATE clause</a></li>
* <li><a href="http://www.h2database.com/html/grammar.html#select">H2's FOR
* UPDATE clause</a></li>
* <li><a
* href="http://www.hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#N11DA9"
* >HSQLDB's FOR UPDATE clause</a></li>
* <li><a
* href="http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html"
* >MySQL's InnoDB locking reads</a></li>
* <li><a
* href="http://www.techonthenet.com/oracle/cursors/for_update.php">Oracle's
* PL/SQL FOR UPDATE clause</a></li>
* <li><a href=
* "http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE"
* >Postgres FOR UPDATE / FOR SHARE</a></li>
* </ul>
* <h3>Simulation</h3> These dialects can simulate the
* <code>FOR UPDATE</code> clause using a cursor. The cursor is handled by
* the JDBC driver, at {@link PreparedStatement} construction time, when
* calling {@link Connection#prepareStatement(String, int, int)} with
* {@link ResultSet#CONCUR_UPDATABLE}. jOOQ handles simulation of a
* <code>FOR UPDATE</code> clause using <code>CONCUR_UPDATABLE</code> for
* these dialects:
* <ul>
* <li> {@link SQLDialect#CUBRID}</li>
* <li> {@link SQLDialect#SQLSERVER}</li>
* </ul>
* <p>
* Note: This simulation may not be efficient for large result sets!
* <h3>Not supported</h3> These dialects are known not to support the
* <code>FOR UPDATE</code> clause in regular SQL:
* <ul>
* <li> {@link SQLDialect#SQLITE}</li>
* </ul>
* <p>
* If your dialect does not support this clause, jOOQ will still render it,
* if you apply it to your query. This might then cause syntax errors
* reported either by your database or your JDBC driver.
* <p>
* You shouldn't combine this with {@link #setForShare(boolean)}
*
* @param forUpdate The flag's value
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
void setForUpdate(boolean forUpdate);
/**
* Some RDBMS allow for specifying the fields that should be locked by the
* <code>FOR UPDATE</code> clause, instead of the full row.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be natively supported by any of these dialects:
* <ul>
* <li>DB2</li>
* <li>Derby</li>
* <li>H2</li>
* <li>HSQLDB</li>
* <li>Ingres</li>
* <li>Oracle</li>
* <li>Sybase</li>
* </ul>
* <p>
* Note, that {@link SQLDialect#DB2} has some stricter requirements
* regarding the updatability of fields. Refer to the DB2 documentation for
* further details
*
* @param fields The fields that should be locked
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
void setForUpdateOf(Field<?>... fields);
/**
* Some RDBMS allow for specifying the fields that should be locked by the
* <code>FOR UPDATE</code> clause, instead of the full row.
* <p>
*
* @see #setForUpdateOf(Field...)
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, SYBASE })
void setForUpdateOf(Collection<? extends Field<?>> fields);
/**
* Some RDBMS allow for specifying the tables that should be locked by the
* <code>FOR UPDATE</code> clause, instead of the full row.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be natively supported by any of these dialects:
* <ul>
* <li>Postgres</li>
* <li>H2</li>
* <li>HSQLDB</li>
* <li>Sybase</li>
* </ul>
* <p>
* jOOQ simulates this by locking all known fields of [<code>tables</code>]
* for any of these dialects:
* <ul>
* <li>DB2</li>
* <li>Derby</li>
* <li>Ingres</li>
* <li>Oracle</li>
* </ul>
*
* @param tables The tables that should be locked
*/
@Support({ DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, POSTGRES, ORACLE, SYBASE })
void setForUpdateOf(Table<?>... tables);
/**
* Some RDBMS allow for specifying the locking mode for the applied
* <code>FOR UPDATE</code> clause. In this case, the session will wait for
* some <code>seconds</code>, before aborting the lock acquirement if the
* lock is not available.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li>Oracle</li>
* </ul>
*
* @param seconds The number of seconds to wait for a lock
*/
@Support(ORACLE)
void setForUpdateWait(int seconds);
/**
* Some RDBMS allow for specifying the locking mode for the applied
* <code>FOR UPDATE</code> clause. In this case, the session will not wait
* before aborting the lock acquirement if the lock is not available.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li>Oracle</li>
* </ul>
*/
@Support(ORACLE)
void setForUpdateNoWait();
/**
* Some RDBMS allow for specifying the locking mode for the applied
* <code>FOR UPDATE</code> clause. In this case, the session will skip all
* locked rows from the select statement, whose lock is not available.
* <p>
* This automatically sets the {@link #setForUpdate(boolean)} flag, and
* unsets the {@link #setForShare(boolean)} flag, if it was previously set.
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li>Oracle</li>
* </ul>
*/
@Support(ORACLE)
void setForUpdateSkipLocked();
/**
* Sets the "FOR SHARE" flag onto the query
* <p>
* This has been observed to be supported by any of these dialects:
* <ul>
* <li><a
* href="http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html"
* >MySQL's InnoDB locking reads</a></li>
* <li><a href=
* "http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE"
* >Postgres FOR UPDATE / FOR SHARE</a></li>
* </ul>
* <p>
* If your dialect does not support this clause, jOOQ will still render it,
* if you apply it to your query. This might then cause syntax errors
* reported either by your database or your JDBC driver.
* <p>
* You shouldn't combine this with {@link #setForUpdate(boolean)}
*
* @param forShare The flag's value
*/
@Support({ MYSQL, POSTGRES })
void setForShare(boolean forShare);
}

View File

@ -1,125 +0,0 @@
/**
* Copyright (c) 2009-2012, 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.Collection;
import org.jooq.impl.Factory;
/**
* This type is used for the {@link Select}'s DSL API when selecting specific
* {@link Record} types.
* <p>
* Example: <code><pre>
* create.selectFrom(T_AUTHOR)
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @param <R> The record type being returned by this query
* @author Lukas Eder
*/
public interface SimpleSelectWhereStep<R extends Record> extends SimpleSelectOrderByStep<R> {
/**
* Add a <code>WHERE</code> clause to the query
*/
@Support
SimpleSelectConditionStep<R> where(Condition... conditions);
/**
* Add a <code>WHERE</code> clause to the query
*/
@Support
SimpleSelectConditionStep<R> where(Collection<Condition> conditions);
/**
* Add a <code>WHERE</code> clause to the query
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String)
*/
@Support
SimpleSelectConditionStep<R> where(String sql);
/**
* Add a <code>WHERE</code> clause to the query
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String, Object...)
*/
@Support
SimpleSelectConditionStep<R> where(String sql, Object... bindings);
/**
* Add a <code>WHERE</code> clause to the query
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @see Factory#condition(String, QueryPart...)
*/
@Support
SimpleSelectConditionStep<R> where(String sql, QueryPart... parts);
/**
* Add a <code>WHERE EXISTS</code> clause to the query
*/
@Support
SimpleSelectConditionStep<R> whereExists(Select<?> select);
/**
* Add a <code>WHERE NOT EXISTS</code> clause to the query
*/
@Support
SimpleSelectConditionStep<R> whereNotExists(Select<?> select);
}

View File

@ -186,7 +186,7 @@ public interface UpdatableRecord<R extends UpdatableRecord<R>> extends Updatable
* checking of database record state and the actual <code>UPDATE</code></li>
* </ul>
* <p>
* See {@link SimpleSelectQuery#setForUpdate(boolean)} for more details</li>
* See {@link SelectQuery#setForUpdate(boolean)} for more details</li>
* </ul>
* <h3>Statement examples</h3>
* <p>
@ -252,7 +252,7 @@ public interface UpdatableRecord<R extends UpdatableRecord<R>> extends Updatable
* checking of database record state and the actual <code>DELETE</code></li>
* </ul>
* <p>
* See {@link SimpleSelectQuery#setForUpdate(boolean)} for more details</li>
* See {@link SelectQuery#setForUpdate(boolean)} for more details</li>
* </ul>
* <h3>Statement examples</h3>
* <p>

View File

@ -1,426 +0,0 @@
/**
* Copyright (c) 2009-2012, 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.sql.ResultSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import org.jooq.Converter;
import org.jooq.Cursor;
import org.jooq.Field;
import org.jooq.FutureResult;
import org.jooq.Record;
import org.jooq.RecordHandler;
import org.jooq.RecordMapper;
import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.Select;
import org.jooq.SelectQuery;
import org.jooq.Table;
/**
* This class serves as a base class for <code>SelectImpl</code> and
* <code>SimpleSelectImpl</code>, the two classes that implement the
* <code>SELECT</code> DSL API. It delegates all calls of the {@link Select} API
* to an underlying {@link Select} (e.g. a non-DSL {@link SelectQuery})
*
* @author Lukas Eder
*/
abstract class AbstractDelegatingSelect<R extends Record>
extends AbstractDelegatingQuery<Select<R>>
implements Select<R> {
/**
* Generated UID
*/
private static final long serialVersionUID = 3382400928803573548L;
AbstractDelegatingSelect(Select<R> query) {
super(query);
}
@Override
public final ResultQuery<R> maxRows(int rows) {
return getDelegate().maxRows(rows);
}
@Override
public final Class<? extends R> getRecordType() {
return getDelegate().getRecordType();
}
@Override
public final List<Field<?>> getSelect() {
return getDelegate().getSelect();
}
@Override
public final Result<R> getResult() {
return getDelegate().getResult();
}
@Override
public final Result<R> fetch() {
return getDelegate().fetch();
}
@Override
public final ResultSet fetchResultSet() {
return getDelegate().fetchResultSet();
}
@Override
public final Cursor<R> fetchLazy() {
return getDelegate().fetchLazy();
}
@Override
public final Cursor<R> fetchLazy(int fetchSize) {
return getDelegate().fetchLazy(fetchSize);
}
@Override
public final List<Result<Record>> fetchMany() {
return getDelegate().fetchMany();
}
@Override
public final <T> List<T> fetch(Field<T> field) {
return getDelegate().fetch(field);
}
@Override
public final <T> List<T> fetch(Field<?> field, Class<? extends T> type) {
return getDelegate().fetch(field, type);
}
@Override
public final <T, U> List<U> fetch(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetch(field, converter);
}
@Override
public final List<?> fetch(int fieldIndex) {
return getDelegate().fetch(fieldIndex);
}
@Override
public final <T> List<T> fetch(int fieldIndex, Class<? extends T> type) {
return getDelegate().fetch(fieldIndex, type);
}
@Override
public final <U> List<U> fetch(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetch(fieldIndex, converter);
}
@Override
public final List<?> fetch(String fieldName) {
return getDelegate().fetch(fieldName);
}
@Override
public final <T> List<T> fetch(String fieldName, Class<? extends T> type) {
return getDelegate().fetch(fieldName, type);
}
@Override
public final <U> List<U> fetch(String fieldName, Converter<?, U> converter) {
return getDelegate().fetch(fieldName, converter);
}
@Override
public final <T> T fetchOne(Field<T> field) {
return getDelegate().fetchOne(field);
}
@Override
public final <T> T fetchOne(Field<?> field, Class<? extends T> type) {
return getDelegate().fetchOne(field, type);
}
@Override
public final <T, U> U fetchOne(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetchOne(field, converter);
}
@Override
public final Object fetchOne(int fieldIndex) {
return getDelegate().fetchOne(fieldIndex);
}
@Override
public final <T> T fetchOne(int fieldIndex, Class<? extends T> type) {
return getDelegate().fetchOne(fieldIndex, type);
}
@Override
public final <U> U fetchOne(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetchOne(fieldIndex, converter);
}
@Override
public final Object fetchOne(String fieldName) {
return getDelegate().fetchOne(fieldName);
}
@Override
public final <T> T fetchOne(String fieldName, Class<? extends T> type) {
return getDelegate().fetchOne(fieldName, type);
}
@Override
public final <U> U fetchOne(String fieldName, Converter<?, U> converter) {
return getDelegate().fetchOne(fieldName, converter);
}
@Override
public final R fetchOne() {
return getDelegate().fetchOne();
}
@Override
public final R fetchAny() {
return getDelegate().fetchAny();
}
@Override
public final <K> Map<K, R> fetchMap(Field<K> key) {
return getDelegate().fetchMap(key);
}
@Override
public final <K, V> Map<K, V> fetchMap(Field<K> key, Field<V> value) {
return getDelegate().fetchMap(key, value);
}
@Override
public final Map<Record, R> fetchMap(Field<?>[] keys) {
return getDelegate().fetchMap(keys);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) {
return getDelegate().fetchMap(keys, type);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchMap(key, type);
}
@Override
public final List<Map<String, Object>> fetchMaps() {
return getDelegate().fetchMaps();
}
@Override
public final Map<String, Object> fetchOneMap() {
return getDelegate().fetchOneMap();
}
@Override
public final <K> Map<K, Result<R>> fetchGroups(Field<K> key) {
return getDelegate().fetchGroups(key);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(Field<K> key, Field<V> value) {
return getDelegate().fetchGroups(key, value);
}
@Override
public final Map<Record, Result<R>> fetchGroups(Field<?>[] keys) {
return getDelegate().fetchGroups(keys);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(Field<?>[] keys, Class<? extends E> type) {
return getDelegate().fetchGroups(keys, type);
}
@Override
public final Object[][] fetchArrays() {
return getDelegate().fetchArrays();
}
@Override
public final Object[] fetchArray(int fieldIndex) {
return getDelegate().fetchArray(fieldIndex);
}
@Override
public final <T> T[] fetchArray(int fieldIndex, Class<? extends T> type) {
return getDelegate().fetchArray(fieldIndex, type);
}
@Override
public final <U> U[] fetchArray(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetchArray(fieldIndex, converter);
}
@Override
public final Object[] fetchArray(String fieldName) {
return getDelegate().fetchArray(fieldName);
}
@Override
public final <T> T[] fetchArray(String fieldName, Class<? extends T> type) {
return getDelegate().fetchArray(fieldName, type);
}
@Override
public final <U> U[] fetchArray(String fieldName, Converter<?, U> converter) {
return getDelegate().fetchArray(fieldName, converter);
}
@Override
public final <T> T[] fetchArray(Field<T> field) {
return getDelegate().fetchArray(field);
}
@Override
public final <T> T[] fetchArray(Field<?> field, Class<? extends T> type) {
return getDelegate().fetchArray(field, type);
}
@Override
public final <T, U> U[] fetchArray(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetchArray(field, converter);
}
@Override
public final Object[] fetchOneArray() {
return getDelegate().fetchOneArray();
}
@Override
public final <T> List<T> fetchInto(Class<? extends T> type) {
return getDelegate().fetchInto(type);
}
@Override
public final <E> E fetchOneInto(Class<? extends E> type) {
return getDelegate().fetchOneInto(type);
}
@Override
public final <Z extends Record> Z fetchOneInto(Table<Z> table) {
return getDelegate().fetchOneInto(table);
}
@Override
public final <Z extends Record> Result<Z> fetchInto(Table<Z> table) {
return getDelegate().fetchInto(table);
}
@Override
public final <H extends RecordHandler<R>> H fetchInto(H handler) {
return getDelegate().fetchInto(handler);
}
@Override
public final <E> List<E> fetch(RecordMapper<? super R, E> mapper) {
return getDelegate().fetch(mapper);
}
@Override
public final <K, E> Map<K, List<E>> fetchGroups(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchGroups(key, type);
}
@Override
public final FutureResult<R> fetchLater() {
return getDelegate().fetchLater();
}
@Override
public final FutureResult<R> fetchLater(ExecutorService executor) {
return getDelegate().fetchLater(executor);
}
@Override
public final Table<R> asTable() {
return getDelegate().asTable();
}
@Override
public final Table<R> asTable(String alias) {
return getDelegate().asTable(alias);
}
@Override
public final <T> Field<T> asField() {
return getDelegate().asField();
}
@Override
public final <T> Field<T> asField(String alias) {
return getDelegate().asField(alias);
}
@Override
public final <T> Field<T> getField(Field<T> field) {
return getDelegate().asTable().getField(field);
}
@Override
public final Field<?> getField(String name) {
return getDelegate().asTable().getField(name);
}
@Override
public final Field<?> getField(int index) {
return getDelegate().asTable().getField(index);
}
@Override
public final List<Field<?>> getFields() {
return getDelegate().asTable().getFields();
}
@Override
public final int getIndex(Field<?> field) {
return getDelegate().asTable().getIndex(field);
}
@Override
public final int getIndex(String fieldName) {
return getDelegate().asTable().getIndex(fieldName);
}
}

View File

@ -1,885 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static java.util.Arrays.asList;
import static org.jooq.SQLDialect.ASE;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.impl.Factory.inline;
import static org.jooq.impl.Factory.name;
import static org.jooq.impl.Factory.one;
import static org.jooq.impl.Factory.rowNumber;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.jooq.BindContext;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Field;
import org.jooq.GroupField;
import org.jooq.Operator;
import org.jooq.Param;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.RenderContext;
import org.jooq.SQLDialect;
import org.jooq.SimpleSelectQuery;
import org.jooq.SortField;
import org.jooq.Table;
import org.jooq.TableLike;
import org.jooq.tools.StringUtils;
/**
* A sub-select is a <code>SELECT</code> statement that can be combined with
* other <code>SELECT</code> statement in <code>UNION</code>s and similar
* operations.
*
* @author Lukas Eder
*/
abstract class AbstractSubSelect<R extends Record> extends AbstractSelect<R> implements SimpleSelectQuery<R> {
/**
* Generated UID
*/
private static final long serialVersionUID = 1646393178384872967L;
private final FieldList select;
private String hint;
private boolean distinct;
private boolean forUpdate;
private final FieldList forUpdateOf;
private final TableList forUpdateOfTables;
private ForUpdateMode forUpdateMode;
private int forUpdateWait;
private boolean forShare;
private final TableList from;
private final ConditionProviderImpl condition;
private final ConditionProviderImpl connectBy;
private boolean connectByNoCycle;
private final ConditionProviderImpl connectByStartWith;
private boolean grouping;
private final QueryPartList<GroupField> groupBy;
private final ConditionProviderImpl having;
private final SortFieldList orderBy;
private boolean orderBySiblings;
private final Limit limit;
AbstractSubSelect(Configuration configuration) {
this(configuration, null);
}
AbstractSubSelect(Configuration configuration, TableLike<? extends R> from) {
this(configuration, from, false);
}
AbstractSubSelect(Configuration configuration, TableLike<? extends R> from, boolean distinct) {
super(configuration);
this.distinct = distinct;
this.select = new SelectFieldList();
this.from = new TableList();
this.condition = new ConditionProviderImpl();
this.connectBy = new ConditionProviderImpl();
this.connectByStartWith = new ConditionProviderImpl();
this.groupBy = new QueryPartList<GroupField>();
this.having = new ConditionProviderImpl();
this.orderBy = new SortFieldList();
this.limit = new Limit();
if (from != null) {
this.from.add(from.asTable());
}
this.forUpdateOf = new FieldList();
this.forUpdateOfTables = new TableList();
}
@Override
public final void bind(BindContext context) {
context.declareFields(true)
.bind((QueryPart) getSelect0())
.declareFields(false)
.declareTables(true)
.bind((QueryPart) getFrom())
.declareTables(false)
.bind(getWhere())
.bind(getConnectByStartWith())
.bind(getConnectBy())
.bind((QueryPart) getGroupBy())
.bind(getHaving())
.bind((QueryPart) getOrderBy());
// TOP clauses never bind values. So this can be safely applied at the
// end for LIMIT .. OFFSET clauses, or ROW_NUMBER() filtering
if (getLimit().isApplicable()) {
context.bind(getLimit());
}
context.bind((QueryPart) forUpdateOf)
.bind((QueryPart) forUpdateOfTables);
}
@Override
public final void toSQL(RenderContext context) {
// If a limit applies
if (getLimit().isApplicable()) {
switch (context.getDialect()) {
// Oracle knows the ROWNUM pseudo-column. That makes things simple
case ORACLE:
toSQLReferenceLimitOracle(context);
break;
// With DB2, there are two possibilities
case DB2: {
// DB2 natively supports a "FIRST ROWS" clause, without
// offset and without bind values
if (getLimit().offsetZero() && !getLimit().rendersParams()) {
toSQLReferenceLimitDefault(context);
}
// "OFFSET" has to be simulated
else {
toSQLReferenceLimitDB2SQLServerSybase(context);
}
break;
}
// Sybase ASE and SQL Server support a TOP clause without OFFSET
// OFFSET can be simulated in SQL Server, not in ASE
case ASE:
case SQLSERVER: {
// Native TOP support, without OFFSET and without bind values
if (getLimit().offsetZero() && !getLimit().rendersParams()) {
toSQLReference0(context);
}
// OFFSET simulation
else {
toSQLReferenceLimitDB2SQLServerSybase(context);
}
break;
}
// Sybase has TOP .. START AT support (no bind values)
// Firebird has FIRST .. SKIP support (no bind values)
case SYBASE: {
// Native TOP support, without OFFSET and without bind values
if (!getLimit().rendersParams()) {
toSQLReference0(context);
}
// OFFSET simulation
else {
toSQLReferenceLimitDB2SQLServerSybase(context);
}
break;
}
// By default, render the dialect's limit clause
default: {
toSQLReferenceLimitDefault(context);
break;
}
}
}
// If no limit applies, just render the rest of the query
else {
toSQLReference0(context);
}
// [#1296] FOR UPDATE is simulated in some dialects using ResultSet.CONCUR_UPDATABLE
if (forUpdate && !asList(CUBRID, SQLSERVER).contains(context.getDialect())) {
context.formatSeparator()
.keyword("for update");
if (!forUpdateOf.isEmpty()) {
context.keyword(" of ");
Utils.fieldNames(context, forUpdateOf);
}
else if (!forUpdateOfTables.isEmpty()) {
context.keyword(" of ");
switch (context.getDialect()) {
// Some dialects don't allow for an OF [table-names] clause
// It can be simulated by listing the table's fields, though
case DB2:
case DERBY:
case INGRES:
case ORACLE: {
forUpdateOfTables.toSQLFieldNames(context);
break;
}
// Render the OF [table-names] clause
default:
Utils.tableNames(context, forUpdateOfTables);
break;
}
}
if (forUpdateMode != null) {
context.sql(" ");
context.keyword(forUpdateMode.toSQL());
if (forUpdateMode == ForUpdateMode.WAIT) {
context.sql(" ");
context.sql(forUpdateWait);
}
}
}
else if (forShare) {
switch (context.getDialect()) {
// MySQL has a non-standard implementation for the "FOR SHARE" clause
case MYSQL:
context.formatSeparator()
.keyword("lock in share mode");
break;
// Postgres is known to implement the "FOR SHARE" clause like this
default:
context.formatSeparator()
.keyword("for share");
break;
}
}
}
/**
* The default LIMIT / OFFSET clause in most dialects
*/
private void toSQLReferenceLimitDefault(RenderContext context) {
toSQLReference0(context);
context.sql(getLimit());
}
/**
* Simulate the LIMIT / OFFSET clause in the {@link SQLDialect#DB2},
* {@link SQLDialect#SQLSERVER} and {@link SQLDialect#SYBASE} dialects
*/
private final void toSQLReferenceLimitDB2SQLServerSybase(RenderContext context) {
// [#1954] Render enclosed SELECT first to obtain a "unique" hash code
RenderContext tmpLocal = new DefaultRenderContext(context);
toSQLReference0(tmpLocal);
String tmpEnclosed = tmpLocal.render();
String subqueryName = "limit_" + Utils.hash(tmpEnclosed);
String rownumName = "rownum_" + Utils.hash(tmpEnclosed);
// Render enclosed SELECT again, adding an additional ROW_NUMBER() OVER()
// window function, calculating row numbers for the LIMIT .. OFFSET clause
RenderContext local = new DefaultRenderContext(context);
toSQLReference0(local, rowNumber().over().orderBy(getNonEmptyOrderBy()).as(rownumName));
String enclosed = local.render();
context.keyword("select * from (")
.formatIndentStart()
.formatNewLine()
.sql(enclosed)
.formatIndentEnd()
.formatNewLine()
.keyword(") as ")
.sql(name(subqueryName))
.formatSeparator()
.keyword("where ")
.sql(name(rownumName))
.sql(" > ")
.sql(getLimit().getLowerRownum())
.formatSeparator()
.keyword("and ")
.sql(name(rownumName))
.sql(" <= ")
.sql(getLimit().getUpperRownum());
}
/**
* Simulate the LIMIT / OFFSET clause in the {@link SQLDialect#ORACLE}
* dialect
*/
private final void toSQLReferenceLimitOracle(RenderContext context) {
RenderContext local = new DefaultRenderContext(context);
toSQLReference0(local);
String enclosed = local.render();
String subqueryName = "limit_" + Utils.hash(enclosed);
String rownumName = "rownum_" + Utils.hash(enclosed);
context.keyword("select * from (")
.formatIndentStart()
.formatNewLine()
.keyword("select ")
.sql(name(subqueryName))
.keyword(".*, rownum as ")
.sql(name(rownumName))
.formatSeparator()
.keyword("from (")
.formatIndentStart()
.formatNewLine()
.sql(enclosed)
.formatIndentEnd()
.formatNewLine()
.sql(") ")
.sql(name(subqueryName))
.formatSeparator()
.keyword("where rownum <= ")
.sql(getLimit().getUpperRownum())
.formatIndentEnd()
.formatNewLine()
.sql(") ")
.formatSeparator()
.keyword("where ")
.sql(name(rownumName))
.sql(" > ")
.sql(getLimit().getLowerRownum());
}
/**
* This method renders the main part of a query without the LIMIT clause.
* This part is common to any type of limited query
*/
private final void toSQLReference0(RenderContext context) {
toSQLReference0(context, null);
}
/**
* This method renders the main part of a query without the LIMIT clause.
* This part is common to any type of limited query
*/
private final void toSQLReference0(RenderContext context, QueryPart limitOffsetRownumber) {
// SELECT clause
// -------------
context.keyword("select ");
// [#1493] Oracle hints come directly after the SELECT keyword
if (!StringUtils.isBlank(hint)) {
context.sql(hint).sql(" ");
}
if (distinct) {
context.keyword("distinct ");
}
// Sybase and SQL Server have leading TOP clauses
switch (context.getDialect()) {
case ASE:
case SQLSERVER: {
// If we have a TOP clause, it needs to be rendered here
if (getLimit().isApplicable() && getLimit().offsetZero() && !getLimit().rendersParams()) {
context.sql(getLimit()).sql(" ");
}
// If we don't have a limit, some subqueries still need a "TOP" clause
else if (context.getDialect() == SQLSERVER && !getOrderBy().isEmpty()) {
// [#759] The TOP 100% is only rendered in subqueries
if (context.subquery() || getLimit().isApplicable()) {
context.keyword("top 100 percent ");
}
}
break;
}
case SYBASE: {
if (getLimit().isApplicable() && !getLimit().rendersParams()) {
context.sql(getLimit()).sql(" ");
}
break;
}
// [#780] Ordered subqueries should be handled for Ingres and ASE as well
case INGRES: {
}
}
context.declareFields(true);
context.sql(getSelect1());
if (limitOffsetRownumber != null) {
// [#1724] Inlining is necessary to avoid further complexity between
// toSQL()'s LIMIT .. OFFSET rendering and bind()'s "obliviousness"
// thereof. This should be improved by delegating to composed Select
// objects.
boolean inline = context.inline();
context.inline(true)
.sql(",")
.formatIndentStart()
.formatSeparator()
.sql(limitOffsetRownumber)
.formatIndentEnd()
.inline(inline);
}
context.declareFields(false);
// FROM and JOIN clauses
// ---------------------
context.declareTables(true);
if (!context.render(getFrom()).isEmpty()) {
context.formatSeparator()
.keyword("from ")
.sql(getFrom());
// [#1681] Sybase ASE and Ingres need a cross-joined dummy table
// To be able to GROUP BY () empty sets
if (grouping && getGroupBy().isEmpty() && asList(ASE, INGRES).contains(context.getDialect())) {
context.sql(", (select 1 as x) as empty_grouping_dummy_table");
}
}
context.declareTables(false);
// WHERE clause
// ------------
if (!(getWhere().getWhere() instanceof TrueCondition)) {
context.formatSeparator()
.keyword("where ")
.sql(getWhere());
}
// 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);
}
// GROUP BY and HAVING clause
// --------------------------
if (grouping) {
context.formatSeparator()
.keyword("group by ");
// [#1665] Empty GROUP BY () clauses need parentheses
if (getGroupBy().isEmpty()) {
// [#1681] Use the constant field from the dummy table Sybase ASE, Ingres
if (asList(ASE, INGRES).contains(context.getDialect())) {
context.sql("empty_grouping_dummy_table.x");
}
// Some dialects don't support empty GROUP BY () clauses
else if (asList(CUBRID, DERBY, FIREBIRD, HSQLDB, MYSQL, POSTGRES, SQLITE).contains(context.getDialect())) {
context.sql("1");
}
// Few dialects support the SQL standard empty grouping set
else {
context.sql("()");
}
}
else {
context.sql(getGroupBy());
}
}
if (!(getHaving().getWhere() instanceof TrueCondition)) {
context.formatSeparator()
.keyword("having ")
.sql(getHaving());
}
// ORDER BY clause
// ---------------
if (!getOrderBy().isEmpty()) {
context.formatSeparator()
.keyword("order ")
.keyword(orderBySiblings ? "siblings " : "")
.keyword("by ")
.sql(getOrderBy());
}
}
private void toSQLStartWith(RenderContext context) {
if (!(getConnectByStartWith().getWhere() instanceof TrueCondition)) {
context.formatSeparator()
.keyword("start with ")
.sql(getConnectByStartWith());
}
}
private void toSQLConnectBy(RenderContext context) {
context.formatSeparator()
.keyword("connect by");
if (connectByNoCycle) {
context.keyword(" nocycle");
}
context.sql(" ").sql(getConnectBy());
}
// @Mixin - Declaration in SelectQuery
public final void addSelect(Collection<? extends Field<?>> fields) {
getSelect0().addAll(fields);
}
// @Mixin - Declaration in SelectQuery
public final void addSelect(Field<?>... fields) {
addSelect(Arrays.asList(fields));
}
// @Mixin - Declaration in SelectQuery
public final void setDistinct(boolean distinct) {
this.distinct = distinct;
}
@Override
public final void addLimit(int numberOfRows) {
addLimit(0, numberOfRows);
}
@Override
public final void addLimit(Param<Integer> numberOfRows) {
addLimit(0, numberOfRows);
}
@Override
public final void addLimit(int offset, int numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void addLimit(int offset, Param<Integer> numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void addLimit(Param<Integer> offset, int numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void addLimit(Param<Integer> offset, Param<Integer> numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void setForUpdate(boolean forUpdate) {
this.forUpdate = forUpdate;
this.forShare = false;
}
@Override
public final void setForUpdateOf(Field<?>... fields) {
setForUpdateOf(Arrays.asList(fields));
}
@Override
public final void setForUpdateOf(Collection<? extends Field<?>> fields) {
setForUpdate(true);
forUpdateOf.clear();
forUpdateOfTables.clear();
forUpdateOf.addAll(fields);
}
@Override
public final void setForUpdateOf(Table<?>... tables) {
setForUpdate(true);
forUpdateOf.clear();
forUpdateOfTables.clear();
forUpdateOfTables.addAll(Arrays.asList(tables));
}
@Override
public final void setForUpdateWait(int seconds) {
setForUpdate(true);
forUpdateMode = ForUpdateMode.WAIT;
forUpdateWait = seconds;
}
@Override
public final void setForUpdateNoWait() {
setForUpdate(true);
forUpdateMode = ForUpdateMode.NOWAIT;
forUpdateWait = 0;
}
@Override
public final void setForUpdateSkipLocked() {
setForUpdate(true);
forUpdateMode = ForUpdateMode.SKIP_LOCKED;
forUpdateWait = 0;
}
@Override
public final void setForShare(boolean forShare) {
this.forUpdate = false;
this.forShare = forShare;
this.forUpdateOf.clear();
this.forUpdateOfTables.clear();
this.forUpdateMode = null;
this.forUpdateWait = 0;
}
@Override
public final List<Field<?>> getSelect() {
return getSelect1();
}
final FieldList getSelect0() {
return select;
}
final FieldList getSelect1() {
if (getSelect0().isEmpty()) {
FieldList result = new SelectFieldList();
// [#109] [#489]: SELECT * is only applied when at least one table
// from the table source is "unknown", i.e. not generated from a
// physical table. Otherwise, the fields are selected explicitly
if (knownTableSource()) {
for (TableLike<?> table : getFrom()) {
for (Field<?> field : table.asTable().getFields()) {
result.add(field);
}
}
}
// The default is SELECT 1, when projections and table sources are
// both empty
if (getFrom().isEmpty()) {
result.add(one());
}
return result;
}
return getSelect0();
}
private final boolean knownTableSource() {
for (Table<?> table : getFrom()) {
if (!knownTable(table)) {
return false;
}
}
return true;
}
private final boolean knownTable(Table<?> table) {
return table.getFields().size() > 0;
}
@SuppressWarnings("unchecked")
@Override
public final Class<? extends R> getRecordType() {
// Generated record classes only come into play, when the select is
// - on a single table
// - a select *
if (getFrom().size() == 1 && getSelect0().isEmpty()) {
return (Class<? extends R>) getFrom().get(0).asTable().getRecordType();
}
else {
return (Class<? extends R>) RecordImpl.class;
}
}
final TableList getFrom() {
return from;
}
final void setGrouping() {
grouping = true;
}
final QueryPartList<GroupField> getGroupBy() {
return groupBy;
}
final Limit getLimit() {
return limit;
}
final ConditionProviderImpl getWhere() {
return condition;
}
final ConditionProviderImpl getConnectBy() {
return connectBy;
}
final ConditionProviderImpl getConnectByStartWith() {
return connectByStartWith;
}
final ConditionProviderImpl getHaving() {
return having;
}
final SortFieldList getOrderBy() {
return orderBy;
}
final SortFieldList getNonEmptyOrderBy() {
if (getOrderBy().isEmpty()) {
SortFieldList result = new SortFieldList();
result.add(getSelect().get(0).asc());
return result;
}
return getOrderBy();
}
@Override
public final void addOrderBy(Collection<SortField<?>> fields) {
getOrderBy().addAll(fields);
}
@Override
public final void addOrderBy(Field<?>... fields) {
getOrderBy().addAll(fields);
}
@Override
public final void addOrderBy(SortField<?>... fields) {
addOrderBy(Arrays.asList(fields));
}
@Override
public final void addOrderBy(int... fieldIndexes) {
Field<?>[] fields = new Field[fieldIndexes.length];
for (int i = 0; i < fieldIndexes.length; i++) {
fields[i] = inline(fieldIndexes[i]);
}
addOrderBy(fields);
}
@Override
public final void setOrderBySiblings(boolean orderBySiblings) {
this.orderBySiblings = orderBySiblings;
}
@Override
public final void addConditions(Condition... conditions) {
condition.addConditions(conditions);
}
@Override
public final void addConditions(Collection<Condition> conditions) {
condition.addConditions(conditions);
}
@Override
public final void addConditions(Operator operator, Condition... conditions) {
condition.addConditions(operator, conditions);
}
@Override
public final void addConditions(Operator operator, Collection<Condition> conditions) {
condition.addConditions(operator, conditions);
}
final void setConnectByNoCycle(boolean connectByNoCycle) {
this.connectByNoCycle = connectByNoCycle;
}
final void setStartWith(Condition condition) {
connectByStartWith.addConditions(condition);
}
final void setHint(String hint) {
this.hint = hint;
}
@Override
final boolean isForUpdate() {
return forUpdate;
}
// -------------------------------------------------------------------------
// Utility classes
// -------------------------------------------------------------------------
/**
* The lock mode for the <code>FOR UPDATE</code> clause, if set.
*/
private static enum ForUpdateMode {
WAIT("wait"),
NOWAIT("nowait"),
SKIP_LOCKED("skip locked"),
;
private final String sql;
private ForUpdateMode(String sql) {
this.sql = sql;
}
public final String toSQL() {
return sql;
}
}
}

View File

@ -104,9 +104,8 @@ import org.jooq.SQLDialect;
import org.jooq.Schema;
import org.jooq.SelectQuery;
import org.jooq.SelectSelectStep;
import org.jooq.SelectWhereStep;
import org.jooq.Sequence;
import org.jooq.SimpleSelectQuery;
import org.jooq.SimpleSelectWhereStep;
import org.jooq.Support;
import org.jooq.Table;
import org.jooq.TableLike;
@ -1300,8 +1299,8 @@ public class Executor implements Configuration {
* </pre></code>
*/
@Support
public final <R extends Record> SimpleSelectWhereStep<R> selectFrom(Table<R> table) {
return new SimpleSelectImpl<R>(this, table);
public final <R extends Record> SelectWhereStep<R> selectFrom(Table<R> table) {
return new SelectImpl<R>(this).from(table);
}
/**
@ -1518,7 +1517,7 @@ public class Executor implements Configuration {
* Create a new {@link SelectQuery}
*/
@Support
public final SelectQuery selectQuery() {
public final SelectQuery<Record> selectQuery() {
return new SelectQueryImpl(this);
}
@ -1529,8 +1528,8 @@ public class Executor implements Configuration {
* @return The new {@link SelectQuery}
*/
@Support
public final <R extends Record> SimpleSelectQuery<R> selectQuery(TableLike<R> table) {
return new SimpleSelectQueryImpl<R>(this, table);
public final <R extends Record> SelectQuery<R> selectQuery(TableLike<R> table) {
return new SelectQueryImpl<R>(this, table);
}
/**

View File

@ -58,7 +58,7 @@ import org.jooq.LoaderCSVStep;
import org.jooq.LoaderError;
import org.jooq.LoaderOptionsStep;
import org.jooq.LoaderXMLStep;
import org.jooq.SimpleSelectQuery;
import org.jooq.SelectQuery;
import org.jooq.Table;
import org.jooq.TableRecord;
import org.jooq.UpdatableTable;
@ -380,7 +380,7 @@ class LoaderImpl<R extends TableRecord<R>> implements
// TODO: This can be implemented faster using a MERGE statement
// in some dialects
else if (onDuplicate == ON_DUPLICATE_KEY_IGNORE) {
SimpleSelectQuery<R> select = create.selectQuery(table);
SelectQuery<R> select = create.selectQuery(table);
for (int i = 0; i < row.length; i++) {
if (i < fields.length && mainKey[i]) {

View File

@ -40,19 +40,30 @@ import static org.jooq.impl.Factory.exists;
import static org.jooq.impl.Factory.notExists;
import static org.jooq.impl.Factory.table;
import java.sql.ResultSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.Cursor;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.FutureResult;
import org.jooq.GroupField;
import org.jooq.JoinType;
import org.jooq.Operator;
import org.jooq.Param;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.RecordHandler;
import org.jooq.RecordMapper;
import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.Select;
import org.jooq.SelectConditionStep;
import org.jooq.SelectConnectByConditionStep;
@ -76,7 +87,7 @@ import org.jooq.exception.DataAccessException;
*
* @author Lukas Eder
*/
class SelectImpl<R extends Record> extends AbstractDelegatingSelect<R> implements
class SelectImpl<R extends Record> extends AbstractDelegatingQuery<Select<R>> implements
// Cascading interface implementations for Select behaviour
SelectSelectStep<R>,
@ -128,9 +139,8 @@ class SelectImpl<R extends Record> extends AbstractDelegatingSelect<R> implement
this(configuration, false);
}
@SuppressWarnings("unchecked")
SelectImpl(Configuration configuration, boolean distinct) {
this((Select<R>) new SelectQueryImpl(configuration, distinct));
this(new SelectQueryImpl<R>(configuration, distinct));
}
SelectImpl(Select<R> query) {
@ -138,8 +148,8 @@ class SelectImpl<R extends Record> extends AbstractDelegatingSelect<R> implement
}
@Override
public final SelectQuery getQuery() {
return (SelectQuery) getDelegate();
public final SelectQuery<R> getQuery() {
return (SelectQuery<R>) getDelegate();
}
/**
@ -897,6 +907,356 @@ class SelectImpl<R extends Record> extends AbstractDelegatingSelect<R> implement
return partitionBy(fields.toArray(new Field[fields.size()]));
}
@Override
public final ResultQuery<R> maxRows(int rows) {
return getDelegate().maxRows(rows);
}
@Override
public final Class<? extends R> getRecordType() {
return getDelegate().getRecordType();
}
@Override
public final List<Field<?>> getSelect() {
return getDelegate().getSelect();
}
@Override
public final Result<R> getResult() {
return getDelegate().getResult();
}
@Override
public final Result<R> fetch() {
return getDelegate().fetch();
}
@Override
public final ResultSet fetchResultSet() {
return getDelegate().fetchResultSet();
}
@Override
public final Cursor<R> fetchLazy() {
return getDelegate().fetchLazy();
}
@Override
public final Cursor<R> fetchLazy(int fetchSize) {
return getDelegate().fetchLazy(fetchSize);
}
@Override
public final List<Result<Record>> fetchMany() {
return getDelegate().fetchMany();
}
@Override
public final <T> List<T> fetch(Field<T> field) {
return getDelegate().fetch(field);
}
@Override
public final <T> List<T> fetch(Field<?> field, Class<? extends T> type) {
return getDelegate().fetch(field, type);
}
@Override
public final <T, U> List<U> fetch(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetch(field, converter);
}
@Override
public final List<?> fetch(int fieldIndex) {
return getDelegate().fetch(fieldIndex);
}
@Override
public final <T> List<T> fetch(int fieldIndex, Class<? extends T> type) {
return getDelegate().fetch(fieldIndex, type);
}
@Override
public final <U> List<U> fetch(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetch(fieldIndex, converter);
}
@Override
public final List<?> fetch(String fieldName) {
return getDelegate().fetch(fieldName);
}
@Override
public final <T> List<T> fetch(String fieldName, Class<? extends T> type) {
return getDelegate().fetch(fieldName, type);
}
@Override
public final <U> List<U> fetch(String fieldName, Converter<?, U> converter) {
return getDelegate().fetch(fieldName, converter);
}
@Override
public final <T> T fetchOne(Field<T> field) {
return getDelegate().fetchOne(field);
}
@Override
public final <T> T fetchOne(Field<?> field, Class<? extends T> type) {
return getDelegate().fetchOne(field, type);
}
@Override
public final <T, U> U fetchOne(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetchOne(field, converter);
}
@Override
public final Object fetchOne(int fieldIndex) {
return getDelegate().fetchOne(fieldIndex);
}
@Override
public final <T> T fetchOne(int fieldIndex, Class<? extends T> type) {
return getDelegate().fetchOne(fieldIndex, type);
}
@Override
public final <U> U fetchOne(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetchOne(fieldIndex, converter);
}
@Override
public final Object fetchOne(String fieldName) {
return getDelegate().fetchOne(fieldName);
}
@Override
public final <T> T fetchOne(String fieldName, Class<? extends T> type) {
return getDelegate().fetchOne(fieldName, type);
}
@Override
public final <U> U fetchOne(String fieldName, Converter<?, U> converter) {
return getDelegate().fetchOne(fieldName, converter);
}
@Override
public final R fetchOne() {
return getDelegate().fetchOne();
}
@Override
public final R fetchAny() {
return getDelegate().fetchAny();
}
@Override
public final <K> Map<K, R> fetchMap(Field<K> key) {
return getDelegate().fetchMap(key);
}
@Override
public final <K, V> Map<K, V> fetchMap(Field<K> key, Field<V> value) {
return getDelegate().fetchMap(key, value);
}
@Override
public final Map<Record, R> fetchMap(Field<?>[] keys) {
return getDelegate().fetchMap(keys);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) {
return getDelegate().fetchMap(keys, type);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchMap(key, type);
}
@Override
public final List<Map<String, Object>> fetchMaps() {
return getDelegate().fetchMaps();
}
@Override
public final Map<String, Object> fetchOneMap() {
return getDelegate().fetchOneMap();
}
@Override
public final <K> Map<K, Result<R>> fetchGroups(Field<K> key) {
return getDelegate().fetchGroups(key);
}
@Override
public final <K, V> Map<K, List<V>> fetchGroups(Field<K> key, Field<V> value) {
return getDelegate().fetchGroups(key, value);
}
@Override
public final Map<Record, Result<R>> fetchGroups(Field<?>[] keys) {
return getDelegate().fetchGroups(keys);
}
@Override
public final <E> Map<Record, List<E>> fetchGroups(Field<?>[] keys, Class<? extends E> type) {
return getDelegate().fetchGroups(keys, type);
}
@Override
public final Object[][] fetchArrays() {
return getDelegate().fetchArrays();
}
@Override
public final Object[] fetchArray(int fieldIndex) {
return getDelegate().fetchArray(fieldIndex);
}
@Override
public final <T> T[] fetchArray(int fieldIndex, Class<? extends T> type) {
return getDelegate().fetchArray(fieldIndex, type);
}
@Override
public final <U> U[] fetchArray(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetchArray(fieldIndex, converter);
}
@Override
public final Object[] fetchArray(String fieldName) {
return getDelegate().fetchArray(fieldName);
}
@Override
public final <T> T[] fetchArray(String fieldName, Class<? extends T> type) {
return getDelegate().fetchArray(fieldName, type);
}
@Override
public final <U> U[] fetchArray(String fieldName, Converter<?, U> converter) {
return getDelegate().fetchArray(fieldName, converter);
}
@Override
public final <T> T[] fetchArray(Field<T> field) {
return getDelegate().fetchArray(field);
}
@Override
public final <T> T[] fetchArray(Field<?> field, Class<? extends T> type) {
return getDelegate().fetchArray(field, type);
}
@Override
public final <T, U> U[] fetchArray(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetchArray(field, converter);
}
@Override
public final Object[] fetchOneArray() {
return getDelegate().fetchOneArray();
}
@Override
public final <T> List<T> fetchInto(Class<? extends T> type) {
return getDelegate().fetchInto(type);
}
@Override
public final <E> E fetchOneInto(Class<? extends E> type) {
return getDelegate().fetchOneInto(type);
}
@Override
public final <Z extends Record> Z fetchOneInto(Table<Z> table) {
return getDelegate().fetchOneInto(table);
}
@Override
public final <Z extends Record> Result<Z> fetchInto(Table<Z> table) {
return getDelegate().fetchInto(table);
}
@Override
public final <H extends RecordHandler<R>> H fetchInto(H handler) {
return getDelegate().fetchInto(handler);
}
@Override
public final <E> List<E> fetch(RecordMapper<? super R, E> mapper) {
return getDelegate().fetch(mapper);
}
@Override
public final <K, E> Map<K, List<E>> fetchGroups(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchGroups(key, type);
}
@Override
public final FutureResult<R> fetchLater() {
return getDelegate().fetchLater();
}
@Override
public final FutureResult<R> fetchLater(ExecutorService executor) {
return getDelegate().fetchLater(executor);
}
@Override
public final Table<R> asTable() {
return getDelegate().asTable();
}
@Override
public final Table<R> asTable(String alias) {
return getDelegate().asTable(alias);
}
@Override
public final <T> Field<T> asField() {
return getDelegate().asField();
}
@Override
public final <T> Field<T> asField(String alias) {
return getDelegate().asField(alias);
}
@Override
public final <T> Field<T> getField(Field<T> field) {
return getDelegate().asTable().getField(field);
}
@Override
public final Field<?> getField(String name) {
return getDelegate().asTable().getField(name);
}
@Override
public final Field<?> getField(int index) {
return getDelegate().asTable().getField(index);
}
@Override
public final List<Field<?>> getFields() {
return getDelegate().asTable().getFields();
}
@Override
public final int getIndex(Field<?> field) {
return getDelegate().asTable().getIndex(field);
}
@Override
public final int getIndex(String fieldName) {
return getDelegate().asTable().getIndex(fieldName);
}
/**
* The {@link SelectImpl} current condition step
* <p>

View File

@ -33,12 +33,29 @@
* 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 static java.util.Arrays.asList;
import static org.jooq.SQLDialect.ASE;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.impl.Factory.inline;
import static org.jooq.impl.Factory.name;
import static org.jooq.impl.Factory.one;
import static org.jooq.impl.Factory.rowNumber;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.jooq.BindContext;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Field;
@ -46,19 +63,53 @@ import org.jooq.ForeignKey;
import org.jooq.GroupField;
import org.jooq.JoinType;
import org.jooq.Operator;
import org.jooq.Param;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.RenderContext;
import org.jooq.SQLDialect;
import org.jooq.SelectQuery;
import org.jooq.SortField;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.TableLike;
import org.jooq.exception.DataAccessException;
import org.jooq.tools.StringUtils;
/**
* A sub-select is a <code>SELECT</code> statement that can be combined with
* other <code>SELECT</code> statement in <code>UNION</code>s and similar
* operations.
*
* @author Lukas Eder
*/
class SelectQueryImpl extends AbstractSubSelect<Record> implements SelectQuery {
class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements SelectQuery<R> {
private static final long serialVersionUID = 1555503854543561285L;
/**
* Generated UID
*/
private static final long serialVersionUID = 1646393178384872967L;
private final FieldList select;
private String hint;
private boolean distinct;
private boolean forUpdate;
private final FieldList forUpdateOf;
private final TableList forUpdateOfTables;
private ForUpdateMode forUpdateMode;
private int forUpdateWait;
private boolean forShare;
private final TableList from;
private final ConditionProviderImpl condition;
private final ConditionProviderImpl connectBy;
private boolean connectByNoCycle;
private final ConditionProviderImpl connectByStartWith;
private boolean grouping;
private final QueryPartList<GroupField> groupBy;
private final ConditionProviderImpl having;
private final SortFieldList orderBy;
private boolean orderBySiblings;
private final Limit limit;
SelectQueryImpl(Configuration configuration) {
this(configuration, null);
@ -68,40 +119,779 @@ class SelectQueryImpl extends AbstractSubSelect<Record> implements SelectQuery {
this(configuration, null, distinct);
}
SelectQueryImpl(Configuration configuration, TableLike<?> from) {
SelectQueryImpl(Configuration configuration, TableLike<? extends R> from) {
this(configuration, from, false);
}
SelectQueryImpl(Configuration configuration, TableLike<?> from, boolean distinct) {
super(configuration, from, distinct);
SelectQueryImpl(Configuration configuration, TableLike<? extends R> from, boolean distinct) {
super(configuration);
this.distinct = distinct;
this.select = new SelectFieldList();
this.from = new TableList();
this.condition = new ConditionProviderImpl();
this.connectBy = new ConditionProviderImpl();
this.connectByStartWith = new ConditionProviderImpl();
this.groupBy = new QueryPartList<GroupField>();
this.having = new ConditionProviderImpl();
this.orderBy = new SortFieldList();
this.limit = new Limit();
if (from != null) {
this.from.add(from.asTable());
}
this.forUpdateOf = new FieldList();
this.forUpdateOfTables = new TableList();
}
@Override
public final void addFrom(Collection<? extends TableLike<?>> from) {
for (TableLike<?> provider : from) {
public final void bind(BindContext context) {
context.declareFields(true)
.bind((QueryPart) getSelect0())
.declareFields(false)
.declareTables(true)
.bind((QueryPart) getFrom())
.declareTables(false)
.bind(getWhere())
.bind(getConnectByStartWith())
.bind(getConnectBy())
.bind((QueryPart) getGroupBy())
.bind(getHaving())
.bind((QueryPart) getOrderBy());
// TOP clauses never bind values. So this can be safely applied at the
// end for LIMIT .. OFFSET clauses, or ROW_NUMBER() filtering
if (getLimit().isApplicable()) {
context.bind(getLimit());
}
context.bind((QueryPart) forUpdateOf)
.bind((QueryPart) forUpdateOfTables);
}
@Override
public final void toSQL(RenderContext context) {
// If a limit applies
if (getLimit().isApplicable()) {
switch (context.getDialect()) {
// Oracle knows the ROWNUM pseudo-column. That makes things simple
case ORACLE:
toSQLReferenceLimitOracle(context);
break;
// With DB2, there are two possibilities
case DB2: {
// DB2 natively supports a "FIRST ROWS" clause, without
// offset and without bind values
if (getLimit().offsetZero() && !getLimit().rendersParams()) {
toSQLReferenceLimitDefault(context);
}
// "OFFSET" has to be simulated
else {
toSQLReferenceLimitDB2SQLServerSybase(context);
}
break;
}
// Sybase ASE and SQL Server support a TOP clause without OFFSET
// OFFSET can be simulated in SQL Server, not in ASE
case ASE:
case SQLSERVER: {
// Native TOP support, without OFFSET and without bind values
if (getLimit().offsetZero() && !getLimit().rendersParams()) {
toSQLReference0(context);
}
// OFFSET simulation
else {
toSQLReferenceLimitDB2SQLServerSybase(context);
}
break;
}
// Sybase has TOP .. START AT support (no bind values)
// Firebird has FIRST .. SKIP support (no bind values)
case SYBASE: {
// Native TOP support, without OFFSET and without bind values
if (!getLimit().rendersParams()) {
toSQLReference0(context);
}
// OFFSET simulation
else {
toSQLReferenceLimitDB2SQLServerSybase(context);
}
break;
}
// By default, render the dialect's limit clause
default: {
toSQLReferenceLimitDefault(context);
break;
}
}
}
// If no limit applies, just render the rest of the query
else {
toSQLReference0(context);
}
// [#1296] FOR UPDATE is simulated in some dialects using ResultSet.CONCUR_UPDATABLE
if (forUpdate && !asList(CUBRID, SQLSERVER).contains(context.getDialect())) {
context.formatSeparator()
.keyword("for update");
if (!forUpdateOf.isEmpty()) {
context.keyword(" of ");
Utils.fieldNames(context, forUpdateOf);
}
else if (!forUpdateOfTables.isEmpty()) {
context.keyword(" of ");
switch (context.getDialect()) {
// Some dialects don't allow for an OF [table-names] clause
// It can be simulated by listing the table's fields, though
case DB2:
case DERBY:
case INGRES:
case ORACLE: {
forUpdateOfTables.toSQLFieldNames(context);
break;
}
// Render the OF [table-names] clause
default:
Utils.tableNames(context, forUpdateOfTables);
break;
}
}
if (forUpdateMode != null) {
context.sql(" ");
context.keyword(forUpdateMode.toSQL());
if (forUpdateMode == ForUpdateMode.WAIT) {
context.sql(" ");
context.sql(forUpdateWait);
}
}
}
else if (forShare) {
switch (context.getDialect()) {
// MySQL has a non-standard implementation for the "FOR SHARE" clause
case MYSQL:
context.formatSeparator()
.keyword("lock in share mode");
break;
// Postgres is known to implement the "FOR SHARE" clause like this
default:
context.formatSeparator()
.keyword("for share");
break;
}
}
}
/**
* The default LIMIT / OFFSET clause in most dialects
*/
private void toSQLReferenceLimitDefault(RenderContext context) {
toSQLReference0(context);
context.sql(getLimit());
}
/**
* Simulate the LIMIT / OFFSET clause in the {@link SQLDialect#DB2},
* {@link SQLDialect#SQLSERVER} and {@link SQLDialect#SYBASE} dialects
*/
private final void toSQLReferenceLimitDB2SQLServerSybase(RenderContext context) {
// [#1954] Render enclosed SELECT first to obtain a "unique" hash code
RenderContext tmpLocal = new DefaultRenderContext(context);
toSQLReference0(tmpLocal);
String tmpEnclosed = tmpLocal.render();
String subqueryName = "limit_" + Utils.hash(tmpEnclosed);
String rownumName = "rownum_" + Utils.hash(tmpEnclosed);
// Render enclosed SELECT again, adding an additional ROW_NUMBER() OVER()
// window function, calculating row numbers for the LIMIT .. OFFSET clause
RenderContext local = new DefaultRenderContext(context);
toSQLReference0(local, rowNumber().over().orderBy(getNonEmptyOrderBy()).as(rownumName));
String enclosed = local.render();
context.keyword("select * from (")
.formatIndentStart()
.formatNewLine()
.sql(enclosed)
.formatIndentEnd()
.formatNewLine()
.keyword(") as ")
.sql(name(subqueryName))
.formatSeparator()
.keyword("where ")
.sql(name(rownumName))
.sql(" > ")
.sql(getLimit().getLowerRownum())
.formatSeparator()
.keyword("and ")
.sql(name(rownumName))
.sql(" <= ")
.sql(getLimit().getUpperRownum());
}
/**
* Simulate the LIMIT / OFFSET clause in the {@link SQLDialect#ORACLE}
* dialect
*/
private final void toSQLReferenceLimitOracle(RenderContext context) {
RenderContext local = new DefaultRenderContext(context);
toSQLReference0(local);
String enclosed = local.render();
String subqueryName = "limit_" + Utils.hash(enclosed);
String rownumName = "rownum_" + Utils.hash(enclosed);
context.keyword("select * from (")
.formatIndentStart()
.formatNewLine()
.keyword("select ")
.sql(name(subqueryName))
.keyword(".*, rownum as ")
.sql(name(rownumName))
.formatSeparator()
.keyword("from (")
.formatIndentStart()
.formatNewLine()
.sql(enclosed)
.formatIndentEnd()
.formatNewLine()
.sql(") ")
.sql(name(subqueryName))
.formatSeparator()
.keyword("where rownum <= ")
.sql(getLimit().getUpperRownum())
.formatIndentEnd()
.formatNewLine()
.sql(") ")
.formatSeparator()
.keyword("where ")
.sql(name(rownumName))
.sql(" > ")
.sql(getLimit().getLowerRownum());
}
/**
* This method renders the main part of a query without the LIMIT clause.
* This part is common to any type of limited query
*/
private final void toSQLReference0(RenderContext context) {
toSQLReference0(context, null);
}
/**
* This method renders the main part of a query without the LIMIT clause.
* This part is common to any type of limited query
*/
private final void toSQLReference0(RenderContext context, QueryPart limitOffsetRownumber) {
// SELECT clause
// -------------
context.keyword("select ");
// [#1493] Oracle hints come directly after the SELECT keyword
if (!StringUtils.isBlank(hint)) {
context.sql(hint).sql(" ");
}
if (distinct) {
context.keyword("distinct ");
}
// Sybase and SQL Server have leading TOP clauses
switch (context.getDialect()) {
case ASE:
case SQLSERVER: {
// If we have a TOP clause, it needs to be rendered here
if (getLimit().isApplicable() && getLimit().offsetZero() && !getLimit().rendersParams()) {
context.sql(getLimit()).sql(" ");
}
// If we don't have a limit, some subqueries still need a "TOP" clause
else if (context.getDialect() == SQLSERVER && !getOrderBy().isEmpty()) {
// [#759] The TOP 100% is only rendered in subqueries
if (context.subquery() || getLimit().isApplicable()) {
context.keyword("top 100 percent ");
}
}
break;
}
case SYBASE: {
if (getLimit().isApplicable() && !getLimit().rendersParams()) {
context.sql(getLimit()).sql(" ");
}
break;
}
// [#780] Ordered subqueries should be handled for Ingres and ASE as well
case INGRES: {
}
}
context.declareFields(true);
context.sql(getSelect1());
if (limitOffsetRownumber != null) {
// [#1724] Inlining is necessary to avoid further complexity between
// toSQL()'s LIMIT .. OFFSET rendering and bind()'s "obliviousness"
// thereof. This should be improved by delegating to composed Select
// objects.
boolean inline = context.inline();
context.inline(true)
.sql(",")
.formatIndentStart()
.formatSeparator()
.sql(limitOffsetRownumber)
.formatIndentEnd()
.inline(inline);
}
context.declareFields(false);
// FROM and JOIN clauses
// ---------------------
context.declareTables(true);
if (!context.render(getFrom()).isEmpty()) {
context.formatSeparator()
.keyword("from ")
.sql(getFrom());
// [#1681] Sybase ASE and Ingres need a cross-joined dummy table
// To be able to GROUP BY () empty sets
if (grouping && getGroupBy().isEmpty() && asList(ASE, INGRES).contains(context.getDialect())) {
context.sql(", (select 1 as x) as empty_grouping_dummy_table");
}
}
context.declareTables(false);
// WHERE clause
// ------------
if (!(getWhere().getWhere() instanceof TrueCondition)) {
context.formatSeparator()
.keyword("where ")
.sql(getWhere());
}
// 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);
}
// GROUP BY and HAVING clause
// --------------------------
if (grouping) {
context.formatSeparator()
.keyword("group by ");
// [#1665] Empty GROUP BY () clauses need parentheses
if (getGroupBy().isEmpty()) {
// [#1681] Use the constant field from the dummy table Sybase ASE, Ingres
if (asList(ASE, INGRES).contains(context.getDialect())) {
context.sql("empty_grouping_dummy_table.x");
}
// Some dialects don't support empty GROUP BY () clauses
else if (asList(CUBRID, DERBY, FIREBIRD, HSQLDB, MYSQL, POSTGRES, SQLITE).contains(context.getDialect())) {
context.sql("1");
}
// Few dialects support the SQL standard empty grouping set
else {
context.sql("()");
}
}
else {
context.sql(getGroupBy());
}
}
if (!(getHaving().getWhere() instanceof TrueCondition)) {
context.formatSeparator()
.keyword("having ")
.sql(getHaving());
}
// ORDER BY clause
// ---------------
if (!getOrderBy().isEmpty()) {
context.formatSeparator()
.keyword("order ")
.keyword(orderBySiblings ? "siblings " : "")
.keyword("by ")
.sql(getOrderBy());
}
}
private void toSQLStartWith(RenderContext context) {
if (!(getConnectByStartWith().getWhere() instanceof TrueCondition)) {
context.formatSeparator()
.keyword("start with ")
.sql(getConnectByStartWith());
}
}
private void toSQLConnectBy(RenderContext context) {
context.formatSeparator()
.keyword("connect by");
if (connectByNoCycle) {
context.keyword(" nocycle");
}
context.sql(" ").sql(getConnectBy());
}
@Override
public final void addSelect(Collection<? extends Field<?>> fields) {
getSelect0().addAll(fields);
}
@Override
public final void addSelect(Field<?>... fields) {
addSelect(Arrays.asList(fields));
}
@Override
public final void setDistinct(boolean distinct) {
this.distinct = distinct;
}
@Override
public final void addLimit(int numberOfRows) {
addLimit(0, numberOfRows);
}
@Override
public final void addLimit(Param<Integer> numberOfRows) {
addLimit(0, numberOfRows);
}
@Override
public final void addLimit(int offset, int numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void addLimit(int offset, Param<Integer> numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void addLimit(Param<Integer> offset, int numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void addLimit(Param<Integer> offset, Param<Integer> numberOfRows) {
limit.setOffset(offset);
limit.setNumberOfRows(numberOfRows);
}
@Override
public final void setForUpdate(boolean forUpdate) {
this.forUpdate = forUpdate;
this.forShare = false;
}
@Override
public final void setForUpdateOf(Field<?>... fields) {
setForUpdateOf(Arrays.asList(fields));
}
@Override
public final void setForUpdateOf(Collection<? extends Field<?>> fields) {
setForUpdate(true);
forUpdateOf.clear();
forUpdateOfTables.clear();
forUpdateOf.addAll(fields);
}
@Override
public final void setForUpdateOf(Table<?>... tables) {
setForUpdate(true);
forUpdateOf.clear();
forUpdateOfTables.clear();
forUpdateOfTables.addAll(Arrays.asList(tables));
}
@Override
public final void setForUpdateWait(int seconds) {
setForUpdate(true);
forUpdateMode = ForUpdateMode.WAIT;
forUpdateWait = seconds;
}
@Override
public final void setForUpdateNoWait() {
setForUpdate(true);
forUpdateMode = ForUpdateMode.NOWAIT;
forUpdateWait = 0;
}
@Override
public final void setForUpdateSkipLocked() {
setForUpdate(true);
forUpdateMode = ForUpdateMode.SKIP_LOCKED;
forUpdateWait = 0;
}
@Override
public final void setForShare(boolean forShare) {
this.forUpdate = false;
this.forShare = forShare;
this.forUpdateOf.clear();
this.forUpdateOfTables.clear();
this.forUpdateMode = null;
this.forUpdateWait = 0;
}
@Override
public final List<Field<?>> getSelect() {
return getSelect1();
}
final FieldList getSelect0() {
return select;
}
final FieldList getSelect1() {
if (getSelect0().isEmpty()) {
FieldList result = new SelectFieldList();
// [#109] [#489]: SELECT * is only applied when at least one table
// from the table source is "unknown", i.e. not generated from a
// physical table. Otherwise, the fields are selected explicitly
if (knownTableSource()) {
for (TableLike<?> table : getFrom()) {
for (Field<?> field : table.asTable().getFields()) {
result.add(field);
}
}
}
// The default is SELECT 1, when projections and table sources are
// both empty
if (getFrom().isEmpty()) {
result.add(one());
}
return result;
}
return getSelect0();
}
private final boolean knownTableSource() {
for (Table<?> table : getFrom()) {
if (!knownTable(table)) {
return false;
}
}
return true;
}
private final boolean knownTable(Table<?> table) {
return table.getFields().size() > 0;
}
@SuppressWarnings("unchecked")
@Override
public final Class<? extends R> getRecordType() {
// Generated record classes only come into play, when the select is
// - on a single table
// - a select *
if (getFrom().size() == 1 && getSelect0().isEmpty()) {
return (Class<? extends R>) getFrom().get(0).asTable().getRecordType();
}
else {
return (Class<? extends R>) RecordImpl.class;
}
}
final TableList getFrom() {
return from;
}
final void setGrouping() {
grouping = true;
}
final QueryPartList<GroupField> getGroupBy() {
return groupBy;
}
final Limit getLimit() {
return limit;
}
final ConditionProviderImpl getWhere() {
return condition;
}
final ConditionProviderImpl getConnectBy() {
return connectBy;
}
final ConditionProviderImpl getConnectByStartWith() {
return connectByStartWith;
}
final ConditionProviderImpl getHaving() {
return having;
}
final SortFieldList getOrderBy() {
return orderBy;
}
final SortFieldList getNonEmptyOrderBy() {
if (getOrderBy().isEmpty()) {
SortFieldList result = new SortFieldList();
result.add(getSelect().get(0).asc());
return result;
}
return getOrderBy();
}
@Override
public final void addOrderBy(Collection<SortField<?>> fields) {
getOrderBy().addAll(fields);
}
@Override
public final void addOrderBy(Field<?>... fields) {
getOrderBy().addAll(fields);
}
@Override
public final void addOrderBy(SortField<?>... fields) {
addOrderBy(Arrays.asList(fields));
}
@Override
public final void addOrderBy(int... fieldIndexes) {
Field<?>[] fields = new Field[fieldIndexes.length];
for (int i = 0; i < fieldIndexes.length; i++) {
fields[i] = inline(fieldIndexes[i]);
}
addOrderBy(fields);
}
@Override
public final void setOrderBySiblings(boolean orderBySiblings) {
this.orderBySiblings = orderBySiblings;
}
@Override
public final void addConditions(Condition... conditions) {
condition.addConditions(conditions);
}
@Override
public final void addConditions(Collection<Condition> conditions) {
condition.addConditions(conditions);
}
@Override
public final void addConditions(Operator operator, Condition... conditions) {
condition.addConditions(operator, conditions);
}
@Override
public final void addConditions(Operator operator, Collection<Condition> conditions) {
condition.addConditions(operator, conditions);
}
final void setConnectByNoCycle(boolean connectByNoCycle) {
this.connectByNoCycle = connectByNoCycle;
}
final void setStartWith(Condition condition) {
connectByStartWith.addConditions(condition);
}
final void setHint(String hint) {
this.hint = hint;
}
@Override
final boolean isForUpdate() {
return forUpdate;
}
@Override
public final void addFrom(Collection<? extends TableLike<?>> f) {
for (TableLike<?> provider : f) {
getFrom().add(provider.asTable());
}
}
@Override
public final void addFrom(TableLike<?>... from) {
addFrom(Arrays.asList(from));
public final void addFrom(TableLike<?>... f) {
addFrom(Arrays.asList(f));
}
@Override
public final void addConnectBy(Condition condition) {
getConnectBy().addConditions(condition);
public final void addConnectBy(Condition c) {
getConnectBy().addConditions(c);
}
@Override
public final void addConnectByNoCycle(Condition condition) {
getConnectBy().addConditions(condition);
public final void addConnectByNoCycle(Condition c) {
getConnectBy().addConditions(c);
setConnectByNoCycle(true);
}
@Override
public final void setConnectByStartWith(Condition condition) {
setStartWith(condition);
public final void setConnectByStartWith(Condition c) {
setStartWith(c);
}
@Override
@ -346,7 +1136,32 @@ class SelectQueryImpl extends AbstractSubSelect<Record> implements SelectQuery {
}
@Override
public final void addHint(String hint) {
setHint(hint);
public final void addHint(String h) {
setHint(h);
}
// -------------------------------------------------------------------------
// Utility classes
// -------------------------------------------------------------------------
/**
* The lock mode for the <code>FOR UPDATE</code> clause, if set.
*/
private static enum ForUpdateMode {
WAIT("wait"),
NOWAIT("nowait"),
SKIP_LOCKED("skip locked"),
;
private final String sql;
private ForUpdateMode(String sql) {
this.sql = sql;
}
public final String toSQL() {
return sql;
}
}
}

View File

@ -1,399 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 static org.jooq.impl.Factory.condition;
import static org.jooq.impl.Factory.exists;
import static org.jooq.impl.Factory.notExists;
import java.util.Collection;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Field;
import org.jooq.Operator;
import org.jooq.Param;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.Select;
import org.jooq.SelectQuery;
import org.jooq.SimpleSelectConditionStep;
import org.jooq.SimpleSelectForUpdateOfStep;
import org.jooq.SimpleSelectOffsetStep;
import org.jooq.SimpleSelectQuery;
import org.jooq.SimpleSelectWhereStep;
import org.jooq.SortField;
import org.jooq.Table;
/**
* A wrapper for a {@link SelectQuery}
*
* @author Lukas Eder
*/
class SimpleSelectImpl<R extends Record> extends AbstractDelegatingSelect<R>
implements
// Cascading interface implementations for typed Select behaviour
SimpleSelectWhereStep<R>,
SimpleSelectConditionStep<R>,
SimpleSelectOffsetStep<R>,
SimpleSelectForUpdateOfStep<R> {
/**
* Generated UID
*/
private static final long serialVersionUID = -5425308887382166448L;
/**
* The limit that has been added in a limit(int).offset(int) construct
*/
private transient Integer limit;
private transient Param<Integer> limitParam;
SimpleSelectImpl(Configuration configuration) {
this(new SimpleSelectQueryImpl<R>(configuration));
}
SimpleSelectImpl(Configuration configuration, Table<R> table) {
this(configuration, table, false);
}
SimpleSelectImpl(Configuration configuration, Table<R> table, boolean distinct) {
this(new SimpleSelectQueryImpl<R>(configuration, table, distinct));
}
SimpleSelectImpl(Select<R> query) {
super(query);
}
@Override
public final SimpleSelectQuery<R> getQuery() {
return (SimpleSelectQuery<R>) getDelegate();
}
@Override
public final SimpleSelectImpl<R> where(Condition... conditions) {
getQuery().addConditions(conditions);
return this;
}
@Override
public final SimpleSelectImpl<R> where(Collection<Condition> conditions) {
getQuery().addConditions(conditions);
return this;
}
@Override
public final SimpleSelectImpl<R> where(String sql) {
return where(condition(sql));
}
@Override
public final SimpleSelectImpl<R> where(String sql, Object... bindings) {
return where(condition(sql, bindings));
}
@Override
public final SimpleSelectImpl<R> where(String sql, QueryPart... parts) {
return where(condition(sql, parts));
}
@Override
public final SimpleSelectImpl<R> whereExists(Select<?> select) {
return andExists(select);
}
@Override
public final SimpleSelectImpl<R> whereNotExists(Select<?> select) {
return andNotExists(select);
}
@Override
public final SimpleSelectImpl<R> and(Condition condition) {
getQuery().addConditions(condition);
return this;
}
@Override
public final SimpleSelectImpl<R> and(String sql) {
return and(condition(sql));
}
@Override
public final SimpleSelectImpl<R> and(String sql, Object... bindings) {
return and(condition(sql, bindings));
}
@Override
public final SimpleSelectImpl<R> and(String sql, QueryPart... parts) {
return and(condition(sql, parts));
}
@Override
public final SimpleSelectImpl<R> andNot(Condition condition) {
return and(condition.not());
}
@Override
public final SimpleSelectImpl<R> andExists(Select<?> select) {
return and(exists(select));
}
@Override
public final SimpleSelectImpl<R> andNotExists(Select<?> select) {
return and(notExists(select));
}
@Override
public final SimpleSelectImpl<R> or(Condition condition) {
getQuery().addConditions(Operator.OR, condition);
return this;
}
@Override
public final SimpleSelectImpl<R> or(String sql) {
return or(condition(sql));
}
@Override
public final SimpleSelectImpl<R> or(String sql, Object... bindings) {
return or(condition(sql, bindings));
}
@Override
public final SimpleSelectImpl<R> or(String sql, QueryPart... parts) {
return or(condition(sql, parts));
}
@Override
public final SimpleSelectImpl<R> orNot(Condition condition) {
return or(condition.not());
}
@Override
public final SimpleSelectImpl<R> orExists(Select<?> select) {
return or(exists(select));
}
@Override
public final SimpleSelectImpl<R> orNotExists(Select<?> select) {
return or(notExists(select));
}
@Override
public final SimpleSelectImpl<R> orderBy(Field<?>... fields) {
getQuery().addOrderBy(fields);
return this;
}
@Override
public final SimpleSelectImpl<R> orderBy(SortField<?>... fields) {
getQuery().addOrderBy(fields);
return this;
}
@Override
public final SimpleSelectImpl<R> orderBy(Collection<SortField<?>> fields) {
getQuery().addOrderBy(fields);
return this;
}
@Override
public final SimpleSelectImpl<R> orderBy(int... fieldIndexes) {
getQuery().addOrderBy(fieldIndexes);
return this;
}
@Override
public final SimpleSelectImpl<R> orderSiblingsBy(Field<?>... fields) {
getQuery().addOrderBy(fields);
getQuery().setOrderBySiblings(true);
return this;
}
@Override
public final SimpleSelectImpl<R> orderSiblingsBy(SortField<?>... fields) {
getQuery().addOrderBy(fields);
getQuery().setOrderBySiblings(true);
return this;
}
@Override
public final SimpleSelectImpl<R> orderSiblingsBy(Collection<SortField<?>> fields) {
getQuery().addOrderBy(fields);
getQuery().setOrderBySiblings(true);
return this;
}
@Override
public final SimpleSelectImpl<R> orderSiblingsBy(int... fieldIndexes) {
getQuery().addOrderBy(fieldIndexes);
getQuery().setOrderBySiblings(true);
return this;
}
@Override
public final SimpleSelectImpl<R> limit(int numberOfRows) {
this.limit = numberOfRows;
this.limitParam = null;
getQuery().addLimit(numberOfRows);
return this;
}
@Override
public final SimpleSelectImpl<R> limit(Param<Integer> numberOfRows) {
this.limit = null;
this.limitParam = numberOfRows;
getQuery().addLimit(numberOfRows);
return this;
}
@Override
public final SimpleSelectImpl<R> limit(int offset, int numberOfRows) {
getQuery().addLimit(offset, numberOfRows);
return this;
}
@Override
public final SimpleSelectImpl<R> limit(int offset, Param<Integer> numberOfRows) {
getQuery().addLimit(offset, numberOfRows);
return this;
}
@Override
public final SimpleSelectImpl<R> limit(Param<Integer> offset, int numberOfRows) {
getQuery().addLimit(offset, numberOfRows);
return this;
}
@Override
public final SimpleSelectImpl<R> limit(Param<Integer> offset, Param<Integer> numberOfRows) {
getQuery().addLimit(offset, numberOfRows);
return this;
}
@Override
public final SimpleSelectImpl<R> offset(int offset) {
if (limit != null) {
getQuery().addLimit(offset, limit);
}
else if (limitParam != null) {
getQuery().addLimit(offset, limitParam);
}
return this;
}
@Override
public final SimpleSelectImpl<R> offset(Param<Integer> offset) {
if (limit != null) {
getQuery().addLimit(offset, limit);
}
else if (limitParam != null) {
getQuery().addLimit(offset, limitParam);
}
return this;
}
@Override
public final SimpleSelectImpl<R> forUpdate() {
getQuery().setForUpdate(true);
return this;
}
@Override
public final SimpleSelectImpl<R> of(Field<?>... fields) {
getQuery().setForUpdateOf(fields);
return this;
}
@Override
public final SimpleSelectImpl<R> of(Collection<Field<?>> fields) {
getQuery().setForUpdateOf(fields);
return this;
}
@Override
public final SimpleSelectImpl<R> of(Table<?>... tables) {
getQuery().setForUpdateOf(tables);
return this;
}
@Override
public final SimpleSelectImpl<R> wait(int seconds) {
getQuery().setForUpdateWait(seconds);
return this;
}
@Override
public final SimpleSelectImpl<R> noWait() {
getQuery().setForUpdateNoWait();
return this;
}
@Override
public final SimpleSelectImpl<R> skipLocked() {
getQuery().setForUpdateSkipLocked();
return this;
}
@Override
public final SimpleSelectImpl<R> forShare() {
getQuery().setForShare(true);
return this;
}
@Override
public final Select<R> union(Select<? extends R> select) {
return new SimpleSelectImpl<R>(getQuery().union(select));
}
@Override
public final Select<R> unionAll(Select<? extends R> select) {
return new SimpleSelectImpl<R>(getQuery().unionAll(select));
}
@Override
public final Select<R> except(Select<? extends R> select) {
return new SimpleSelectImpl<R>(getQuery().except(select));
}
@Override
public final Select<R> intersect(Select<? extends R> select) {
return new SimpleSelectImpl<R>(getQuery().intersect(select));
}
}

View File

@ -1,63 +0,0 @@
/**
* Copyright (c) 2009-2012, 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 org.jooq.Configuration;
import org.jooq.Record;
import org.jooq.TableLike;
/**
* @author Lukas Eder
*/
class SimpleSelectQueryImpl<R extends Record> extends AbstractSubSelect<R> {
/**
* Generated UID
*/
private static final long serialVersionUID = 3200508777418108686L;
SimpleSelectQueryImpl(Configuration configuration) {
this(configuration, null);
}
SimpleSelectQueryImpl(Configuration configuration, TableLike<R> from) {
this(configuration, from, false);
}
SimpleSelectQueryImpl(Configuration configuration, TableLike<R> from, boolean distinct) {
super(configuration, from, distinct);
}
}

View File

@ -54,7 +54,6 @@ import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.SelectQuery;
import org.jooq.SimpleSelectQuery;
import org.jooq.StoreQuery;
import org.jooq.TableField;
import org.jooq.TableRecord;
@ -335,7 +334,7 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
@Override
public final void refresh(Field<?>... fields) {
SelectQuery select = create().selectQuery();
SelectQuery<?> select = create().selectQuery();
select.addSelect(fields);
select.addFrom(getTable());
Utils.addConditions(select, this, getMainKey().getFieldsArray());
@ -419,7 +418,7 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
* database record has been changed compared to this record.
*/
private final void checkIfChanged(TableField<R, ?>[] keys) {
SimpleSelectQuery<R> select = create().selectQuery(getTable());
SelectQuery<R> select = create().selectQuery(getTable());
Utils.addConditions(select, this, keys);
// [#1547] SQLite doesn't support FOR UPDATE. CUBRID and SQL Server

View File

@ -111,7 +111,6 @@ import org.jooq.RowN;
import org.jooq.Select;
import org.jooq.SelectFinalStep;
import org.jooq.SelectQuery;
import org.jooq.SimpleSelectQuery;
import org.jooq.Table;
import org.jooq.Truncate;
import org.jooq.UpdateQuery;
@ -1818,7 +1817,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testConditionalSelectQuery2() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addConditions(falseCondition());
assertEquals("select 1 from dual where 1 = 0", r_refI().render(q));
@ -1828,7 +1827,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testConditionalSelectQuery3() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addConditions(falseCondition());
q.addConditions(trueCondition());
@ -1839,7 +1838,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testConditionalSelectQuery4() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
Condition c1 = FIELD_ID1.equal(10);
Condition c2 = FIELD_ID1.equal(20);
@ -1865,7 +1864,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testConditionalSelectQuery5() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
Condition c1 = condition("\"TABLE1\".\"ID1\" = ?", "10");
Condition c2 = condition("\"TABLE2\".\"ID2\" = 20 or \"TABLE2\".\"ID2\" = ?", 30);
@ -1888,7 +1887,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testDistinctSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addSelect(FIELD_ID1, FIELD_ID2);
q.setDistinct(true);
@ -1902,7 +1901,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testProductSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addFrom(TABLE2);
@ -1917,7 +1916,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testJoinSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addJoin(TABLE2);
@ -1931,7 +1930,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testJoinOnConditionSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addJoin(TABLE2, FIELD_ID1.equal(FIELD_ID2));
@ -1952,7 +1951,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testJoinComplexSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addJoin(TABLE2,
@ -2009,7 +2008,7 @@ public class BasicTest extends AbstractTest {
Table<Table1Record> t1 = TABLE1.as("t1");
Table<Table1Record> t2 = TABLE1.as("t2");
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(t1);
q.addJoin(t2, t1.getField(FIELD_ID1).equal(t2.getField(FIELD_ID1)));
@ -2025,7 +2024,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testJoinTypeSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addJoin(TABLE2, LEFT_OUTER_JOIN, FIELD_ID1.equal(FIELD_ID2));
assertEquals("select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\", \"TABLE2\".\"ID2\", \"TABLE2\".\"NAME2\", \"TABLE2\".\"DATE2\" from \"TABLE1\" left outer join \"TABLE2\" on \"TABLE1\".\"ID1\" = \"TABLE2\".\"ID2\"", r_refI().render(q));
@ -2038,7 +2037,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testGroupSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addGroupBy();
@ -2107,7 +2106,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testOrderSelectQuery() throws Exception {
SimpleSelectQuery<Table1Record> q = create.selectQuery(TABLE1);
SelectQuery<Table1Record> q = create.selectQuery(TABLE1);
q.addOrderBy(FIELD_ID1);
assertEquals("select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\" order by \"TABLE1\".\"ID1\" asc", r_refI().render(q));
@ -2127,7 +2126,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testCompleteSelectQuery() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addJoin(TABLE2, FIELD_ID1.equal(FIELD_ID2));
q.addSelect(FIELD_ID1, FIELD_ID2);
@ -2198,8 +2197,8 @@ public class BasicTest extends AbstractTest {
}
private Select<?> createCombinedSelectQuery() {
SelectQuery q1 = create.selectQuery();
SelectQuery q2 = create.selectQuery();
SelectQuery<Record> q1 = create.selectQuery();
SelectQuery<Record> q2 = create.selectQuery();
q1.addFrom(TABLE1);
q2.addFrom(TABLE1);
@ -2219,9 +2218,9 @@ public class BasicTest extends AbstractTest {
@Test
public void testInnerSelect1() throws Exception {
SimpleSelectQuery<Table1Record> q1 = create.selectQuery(TABLE1);
SimpleSelectQuery<Table1Record> q2 = create.selectQuery(q1.asTable().as("inner_temp_table"));
SimpleSelectQuery<Table1Record> q3 = create.selectQuery(q2.asTable().as("outer_temp_table"));
SelectQuery<Table1Record> q1 = create.selectQuery(TABLE1);
SelectQuery<Table1Record> q2 = create.selectQuery(q1.asTable().as("inner_temp_table"));
SelectQuery<Table1Record> q3 = create.selectQuery(q2.asTable().as("outer_temp_table"));
assertEquals("select \"inner_temp_table\".\"ID1\", \"inner_temp_table\".\"NAME1\", \"inner_temp_table\".\"DATE1\" from (select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\") \"inner_temp_table\"", r_refI().render(q2));
assertEquals("select \"inner_temp_table\".\"ID1\", \"inner_temp_table\".\"NAME1\", \"inner_temp_table\".\"DATE1\" from (select \"TABLE1\".\"ID1\", \"TABLE1\".\"NAME1\", \"TABLE1\".\"DATE1\" from \"TABLE1\") \"inner_temp_table\"", r_ref().render(q2));
@ -2232,8 +2231,8 @@ public class BasicTest extends AbstractTest {
@Test
public void testInnerSelect2() throws Exception {
SelectQuery q1 = create.selectQuery();
SelectQuery q2 = create.selectQuery();
SelectQuery<?> q1 = create.selectQuery();
SelectQuery<?> q2 = create.selectQuery();
q1.addFrom(TABLE1);
q2.addFrom(TABLE2);
@ -2248,7 +2247,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testInnerSelect3() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addConditions(FIELD_ID1.in(select(FIELD_ID2).from(TABLE2)));
@ -2259,7 +2258,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testInnerSelect4() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addConditions(FIELD_ID1.equal(select(FIELD_ID2).from(TABLE2)));
@ -2270,7 +2269,7 @@ public class BasicTest extends AbstractTest {
@Test
public void testInnerSelect5() throws Exception {
SelectQuery q = create.selectQuery();
SelectQuery<?> q = create.selectQuery();
q.addFrom(TABLE1);
q.addConditions(FIELD_ID1.greaterThan(any(select(FIELD_ID2).from(TABLE2))));
@ -2281,8 +2280,8 @@ public class BasicTest extends AbstractTest {
@Test
public void testInnerSelect6() throws Exception {
SelectQuery q1 = create.selectQuery();
SelectQuery q2 = create.selectQuery();
SelectQuery<?> q1 = create.selectQuery();
SelectQuery<?> q2 = create.selectQuery();
q1.addFrom(TABLE1);
q2.addFrom(TABLE2);