diff --git a/ebean-api/src/main/java/io/ebean/QueryBuilder.java b/ebean-api/src/main/java/io/ebean/QueryBuilder.java index c50f21e59d..85bd8e05e6 100644 --- a/ebean-api/src/main/java/io/ebean/QueryBuilder.java +++ b/ebean-api/src/main/java/io/ebean/QueryBuilder.java @@ -44,6 +44,16 @@ public interface QueryBuilder, T> extends Que */ SELF alsoIf(BooleanSupplier predicate, Consumer apply); + /** + * Apply changes to the query when the supplied value is non-null. + *

+ * Typically, the changes are extra predicates etc. + * + * @param value The value which when non-null the changes are applied + * @param apply The changes to apply to the query + */ + SELF alsoIfPresent(@Nullable Object value, Consumer apply); + /** * Perform an 'As of' query using history tables to return the object graph * as of a time in the past. 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 01c60aabc9..1078fdf1fe 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 @@ -219,6 +219,11 @@ public Query alsoIf(BooleanSupplier predicate, Consumer> apply) { throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup"); } + @Override + public Query alsoIfPresent(@Nullable Object value, Consumer> apply) { + throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup"); + } + @Override public Query usingTransaction(Transaction transaction) { 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 11601a5c6a..687bb72d82 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 @@ -307,6 +307,14 @@ public Query alsoIf(BooleanSupplier predicate, Consumer> consumer) { return this; } + @Override + public Query alsoIfPresent(@Nullable Object value, Consumer> consumer) { + if (value != null) { + consumer.accept(this); + } + return this; + } + @Override public final void addSoftDeletePredicate(String softDeletePredicate) { if (softDeletePredicates == null) { 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 536979f828..2f15c5a98b 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java @@ -273,6 +273,14 @@ public final R alsoIf(BooleanSupplier predicate, Consumer apply) { return root; } + @Override + public final R alsoIfPresent(@Nullable Object value, Consumer apply) { + if (value != null) { + apply.accept(root); + } + return root; + } + @Override public final R asOf(Timestamp asOf) { query.asOf(asOf); diff --git a/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java b/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java index 33702725b1..3888f103a3 100644 --- a/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java +++ b/ebean-querybean/src/test/java/org/querytest/QueryAlsoIfTest.java @@ -36,7 +36,7 @@ void apply() { .query(); q.findList(); - assertThat(q.getGeneratedSql()).isEqualTo("select /* QueryAlsoIfTest.apply */ t0.id, t0.name from be_customer t0 where t0.name is not null and t0.status = ?"); + assertThat(q.getGeneratedSql()).contains("from be_customer t0 where t0.name is not null and t0.status = ?"); } @Test @@ -48,7 +48,33 @@ void notApply() { .query(); q.findList(); - assertThat(q.getGeneratedSql()).isEqualTo("select /* QueryAlsoIfTest.notApply */ t0.id, t0.name from be_customer t0 where t0.name is not null"); + assertThat(q.getGeneratedSql()).contains("from be_customer t0 where t0.name is not null"); + } + + @Test + void applyIfPresent() { + Object value = "yes"; + var q = new QCustomer() + .select(name) + .name.isNotNull() + .alsoIfPresent(value, query -> query.status.equalTo(Customer.Status.GOOD)) + .query(); + + q.findList(); + assertThat(q.getGeneratedSql()).isEqualTo("select /* QueryAlsoIfTest.applyIfPresent */ t0.id, t0.name from be_customer t0 where t0.name is not null and t0.status = ?"); + } + + @Test + void notApplyIfPresent() { + Object value = null; + var q = new QCustomer() + .select(name) + .name.isNotNull() + .alsoIfPresent(value, query -> query.status.equalTo(Customer.Status.GOOD)) + .query(); + + q.findList(); + assertThat(q.getGeneratedSql()).isEqualTo("select /* QueryAlsoIfTest.notApplyIfPresent */ t0.id, t0.name from be_customer t0 where t0.name is not null"); } @Test 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 3ed66c8003..d1e0e6ec37 100644 --- a/ebean-test/src/test/java/org/tests/query/TestQueryAlsoIf.java +++ b/ebean-test/src/test/java/org/tests/query/TestQueryAlsoIf.java @@ -33,4 +33,28 @@ void notApply() { query.findList(); assertThat(query.getGeneratedSql()).isEqualTo("select t0.id, t0.name from o_customer t0"); } + + @Test + void applyIfPresent() { + ResetBasicData.reset(); + Object value = "yes"; + Query query = DB.find(Customer.class) + .select("name") + .alsoIfPresent(value, qy -> qy.where().isNotNull("name")); + + query.findList(); + assertThat(query.getGeneratedSql()).isEqualTo("select t0.id, t0.name from o_customer t0 where t0.name is not null"); + } + + @Test + void notApplyIfPresent() { + ResetBasicData.reset(); + Object value = null; + Query query = DB.find(Customer.class) + .select("name") + .alsoIfPresent(value, qy -> qy.where().isNotNull("name")); + + query.findList(); + assertThat(query.getGeneratedSql()).isEqualTo("select t0.id, t0.name from o_customer t0"); + } }