diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/AggregateWindowFunctionTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/AggregateWindowFunctionTests.java index 9d14b43d32..5ccdcdfec2 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/AggregateWindowFunctionTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/AggregateWindowFunctionTests.java @@ -59,6 +59,7 @@ import static org.jooq.impl.Factory.cumeDist; import static org.jooq.impl.Factory.denseRank; import static org.jooq.impl.Factory.firstValue; import static org.jooq.impl.Factory.groupConcat; +import static org.jooq.impl.Factory.inline; import static org.jooq.impl.Factory.lag; import static org.jooq.impl.Factory.lead; import static org.jooq.impl.Factory.listAgg; @@ -68,6 +69,7 @@ import static org.jooq.impl.Factory.median; import static org.jooq.impl.Factory.min; import static org.jooq.impl.Factory.minDistinct; import static org.jooq.impl.Factory.ntile; +import static org.jooq.impl.Factory.one; import static org.jooq.impl.Factory.percentRank; import static org.jooq.impl.Factory.rank; import static org.jooq.impl.Factory.regrAvgX; @@ -80,6 +82,9 @@ import static org.jooq.impl.Factory.regrSXY; import static org.jooq.impl.Factory.regrSYY; import static org.jooq.impl.Factory.regrSlope; import static org.jooq.impl.Factory.rowNumber; +import static org.jooq.impl.Factory.select; +import static org.jooq.impl.Factory.selectDistinct; +import static org.jooq.impl.Factory.selectFrom; import static org.jooq.impl.Factory.stddevPop; import static org.jooq.impl.Factory.stddevSamp; import static org.jooq.impl.Factory.sum; @@ -280,6 +285,23 @@ extends BaseTest extends ResultQuery, TableLike, * All fields selected in this query */ List> getSelect(); + + /** + * Execute this query in the context of its attached executor and return + * a COUNT(*) value. + *

+ * This wraps a pre-existing SELECT query in another one to + * calculate the COUNT(*) value, without modifying the original + * SELECT. An example:

+     * -- Original query:
+     * SELECT id, title FROM book WHERE title LIKE '%a%'
+     *
+     * -- Wrapped query:
+     * SELECT count(*) FROM (
+     *   SELECT id, title FROM book WHERE title LIKE '%a%'
+     * )
+     * 
This is particularly useful for those databases that do not + * support the COUNT(*) OVER() window function to calculate + * total results in paged queries. + * + * @return The COUNT(*) result + * @throws DataAccessException if something went wrong executing the query + */ + int fetchCount() throws DataAccessException; } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractSelect.java b/jOOQ/src/main/java/org/jooq/impl/AbstractSelect.java index f92af27cf2..a6c66c47dc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractSelect.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractSelect.java @@ -48,6 +48,7 @@ import org.jooq.Result; import org.jooq.Row; import org.jooq.Select; import org.jooq.Table; +import org.jooq.exception.DataAccessException; /** * A common base class for all SELECT statements. @@ -62,6 +63,11 @@ abstract class AbstractSelect extends AbstractResultQuery i super(configuration); } + @Override + public final int fetchCount() throws DataAccessException { + return new Executor(getConfiguration()).fetchCount(this); + } + @Override public final Select union(Select select) { return new Union(getConfiguration(), this, select, CombineOperator.UNION); diff --git a/jOOQ/src/main/java/org/jooq/impl/Executor.java b/jOOQ/src/main/java/org/jooq/impl/Executor.java index 685291ca72..98f928dee4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Executor.java +++ b/jOOQ/src/main/java/org/jooq/impl/Executor.java @@ -5328,6 +5328,32 @@ public class Executor implements Configuration { } } + /** + * Execute a {@link Select} query in the context of this executor and return + * a COUNT(*) value. + *

+ * This wraps a pre-existing SELECT query in another one to + * calculate the COUNT(*) value, without modifying the original + * SELECT. An example:

+     * -- Original query:
+     * SELECT id, title FROM book WHERE title LIKE '%a%'
+     *
+     * -- Wrapped query:
+     * SELECT count(*) FROM (
+     *   SELECT id, title FROM book WHERE title LIKE '%a%'
+     * )
+     * 
This is particularly useful for those databases that do not + * support the COUNT(*) OVER() window function to calculate + * total results in paged queries. + * + * @param query The wrapped query + * @return The COUNT(*) result + * @throws DataAccessException if something went wrong executing the query + */ + public final int fetchCount(Select query) throws DataAccessException { + return selectCount().from(query).fetchOne(0, int.class); + } + /** * Execute a {@link Query} in the context of this executor. * diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java index 9ec296606a..0e6d569a26 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java @@ -153,6 +153,11 @@ class SelectImpl extends AbstractDelegatingQuery> im return (SelectQuery) getDelegate(); } + @Override + public final int fetchCount() { + return getDelegate().fetchCount(); + } + /** * This method must be able to return both incompatible types * SelectSelectStep<Record> and SelectSelectStep<R>