Skip to content

Commit

Permalink
feat: create implementation to after cursor
Browse files Browse the repository at this point in the history
Signed-off-by: Otavio Santana <otaviopolianasantana@gmail.com>
  • Loading branch information
otaviojava committed Mar 30, 2024
1 parent c769c2e commit e26c583
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 34 deletions.
Expand Up @@ -19,6 +19,7 @@
import jakarta.data.page.PageRequest;
import jakarta.data.page.impl.CursoredPageRecord;
import org.eclipse.jnosql.communication.CommunicationException;
import org.eclipse.jnosql.communication.Condition;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -48,20 +49,51 @@ public CursoredPage<CommunicationEntity> cursor(SelectQuery query, PageRequest<?
}
}

private PageRequest.Cursor getCursor(List<Sort<?>> sorts, CommunicationEntity entity) {
List<Object> keys = new ArrayList<>(sorts.size());
for (Sort<?> sort : sorts) {
String name = sort.property();
Element element = entity.find(name)
.orElseThrow(() -> new CommunicationException("The sort name does not exist in the entity: " + name));
keys.add(element.get());
}
return PageRequest.Cursor.forKey(keys.toArray());
}

}, CURSOR_NEXT {
@SuppressWarnings("unchecked")
@Override
public CursoredPage<CommunicationEntity> cursor(SelectQuery query, PageRequest<?> pageRequest, DatabaseManager template) {
return null;


PageRequest.Cursor cursor = pageRequest.cursor().orElseThrow();
CriteriaCondition condition = getCriteriaCondition(query, cursor);

var select = new DefaultSelectQuery(pageRequest.size(), 0, query.name(), query.columns(), query.sorts(),
query.condition().map(c -> c.and(condition)).orElse(condition));

var entities = template.select(select).toList();
var last = entities.isEmpty() ? null : entities.get(entities.size() - 1);
if (last == null) {
return new CursoredPageRecord<>(entities, Collections.emptyList(), -1, (PageRequest<CommunicationEntity>) pageRequest,
null, null);
} else {
PageRequest.Cursor nextCursor = getCursor(query.sorts(), last);
PageRequest<CommunicationEntity> afterCursor = PageRequest.<CommunicationEntity>ofSize(pageRequest.size())
.afterCursor(nextCursor);

return new CursoredPageRecord<>(entities, List.of(cursor, nextCursor), -1, (PageRequest<CommunicationEntity>)
pageRequest, afterCursor, null);
}
}

static CriteriaCondition getCriteriaCondition(SelectQuery query, PageRequest.Cursor cursor) {
CriteriaCondition condition = null;
CriteriaCondition previousCondition = null;
List<Sort<?>> sorts = query.sorts();
for (int index = 0; index < sorts.size(); index++) {
Sort<?> sort = sorts.get(index);
Object key = cursor.get(index);
if(condition == null) {
condition = CriteriaCondition.gt(sort.property(), key);
previousCondition = CriteriaCondition.eq(sort.property(), key);
} else {
condition = condition.or(previousCondition.and(CriteriaCondition.gt(sort.property(), key)));
previousCondition = previousCondition.and(CriteriaCondition.eq(sort.property(), key));
}

}
return condition;
}
}, CURSOR_PREVIOUS {
@Override
Expand All @@ -82,4 +114,15 @@ public static CursorExecutor of(PageRequest.Mode value) {
};

}

private static PageRequest.Cursor getCursor(List<Sort<?>> sorts, CommunicationEntity entity) {
List<Object> keys = new ArrayList<>(sorts.size());
for (Sort<?> sort : sorts) {
String name = sort.property();
Element element = entity.find(name)
.orElseThrow(() -> new CommunicationException("The sort name does not exist in the entity: " + name));
keys.add(element.get());
}
return PageRequest.Cursor.forKey(keys.toArray());
}
}
Expand Up @@ -14,16 +14,21 @@
import jakarta.data.page.CursoredPage;
import jakarta.data.page.PageRequest;
import org.assertj.core.api.SoftAssertions;
import org.eclipse.jnosql.communication.Condition;
import org.eclipse.jnosql.communication.TypeReference;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;

import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
Expand All @@ -44,22 +49,13 @@ void shouldReturnPaginationOffSet() {
SelectQuery query = SelectQuery.select().from("person")
.orderBy("name").asc().build();

var entity = CommunicationEntity.of("name");
entity.add("name", "Ada");
entity.add("age", 10);
entity.add("id", UUID.randomUUID().toString());

var entity2 = CommunicationEntity.of("name");
entity2.add("name", "Poliana");
entity2.add("age", 35);
entity2.add("id", UUID.randomUUID().toString());

Mockito.when(databaseManager.select(Mockito.any(SelectQuery.class)))
.thenReturn(Stream.of(entity, entity2));
.thenReturn(stream());

CursoredPage<CommunicationEntity> entities = databaseManager.selectCursor(query,
PageRequest.ofSize(10));

SoftAssertions.assertSoftly(soft -> {
assertSoftly(soft -> {
PageRequest<CommunicationEntity> pageRequest = entities.pageRequest();
PageRequest<CommunicationEntity> nextedPageRequest = entities.nextPageRequest();
PageRequest.Cursor cursor = nextedPageRequest.cursor().orElseThrow();
Expand All @@ -82,22 +78,13 @@ void shouldReturnPaginationOffSet2() {
.orderBy("name").asc()
.orderBy("age").desc().build();

var entity = CommunicationEntity.of("name");
entity.add("name", "Ada");
entity.add("age", 10);
entity.add("id", UUID.randomUUID().toString());

var entity2 = CommunicationEntity.of("name");
entity2.add("name", "Poliana");
entity2.add("age", 35);
entity2.add("id", UUID.randomUUID().toString());

Mockito.when(databaseManager.select(Mockito.any(SelectQuery.class)))
.thenReturn(Stream.of(entity, entity2));
.thenReturn(stream());
CursoredPage<CommunicationEntity> entities = databaseManager.selectCursor(query,
PageRequest.ofSize(10));

SoftAssertions.assertSoftly(soft -> {
assertSoftly(soft -> {
PageRequest<CommunicationEntity> pageRequest = entities.pageRequest();
PageRequest<CommunicationEntity> nextedPageRequest = entities.nextPageRequest();
PageRequest.Cursor cursor = nextedPageRequest.cursor().orElseThrow();
Expand All @@ -115,4 +102,71 @@ void shouldReturnPaginationOffSet2() {
});
}

@Test
void shouldReturnPaginationAfterKeySingleElementWhenConditionIsNull() {
SelectQuery query = SelectQuery.select().from("person")
.orderBy("name").asc()
.orderBy("age").asc()
.orderBy("id").asc().build();

Mockito.when(databaseManager.select(Mockito.any(SelectQuery.class)))
.thenReturn(stream());

var id = UUID.randomUUID().toString();
CursoredPage<CommunicationEntity> entities = databaseManager.selectCursor(query,
PageRequest.ofSize(10).afterKey("Ada", 20, id));

ArgumentCaptor<SelectQuery> captor = ArgumentCaptor.forClass(SelectQuery.class);
Mockito.verify(databaseManager).select(captor.capture());
SelectQuery selectQuery = captor.getValue();

CriteriaCondition condition = selectQuery.condition().orElseThrow();

assertSoftly(soft -> {
soft.assertThat(condition.condition()).isEqualTo(Condition.OR);
List<CriteriaCondition> criteriaConditions = condition.element().get(new TypeReference<>() {
});

soft.assertThat(criteriaConditions).hasSize(3);
soft.assertThat(criteriaConditions.get(0)).isEqualTo(CriteriaCondition.gt("name", "Ada"));
soft.assertThat(criteriaConditions.get(1)).isEqualTo(
CriteriaCondition.eq("name", "Ada").and(CriteriaCondition.gt("age", 20)));
soft.assertThat(criteriaConditions.get(2)).isEqualTo(
CriteriaCondition.eq("name", "Ada").and(CriteriaCondition.eq("age", 20))
.and(CriteriaCondition.gt("id", id)));
});

assertSoftly(soft -> {
PageRequest<CommunicationEntity> pageRequest = entities.pageRequest();
PageRequest<CommunicationEntity> nextedPageRequest = entities.nextPageRequest();
PageRequest.Cursor cursor = nextedPageRequest.cursor().orElseThrow();

soft.assertThat(entities).hasSize(2);
soft.assertThat(pageRequest.mode())
.isEqualTo(PageRequest.Mode.CURSOR_NEXT);
soft.assertThat(nextedPageRequest.mode())
.isEqualTo(PageRequest.Mode.CURSOR_NEXT);
soft.assertThat(cursor.elements())
.hasSize(3);
soft.assertThat(cursor.get(0)).isEqualTo("Poliana");
soft.assertThat(cursor.get(1)).isEqualTo(35);
soft.assertThat(cursor.get(2)).isNotNull();

});
}

private Stream<CommunicationEntity> stream() {
var entity = CommunicationEntity.of("name");
entity.add("name", "Ada");
entity.add("age", 10);
entity.add("id", UUID.randomUUID().toString());

var entity2 = CommunicationEntity.of("name");
entity2.add("name", "Poliana");
entity2.add("age", 35);
entity2.add("id", UUID.randomUUID().toString());
return Stream.of(entity, entity2);
}


}

0 comments on commit e26c583

Please sign in to comment.