diff --git a/ebean-api/src/main/java/io/ebean/QueryBuilder.java b/ebean-api/src/main/java/io/ebean/QueryBuilder.java index 1cc1d2d73..4a95544de 100644 --- a/ebean-api/src/main/java/io/ebean/QueryBuilder.java +++ b/ebean-api/src/main/java/io/ebean/QueryBuilder.java @@ -20,6 +20,7 @@ import java.util.stream.Stream; * @param The type of the builder * @param The entity bean type */ +//public interface QueryBuilder, T> extends QueryBuilderProjection { public interface QueryBuilder extends QueryBuilderProjection { /** @@ -27,6 +28,15 @@ public interface QueryBuilder extends QueryBuilderProjection { */ SELF alias(String alias); + /** + * Apply changes to the query using a function. + *

+ * This can be used to apply generic features to queries. + * + * @param apply The changes to apply to the query + */ + SELF also(Consumer> apply); + /** * Apply changes to the query conditional on the supplied predicate. *

diff --git a/ebean-api/src/main/java/io/ebean/QueryBuilderProjection.java b/ebean-api/src/main/java/io/ebean/QueryBuilderProjection.java index 54ff94657..fc84169a9 100644 --- a/ebean-api/src/main/java/io/ebean/QueryBuilderProjection.java +++ b/ebean-api/src/main/java/io/ebean/QueryBuilderProjection.java @@ -6,6 +6,7 @@ package io.ebean; * @param The builder type * @param The entity bean type */ +//public interface QueryBuilderProjection, T> { public interface QueryBuilderProjection { /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java index 9f3278d1d..1132cc9c8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java @@ -2,30 +2,7 @@ package io.ebeaninternal.server.query; import io.avaje.lang.NonNullApi; import io.avaje.lang.Nullable; -import io.ebean.CacheMode; -import io.ebean.CountDistinctOrder; -import io.ebean.Database; -import io.ebean.DtoQuery; -import io.ebean.Expression; -import io.ebean.ExpressionFactory; -import io.ebean.ExpressionList; -import io.ebean.FetchConfig; -import io.ebean.FetchGroup; -import io.ebean.FetchPath; -import io.ebean.FutureIds; -import io.ebean.FutureList; -import io.ebean.FutureRowCount; -import io.ebean.OrderBy; -import io.ebean.PagedList; -import io.ebean.PersistenceContextScope; -import io.ebean.ProfileLocation; -import io.ebean.Query; -import io.ebean.QueryIterator; -import io.ebean.QueryType; -import io.ebean.RawSql; -import io.ebean.Transaction; -import io.ebean.UpdateQuery; -import io.ebean.Version; +import io.ebean.*; import io.ebean.service.SpiFetchGroupQuery; import io.ebeaninternal.api.SpiQueryFetch; import io.ebeaninternal.server.querydefn.OrmQueryDetail; @@ -230,6 +207,11 @@ final class DefaultFetchGroupQuery implements SpiFetchGroupQuery, SpiQuery throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup"); } + @Override + public Query also(Consumer> apply) { + throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup"); + } + @Override public Query alsoIf(BooleanSupplier predicate, Consumer> apply) { throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 097c2fc33..91ac3f0b3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -293,6 +293,12 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { return this; } + @Override + public Query also(Consumer> apply) { + apply.accept(this); + return this; + } + @Override public Query alsoIf(BooleanSupplier predicate, Consumer> consumer) { if (predicate.getAsBoolean()) { diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/IQueryBean.java b/ebean-querybean/src/main/java/io/ebean/typequery/IQueryBean.java index 3fff7c44b..169bafc07 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/IQueryBean.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/IQueryBean.java @@ -44,6 +44,7 @@ import java.util.Collection; * @param the entity bean type (normal entity bean type e.g. Customer) * @param the specific query bean type (e.g. QCustomer) */ +//public interface IQueryBean> extends QueryBuilder { public interface IQueryBean extends QueryBuilder { /** diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java b/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java index 66c0215b7..3b98b0885 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java @@ -57,6 +57,7 @@ import java.util.stream.Stream; * @param the specific root query bean type (e.g. QCustomer) */ @NonNullApi +//public abstract class QueryBean> implements IQueryBean { public abstract class QueryBean implements IQueryBean { /** @@ -275,6 +276,13 @@ public abstract class QueryBean implements IQueryBean { return root; } + + @Override + public R also(Consumer> apply) { + apply.accept(this); + return root; + } + @Override public final R alsoIf(BooleanSupplier predicate, Consumer apply) { if (predicate.getAsBoolean()) { diff --git a/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java b/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java index a9a4dbf50..4c22257f9 100644 --- a/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java +++ b/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java @@ -1,9 +1,12 @@ package org.querytest; +import io.ebean.QueryBuilder; import org.example.domain.Customer; import org.example.domain.query.QCustomer; import org.junit.jupiter.api.Test; +import java.util.function.Consumer; + import static org.assertj.core.api.Assertions.assertThat; import static org.example.domain.query.QCustomer.Alias.name; @@ -11,6 +14,32 @@ class QueryAlsoIfTest { int dummy = 1; + @Test + void also() { + var myPager = new MyPager(10); + var q = new QCustomer() + .select(name) + .also(myPager) + .query(); + + q.findList(); + assertThat(q.getGeneratedSql()).contains("select /* QueryAlsoIfTest.also */ t0.id, t0.name from be_customer t0 limit 10"); + } + + static class MyPager implements Consumer> { + + final int maxRows; + + MyPager(int maxRows) { + this.maxRows = maxRows; + } + + @Override + public void accept(QueryBuilder queryBuilder) { + queryBuilder.setMaxRows(maxRows); + } + } + @Test void apply() { var q = new QCustomer() diff --git a/ebean-test/src/test/java/org/tests/query/TestQueryAlsoIf.java b/ebean-test/src/test/java/org/tests/query/TestQueryAlsoIf.java index 3ed66c800..08478d939 100644 --- a/ebean-test/src/test/java/org/tests/query/TestQueryAlsoIf.java +++ b/ebean-test/src/test/java/org/tests/query/TestQueryAlsoIf.java @@ -2,16 +2,49 @@ package org.tests.query; import io.ebean.DB; import io.ebean.Query; +import io.ebean.QueryBuilder; +import io.ebean.xtest.BaseTestCase; import org.junit.jupiter.api.Test; import org.tests.model.basic.Customer; import org.tests.model.basic.ResetBasicData; +import java.util.function.Consumer; + import static org.assertj.core.api.Assertions.assertThat; -class TestQueryAlsoIf { +class TestQueryAlsoIf extends BaseTestCase { int dummy = 1; + @Test + void also() { + ResetBasicData.reset(); + + MyPager myPager = new MyPager(10); + Query query = DB.find(Customer.class) + .select("name") + .also(myPager); + + query.findList(); + if (isLimitOffset()) { + assertThat(query.getGeneratedSql()).isEqualTo("select t0.id, t0.name from o_customer t0 limit 10"); + } + } + + static class MyPager implements Consumer> { + + final int maxRows; + + MyPager(int maxRows) { + this.maxRows = maxRows; + } + + @Override + public void accept(QueryBuilder queryBuilder) { + queryBuilder.setMaxRows(maxRows); + } + } + @Test void apply() { ResetBasicData.reset();