Skip to content

Commit

Permalink
Merge pull request #426 from eclipse/create-pagination-query
Browse files Browse the repository at this point in the history
Create Special Paramter converter
  • Loading branch information
otaviojava authored Aug 21, 2023
2 parents e6c12c9 + 85da543 commit c79da70
Show file tree
Hide file tree
Showing 7 changed files with 505 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
package org.eclipse.jnosql.mapping.column.query;


import jakarta.data.repository.Limit;
import jakarta.data.repository.Page;
import jakarta.data.repository.Pageable;
import jakarta.data.repository.Sort;
import org.eclipse.jnosql.communication.Params;
import org.eclipse.jnosql.communication.column.ColumnDeleteQuery;
import org.eclipse.jnosql.communication.column.ColumnDeleteQueryParams;
Expand All @@ -34,15 +32,11 @@
import org.eclipse.jnosql.mapping.Converters;
import org.eclipse.jnosql.mapping.NoSQLPage;
import org.eclipse.jnosql.mapping.column.JNoSQLColumnTemplate;
import org.eclipse.jnosql.mapping.column.MappingColumnQuery;
import org.eclipse.jnosql.mapping.metadata.EntityMetadata;
import org.eclipse.jnosql.mapping.repository.DynamicReturn;
import org.eclipse.jnosql.mapping.repository.SpecialParameters;
import org.eclipse.jnosql.mapping.util.ParamsBinder;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
Expand Down Expand Up @@ -145,44 +139,8 @@ protected Function<Pageable, Stream<T>> streamPagination(ColumnQuery query) {


protected ColumnQuery updateQueryDynamically(Object[] args, ColumnQuery query) {
SpecialParameters special = DynamicReturn.findSpecialParameters(args);

if (special.isEmpty()) {
return query;
}
Optional<Limit> limit = special.limit();
if (special.hasOnlySort()) {
List<Sort> sorts = new ArrayList<>();
sorts.addAll(query.sorts());
sorts.addAll(special.sorts());
long skip = limit.map(l -> l.startAt() - 1).orElse(query.skip());
long max = limit.map(Limit::maxResults).orElse((int) query.limit());
return new MappingColumnQuery(sorts, max,
skip,
query.condition().orElse(null),
query.name());
}

if (limit.isPresent()) {
long skip = limit.map(l -> l.startAt() - 1).orElse(query.skip());
long max = limit.map(Limit::maxResults).orElse((int) query.limit());
return new MappingColumnQuery(query.sorts(), max,
skip,
query.condition().orElse(null),
query.name());
}

return special.pageable().<ColumnQuery>map(p -> {
long size = p.size();
long skip = NoSQLPage.skip(p);
List<Sort> sorts = query.sorts();
if (!special.sorts().isEmpty()) {
sorts = new ArrayList<>(query.sorts());
sorts.addAll(special.sorts());
}
return new MappingColumnQuery(sorts, size, skip,
query.condition().orElse(null), query.name());
}).orElse(query);
DynamicQuery dynamicQuery = DynamicQuery.of(args, query);
return dynamicQuery.get();
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2023 Contributors to the Eclipse Foundation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*/
package org.eclipse.jnosql.mapping.column.query;

import jakarta.data.repository.Limit;
import jakarta.data.repository.Sort;
import org.eclipse.jnosql.communication.column.ColumnQuery;
import org.eclipse.jnosql.mapping.NoSQLPage;
import org.eclipse.jnosql.mapping.column.MappingColumnQuery;
import org.eclipse.jnosql.mapping.repository.DynamicReturn;
import org.eclipse.jnosql.mapping.repository.SpecialParameters;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

/**
* A query converter to update dynamic query to a {@link ColumnQuery}
*/
public class DynamicQuery implements Supplier<ColumnQuery> {

private final SpecialParameters special;
private final ColumnQuery query;

private DynamicQuery(SpecialParameters special, ColumnQuery query) {
this.special = special;
this.query = query;
}

@Override
public ColumnQuery get() {
if (special.isEmpty()) {
return query;
}
Optional<Limit> limit = special.limit();
if (special.hasOnlySort()) {
List<Sort> sorts = new ArrayList<>();
sorts.addAll(query.sorts());
sorts.addAll(special.sorts());
long skip = limit.map(l -> l.startAt() - 1).orElse(query.skip());
long max = limit.map(Limit::maxResults).orElse((int) query.limit());
return new MappingColumnQuery(sorts, max,
skip,
query.condition().orElse(null),
query.name());
}

if (limit.isPresent()) {
long skip = limit.map(l -> l.startAt() - 1).orElse(query.skip());
long max = limit.map(Limit::maxResults).orElse((int) query.limit());
List<Sort> sorts = query.sorts();
if (!special.sorts().isEmpty()) {
sorts = new ArrayList<>(query.sorts());
sorts.addAll(special.sorts());
}
return new MappingColumnQuery(sorts, max,
skip,
query.condition().orElse(null),
query.name());
}

return special.pageable().<ColumnQuery>map(p -> {
long size = p.size();
long skip = NoSQLPage.skip(p);
List<Sort> sorts = query.sorts();
if (!special.sorts().isEmpty()) {
sorts = new ArrayList<>(query.sorts());
sorts.addAll(special.sorts());
}
return new MappingColumnQuery(sorts, size, skip,
query.condition().orElse(null), query.name());
}).orElse(query);
}

/**
* Creates a {@link DynamicQuery} instance
* @param args the method parameters
* @param query the column query
* @return the {@link DynamicQuery} instance
* @throws NullPointerException when either args or query are null
*/
public static DynamicQuery of(Object[] args, ColumnQuery query) {
Objects.requireNonNull(args, "args is required");
Objects.requireNonNull(query, "query is required");
return new DynamicQuery(DynamicReturn.findSpecialParameters(args), query);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2023 Contributors to the Eclipse Foundation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*/
package org.eclipse.jnosql.mapping.column.query;

import jakarta.data.repository.Limit;
import jakarta.data.repository.Pageable;
import jakarta.data.repository.Sort;
import org.eclipse.jnosql.communication.column.ColumnQuery;
import org.eclipse.jnosql.mapping.repository.SpecialParameters;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;


class DynamicQueryTest {

@Mock
private SpecialParameters special;

@Mock
private ColumnQuery query;

@Mock
private Limit limit;

@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}

@Test
public void shouldCreateDynamicQuery() {
when(special.isEmpty()).thenReturn(true);
when(query.condition()).thenReturn(Optional.empty());
when(query.name()).thenReturn("sampleQuery");

DynamicQuery dynamicQuery = DynamicQuery.of(new Object[]{}, query);

assertEquals(query, dynamicQuery.get());
}

@Test
public void shouldCreateDynamicQueryWithSortsAndLimit() {
when(special.isEmpty()).thenReturn(false);
when(special.hasOnlySort()).thenReturn(true);
when(special.sorts()).thenReturn(List.of(mock(Sort.class)));
when(limit.startAt()).thenReturn(1L);
when(special.limit()).thenReturn(Optional.of(limit));
when(query.condition()).thenReturn(Optional.empty());
when(query.name()).thenReturn("sampleQuery");
when(query.sorts()).thenReturn(List.of(mock(Sort.class)));
when(query.skip()).thenReturn(0L);
when(query.limit()).thenReturn(10L);

DynamicQuery dynamicQuery = DynamicQuery.of(new Object[]{}, query);

assertEquals("sampleQuery", dynamicQuery.get().name());
assertEquals(0, dynamicQuery.get().skip());
assertEquals(10, dynamicQuery.get().limit());
assertEquals(1, dynamicQuery.get().sorts().size());
}

@Test
public void shouldCreateDynamicQueryWithLimit() {
when(special.isEmpty()).thenReturn(false);
when(special.hasOnlySort()).thenReturn(false);
when(limit.startAt()).thenReturn(1L);
when(special.limit()).thenReturn(Optional.of(limit));
when(query.condition()).thenReturn(Optional.empty());
when(query.name()).thenReturn("sampleQuery");
when(query.sorts()).thenReturn(List.of(mock(Sort.class)));
when(query.skip()).thenReturn(0L);
when(query.limit()).thenReturn(10L);

DynamicQuery dynamicQuery = DynamicQuery.of(new Object[]{}, query);

assertEquals("sampleQuery", dynamicQuery.get().name());
assertEquals(0, dynamicQuery.get().skip());
assertEquals(10, dynamicQuery.get().limit());
assertEquals(1, dynamicQuery.get().sorts().size());
}

@Test
public void shouldCreateDynamicQueryWithPageable() {
when(special.isEmpty()).thenReturn(false);
when(special.pageable()).thenReturn(Optional.of(mock(Pageable.class)));
when(special.sorts()).thenReturn(List.of(mock(Sort.class)));
when(query.condition()).thenReturn(Optional.empty());
when(query.name()).thenReturn("sampleQuery");
when(query.sorts()).thenReturn(List.of(mock(Sort.class)));
when(query.skip()).thenReturn(0L);
when(query.limit()).thenReturn(10L);

DynamicQuery dynamicQuery = DynamicQuery.of(new Object[]{}, query);

assertEquals("sampleQuery", dynamicQuery.get().name());
assertEquals(0, dynamicQuery.get().skip());
assertEquals(10, dynamicQuery.get().limit());
assertEquals(1, dynamicQuery.get().sorts().size());
}

@Test
public void shouldReturnWhenThereIsLimitAndSort(){
when(special.isEmpty()).thenReturn(false);
when(special.pageable()).thenReturn(Optional.of(mock(Pageable.class)));
when(query.condition()).thenReturn(Optional.empty());
when(query.name()).thenReturn("sampleQuery");
when(query.sorts()).thenReturn(Collections.emptyList());
when(query.skip()).thenReturn(0L);
when(query.limit()).thenReturn(10L);

DynamicQuery dynamicQuery = DynamicQuery.of(new Object[]{Sort.asc("name"), Limit.of(20)}
, query);

ColumnQuery columnQuery = dynamicQuery.get();
assertEquals("sampleQuery", columnQuery.name());
assertEquals(0, columnQuery.skip());
assertEquals(20, columnQuery.limit());
assertEquals(1, columnQuery.sorts().size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ static SpecialParameters of(Object[] parameters) {
sorts.add(sort);
} else if (parameter instanceof Limit limitInstance) {
limit = limitInstance;
} else if(parameter instanceof Iterable<?> iterable) {
for (Object value : iterable) {
if (value instanceof Sort sortValue) {
sorts.add(sortValue);
}
}
}
}
return new SpecialParameters(pageable, limit, sorts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -103,4 +104,14 @@ public void shouldReturnLimit() {
assertEquals(1, limit1.startAt());
assertEquals(10, limit1.maxResults());
}

@Test
public void shouldReturnIterableSort(){
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio",
List.of(Sort.asc("name"), Sort.desc("age"))});
assertFalse(parameters.isEmpty());
assertThat(parameters.sorts()).hasSize(2)
.containsExactly(Sort.asc("name"),
Sort.desc("age"));
}
}
Loading

0 comments on commit c79da70

Please sign in to comment.