[#2060] Remove redundant SimpleSelectXXX API
- Removed API elements - Clean up SELECT type hierarchy
This commit is contained in:
parent
caaafad41c
commit
01dfb38317
@ -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);
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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"));
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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"));
|
||||
|
||||
@ -9190,6 +9190,7 @@ for (Record record : create().select(
|
||||
<li>Result<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>
|
||||
|
||||
@ -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();
|
||||
|
||||
}
|
||||
|
||||
@ -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 })
|
||||
|
||||
@ -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 })
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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]) {
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user