Skip to content

Commit

Permalink
Improved queryOne performance in DomainEventQueries
Browse files Browse the repository at this point in the history
  • Loading branch information
johanhaleby committed Sep 27, 2024
1 parent d1a7d6d commit f21ceaf
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 12 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### Changelog next version
* Added better debug logging
* Improved queryOne performance in DomainEventQueries

### 0.19.3 (2024-09-11)
* Added two kotlin extension functions to DomainEventQueries:
1. `queryForList` that just takes a filter and a "SortBy"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public DomainEventQueries(EventStoreQueries eventStoreQueries, CloudEventConvert
* @return All cloud events matching the specified filter, skip, limit and sort by <code>sortBy</code>.
*/
public <E extends T> E queryOne(Filter filter) {
return this.<E>toDomainEvents(eventStoreQueries.query(filter)).findFirst().orElse(null);
return this.<E>toDomainEvents(eventStoreQueries.query(filter, 0, 1)).findFirst().orElse(null);
}

/**
Expand All @@ -65,7 +65,7 @@ public <E extends T> E queryOne(Filter filter) {
* @return The cloud event matching the specified type or {@code null}
*/
public <E extends T> E queryOne(Class<E> type) {
return query(type).findFirst().orElse(null);
return query(type, 0, 1).findFirst().orElse(null);
}

/**
Expand All @@ -74,7 +74,7 @@ public <E extends T> E queryOne(Class<E> type) {
* @return The cloud event matching the specified type or {@code null}
*/
public <E extends T> E queryOne(Class<E> type, SortBy sortBy) {
return queryOne(type, 0, Integer.MAX_VALUE, sortBy);
return queryOne(type, 0, 1, sortBy);
}

/**
Expand All @@ -93,7 +93,8 @@ public <E extends T> E queryOne(Class<E> type, int skip, int limit) {
*/
public <E extends T> E queryOne(Class<E> type, int skip, int limit, SortBy sortBy) {
Objects.requireNonNull(type, "type cannot be null");
return (E) query(Filter.type(cloudEventConverter.getCloudEventType(type)), skip, limit, sortBy).findFirst().orElse(null);
CloudEvent cloudEvent = eventStoreQueries.query(Filter.type(cloudEventConverter.getCloudEventType(type)), skip, limit, sortBy).findFirst().orElse(null);
return toDomainEvent(cloudEvent);
}

/**
Expand Down Expand Up @@ -312,6 +313,13 @@ private <E extends T> Stream<E> toDomainEvents(Stream<CloudEvent> stream) {
return stream.map(cloudEventConverter::toDomainEvent).map(t -> (E) t);
}

private <E extends T> E toDomainEvent(CloudEvent cloudEvent) {
if (cloudEvent == null) {
return null;
}
return (E) cloudEventConverter.toDomainEvent(cloudEvent);
}

@Nullable
private Filter createFilterFrom(Collection<Class<? extends T>> types) {
return (types == null ? Stream.<Class<? extends T>>empty() : types.stream())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;
import org.occurrent.application.converter.CloudEventConverter;
import org.occurrent.application.converter.jackson.JacksonCloudEventConverter;
Expand Down Expand Up @@ -46,6 +48,7 @@
import static org.occurrent.eventstore.api.SortBy.SortDirection.DESCENDING;
import static org.occurrent.filter.Filter.type;

@DisplayNameGeneration(ReplaceUnderscores.class)
public class DomainEventQueriesTest {

private ApplicationService<DomainEvent> applicationService;
Expand Down Expand Up @@ -83,7 +86,7 @@ void all() {
}

@Test
void queryWithAllFilter() {
void query_with_all_filter() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -106,7 +109,7 @@ void queryWithAllFilter() {
}

@Test
void queryBasedOnType() {
void query_based_on_type() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -127,8 +130,9 @@ void queryBasedOnType() {
);
}


@Test
void queryOne() {
void query_one() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -147,7 +151,33 @@ void queryOne() {
}

@Test
void queryBasedOnClassType() {
void query_one_when_multiple_events_match_then_the_first_is_returned() {
// Given
LocalDateTime time = LocalDateTime.now();

applicationService.execute("stream1", toStreamCommand(
composeCommands(
partial(Name::defineName, "eventId1", time, "name", "Some Doe"),
partial(Name::changeName, "eventId2", time, "name", "Jane Doe")
)
));

applicationService.execute("stream2", toStreamCommand(
composeCommands(
partial(Name::defineName, "eventId3", time, "name", "Another Doe"),
partial(Name::changeName, "eventId4", time, "name", "Jane2 Doe")
)
));

// When
NameDefined event = domainEventQueries.queryOne(type(NameDefined.class.getName()));

// Then
assertThat(event).isEqualTo(new NameDefined("eventId1", time, "name", "Some Doe"));
}

@Test
void query_based_on_class_type() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -169,7 +199,7 @@ void queryBasedOnClassType() {
}

@Test
void queryOneBasedOnClassType() {
void query_one_based_on_class_type() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -189,7 +219,7 @@ void queryOneBasedOnClassType() {
}

@Test
void queryBasedOnVarArgClassType() {
void query_based_on_var_arg_class_type() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -212,7 +242,7 @@ void queryBasedOnVarArgClassType() {
}

@Test
void queryBasedOCollectionClassType() {
void query_based_o_collection_class_type() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand All @@ -235,7 +265,7 @@ void queryBasedOCollectionClassType() {
}

@Test
void queryOneBasedOnClassTypeAndSortBy() {
void query_one_based_on_class_type_and_sort_by() {
// Given
LocalDateTime time = LocalDateTime.now();

Expand Down

0 comments on commit f21ceaf

Please sign in to comment.