Skip to content

Commit

Permalink
Merge pull request #3311 from ebean-orm/feature/findSingleAttributeOr…
Browse files Browse the repository at this point in the history
…Empty

enh: Add findSingleAttributeOrEmpty() returning Optional
  • Loading branch information
rbygrave authored Jan 19, 2024
2 parents 2a62d41 + 4477038 commit 089dd8e
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 2 deletions.
19 changes: 19 additions & 0 deletions ebean-api/src/main/java/io/ebean/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,25 @@ enum LockWait {
@Nullable
<A> A findSingleAttribute();

/**
* Execute the query returning a single optional attribute value.
* <p>
* <h3>Example</h3>
* <pre>{@code
*
* Optional<String> maybeName =
* new QCustomer()
* .select(name)
* .id.eq(42)
* .status.eq(NEW)
* .findSingleAttributeOrEmpty();
*
* }</pre>
*
* @return an optional value for the selected property
*/
<A> Optional<A> findSingleAttributeOrEmpty();

/**
* Return true if this is countDistinct query.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ public <A> A findSingleAttribute() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}

@Override
public <A> Optional<A> findSingleAttributeOrEmpty() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}

@Override
public boolean isCountDistinct() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,7 @@ private void prepareForPaging() {
// add the rawSql statement - if any
if (orderByIsEmpty()) {
if (rawSql != null && rawSql.getSql() != null) {
order(rawSql.getSql().getOrderBy());
orderBy(rawSql.getSql().getOrderBy());
}
}
if (checkPagingOrderBy()) {
Expand Down Expand Up @@ -1517,7 +1517,6 @@ public final <K> Map<K, T> findMap() {
}

@Override
@SuppressWarnings("unchecked")
public final <A> List<A> findSingleAttributeList() {
return server.findSingleAttributeList(this);
}
Expand All @@ -1533,6 +1532,11 @@ public final <A> A findSingleAttribute() {
return !list.isEmpty() ? list.get(0) : null;
}

@Override
public final <A> Optional<A> findSingleAttributeOrEmpty() {
return Optional.ofNullable(findSingleAttribute());
}

@Override
public final T findOne() {
return server.findOne(this);
Expand Down
22 changes: 22 additions & 0 deletions ebean-querybean/src/main/java/io/ebean/typequery/TQRootBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -1867,6 +1867,28 @@ public <A> A findSingleAttribute() {
return query.findSingleAttribute();
}

/**
* Execute the query returning a single optional attribute value.
* <p>
* <h3>Example</h3>
* <pre>{@code
*
* Optional<String> maybeName =
* new QCustomer()
* .select(name)
* .id.eq(42)
* .status.eq(NEW)
* .findSingleAttributeOrEmpty();
*
* }</pre>
*
* @return an optional value for the selected property
*/
@Nullable
public <A> Optional<A> findSingleAttributeOrEmpty() {
return query.findSingleAttributeOrEmpty();
}

/**
* Execute the query processing the beans one at a time.
* <p>
Expand Down
26 changes: 26 additions & 0 deletions ebean-querybean/src/test/java/org/querytest/QCustomerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,32 @@ public void testSelectFormula() {
assertThat(maxDate).isNotNull();
}

@Test
public void findSingleAttributeOrEmpty() {

Customer cust = new Customer();
cust.setName("MaybeIExist yeah");
cust.setStatus(Customer.Status.GOOD);
cust.setRegistered(new Date());
cust.save();

Optional<String> customerName = new QCustomer()
.select(name)
.status.eq(Customer.Status.GOOD)
.name.startsWith("MaybeIExist")
.findSingleAttributeOrEmpty();

assertThat(customerName).isPresent();

Optional<String> customerName2 = new QCustomer()
.select(name)
.status.eq(Customer.Status.GOOD)
.name.eq("NahIDoNotExist")
.findSingleAttributeOrEmpty();

assertThat(customerName2).isEmpty();
}


@Test
public void testFetchByScalarValue() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.sql.Date;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -139,6 +140,32 @@ void findSingleAttribute() {
assertThat(name).isNotNull();
}

@Test
void findSingleAttributeOrEmpty() {
ResetBasicData.reset();

Query<Customer> query = DB.find(Customer.class)
.select("name")
.where().eq("name", "Rob").query();

Optional<String> name = query.findSingleAttributeOrEmpty();

assertThat(sqlOf(query)).contains("select t0.name from o_customer t0");
assertThat(name).isPresent().contains("Rob");
}

@Test
void findSingleAttributeOrEmpty_when_empty() {
ResetBasicData.reset();

Query<Customer> query = DB.find(Customer.class)
.select("name")
.where().eq("name", "I_Do_Not_ExistO!").query();

Optional<String> name = query.findSingleAttributeOrEmpty();
assertThat(name).isEmpty();
}

@Test
void findSingleAttributeList_with_join_column() {
ResetBasicData.reset();
Expand Down

0 comments on commit 089dd8e

Please sign in to comment.