Skip to content

Commit

Permalink
feat(count): support count feature
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-thorel-of committed Jan 29, 2024
1 parent 44783cc commit 31a12f5
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.ouestfrance.querydsl.postgrest;

import fr.ouestfrance.querydsl.postgrest.model.CountItem;
import fr.ouestfrance.querydsl.postgrest.model.Page;
import fr.ouestfrance.querydsl.postgrest.model.PageImpl;
import fr.ouestfrance.querydsl.postgrest.model.Range;
Expand Down Expand Up @@ -85,6 +86,12 @@ public <T> List<T> delete(String resource, Map<String, List<String>> params, Map
.queryParams(queryParams).build().toString(), new HashMap<>()), HttpMethod.DELETE, new HttpEntity<>(null, toHeaders(headers)), listRef(clazz)).getBody();
}

@Override
public List<CountItem> count(String resource, Map<String, List<String>> map) {
return restTemplate.exchange(restTemplate.getUriTemplateHandler().expand(UriComponentsBuilder.fromPath(resource)
.queryParams(toMultiMap(map)).build().toString(), new HashMap<>()), HttpMethod.GET, new HttpEntity<>(null, new HttpHeaders()), listRef(CountItem.class)).getBody();
}

private static <T> ParameterizedTypeReference<List<T>> listRef(Class<T> clazz) {
return ParameterizedTypeReference.forType(TypeUtils.parameterize(List.class, clazz));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockserver.client.MockServerClient;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.junit.jupiter.MockServerSettings;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
Expand All @@ -27,7 +28,7 @@
import static org.junit.jupiter.api.Assertions.*;

@MockServerSettings(ports = 8007)
class PostgrestRepositoryTest {
class PostgrestRestTemplateRepositoryTest {

private PostgrestRepository<Post> repository;

Expand All @@ -52,6 +53,14 @@ void shouldSearchPosts(MockServerClient client) {
search.getData().stream().map(Object::getClass).forEach(x -> assertEquals(Post.class, x));
}

@Test
void shouldCountPosts(ClientAndServer client) {
client.when(HttpRequest.request().withPath("/posts").withQueryStringParameter("select", "count()"))
.respond(jsonFileResponse("count_response.json"));
long count = repository.count(new PostRequest());
assertEquals(300, count);
}

@Test
void shouldSearchPostsWithoutContentRange(MockServerClient client) {
client.when(HttpRequest.request().withPath("/posts").withQueryStringParameter("select", "*,authors(*)"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
{
"count": 300
}
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.ouestfrance.querydsl.postgrest;

import fr.ouestfrance.querydsl.postgrest.model.CountItem;
import fr.ouestfrance.querydsl.postgrest.model.Page;
import fr.ouestfrance.querydsl.postgrest.model.PageImpl;
import fr.ouestfrance.querydsl.postgrest.model.Range;
Expand Down Expand Up @@ -73,6 +74,19 @@ public <T> Page<T> search(String resource, Map<String, List<String>> params,
}).orElse(Page.empty());
}

@Override
public List<CountItem> count(String resource, Map<String, List<String>> params) {
ResponseEntity<List<CountItem>> response = webClient.get().uri(uriBuilder -> {
uriBuilder.path(resource);
uriBuilder.queryParams(toMultiMap(params));
return uriBuilder.build();
})
.retrieve()
.toEntity(listRef(CountItem.class))
.block();
return Optional.ofNullable(response).map(HttpEntity::getBody).orElse(List.of());
}

private static void safeAdd(Map<String, List<String>> headers, HttpHeaders httpHeaders) {
Optional.ofNullable(headers)
.map(PostgrestWebClient::toMultiMap).ifPresent(httpHeaders::addAll);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
import fr.ouestfrance.querydsl.postgrest.model.Pageable;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.junit.jupiter.MockServerExtension;
import org.mockserver.junit.jupiter.MockServerSettings;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
Expand All @@ -25,7 +23,7 @@
import static org.junit.jupiter.api.Assertions.*;

@MockServerSettings(ports = 8007)
class PostrgrestRepositoryTest {
class PostrgrestWebClientRepositoryTest {

private final PostgrestRepository<Post> repository = new PostRepository(PostgrestWebClient.of(WebClient.builder()
.baseUrl("http://localhost:8007/")
Expand All @@ -46,6 +44,14 @@ void shouldSearchPosts(ClientAndServer client) {
search.getData().stream().map(Object::getClass).forEach(x -> assertEquals(Post.class, x));
}

@Test
void shouldCountPosts(ClientAndServer client) {
client.when(HttpRequest.request().withPath("/posts").withQueryStringParameter("select", "count()"))
.respond(jsonFileResponse("count_response.json"));
long count = repository.count(new PostRequest());
assertEquals(300, count);
}

@Test
void shouldFindById(ClientAndServer client) {
client.when(HttpRequest.request().withPath("/posts")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
{
"count": 300
}
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.ouestfrance.querydsl.postgrest;

import fr.ouestfrance.querydsl.postgrest.model.CountItem;
import fr.ouestfrance.querydsl.postgrest.model.Page;

import java.util.List;
Expand Down Expand Up @@ -60,4 +61,12 @@ <T> Page<T> search(String resource, Map<String, List<String>> params,
*/
<T> List<T> delete(String resource, Map<String, List<String>> params, Map<String, List<String>> headers, Class<T> clazz);

/**
* Count data
*
* @param resource resource name
* @param map query params
* @return list of count items
*/
List<CountItem> count(String resource, Map<String, List<String>> map);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import fr.ouestfrance.querydsl.postgrest.annotations.Header;
import fr.ouestfrance.querydsl.postgrest.annotations.PostgrestConfiguration;
import fr.ouestfrance.querydsl.postgrest.annotations.Select;
import fr.ouestfrance.querydsl.postgrest.model.Filter;
import fr.ouestfrance.querydsl.postgrest.model.Page;
import fr.ouestfrance.querydsl.postgrest.model.PageImpl;
import fr.ouestfrance.querydsl.postgrest.model.Pageable;
import fr.ouestfrance.querydsl.postgrest.model.*;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.MissingConfigurationException;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.PostgrestRequestException;
import fr.ouestfrance.querydsl.postgrest.model.impl.CountFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.OrderFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.SelectFilter;
import fr.ouestfrance.querydsl.postgrest.services.ext.PostgrestQueryProcessorService;
Expand Down Expand Up @@ -84,6 +82,17 @@ public Page<T> search(Object criteria, Pageable pageable) {
return response;
}


@Override
public long count(Object criteria) {
List<Filter> queryParams = processorService.process(criteria);
queryParams.add(CountFilter.of());
List<CountItem> response = client.count(annotation.resource(), toMap(queryParams));

Check warning on line 90 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/PostgrestRepository.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/PostgrestRepository.java#L88-L90

Added lines #L88 - L90 were not covered by tests
// Retrieve result headers
return response.stream().findFirst().map(x -> x.get("count")).map(Long::valueOf).orElse(0L);

Check warning on line 92 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/PostgrestRepository.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/PostgrestRepository.java#L92

Added line #L92 was not covered by tests
}


@Override
public List<T> upsert(List<Object> values) {
return client.post(annotation.resource(), values, headerMap(Header.Method.UPSERT), clazz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ default Page<T> search(Object criteria) {
return search(criteria, Pageable.unPaged());
}


/**
* Count from criteria object
*
* @param criteria search criteria
* @return count result
*/
long count(Object criteria);

/**
* Search from criteria object with pagination
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import fr.ouestfrance.querydsl.postgrest.model.Filter;
import fr.ouestfrance.querydsl.postgrest.model.Sort;
import fr.ouestfrance.querydsl.postgrest.model.impl.CompositeFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.OrderFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.QueryFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.SelectFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.*;

import java.util.List;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -63,6 +60,19 @@ public void visit(SelectFilter filter) {
.collect(Collectors.joining(",")));
}


/**
* Transform a Select filter to Query
*
* @param filter select filter
*/
public void visit(CountFilter filter) {
builder.append("count()");

Check warning on line 70 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/builders/QueryFilterVisitor.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/builders/QueryFilterVisitor.java#L70

Added line #L70 was not covered by tests
if(filter.getGroupBy() != null) {
builder.append(COMA).append(filter.getGroupBy());

Check warning on line 72 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/builders/QueryFilterVisitor.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/builders/QueryFilterVisitor.java#L72

Added line #L72 was not covered by tests
}
}

Check warning on line 74 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/builders/QueryFilterVisitor.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/builders/QueryFilterVisitor.java#L74

Added line #L74 was not covered by tests

/**
* Transform a Composite filter to Query
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fr.ouestfrance.querydsl.postgrest.model;

import lombok.*;

import java.util.HashMap;

@Getter
@Setter
@NoArgsConstructor

Check warning on line 9 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/CountItem.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/CountItem.java#L9

Added line #L9 was not covered by tests
@EqualsAndHashCode(callSuper = false)
public class CountItem extends HashMap<String, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package fr.ouestfrance.querydsl.postgrest.model.impl;

import fr.ouestfrance.querydsl.postgrest.builders.FilterVisitor;
import fr.ouestfrance.querydsl.postgrest.builders.QueryFilterVisitor;
import fr.ouestfrance.querydsl.postgrest.model.Filter;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* Select filter allow to describe a selection
*/
@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)

Check warning on line 16 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L16

Added line #L16 was not covered by tests
public class CountFilter implements Filter, FilterVisitor {

/**
* Default query param key for selection
*/
private static final String KEY_PARAMETER = "select";
/**
* list of fields
*/
private String groupBy;

Check warning on line 26 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L26

Added line #L26 was not covered by tests


/**
* Create select filter from embedded resources
* @return select filter
*/
public static Filter groupBy(String field) {
return new CountFilter(field);

Check warning on line 34 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L34

Added line #L34 was not covered by tests
}

/**
* Create select filter from embedded resources
*
* @return select filter
*/
public static Filter of() {
return new CountFilter();

Check warning on line 43 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L43

Added line #L43 was not covered by tests
}

@Override
public void accept(QueryFilterVisitor visitor) {
visitor.visit(this);
}

Check warning on line 49 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L48-L49

Added lines #L48 - L49 were not covered by tests

@Override
public String getKey() {
return KEY_PARAMETER;

Check warning on line 53 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L53

Added line #L53 was not covered by tests
}


/**
* Attribute name
*/
@Getter
@RequiredArgsConstructor

Check warning on line 61 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L61

Added line #L61 was not covered by tests
public static class Attribute {
/**
* alias
*/
private final String alias;

Check warning on line 66 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L66

Added line #L66 was not covered by tests
/**
* value selected
*/
private final String value;

Check warning on line 70 in querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java

View check run for this annotation

Codecov / codecov/patch

querydsl-postgrest/src/main/java/fr/ouestfrance/querydsl/postgrest/model/impl/CountFilter.java#L70

Added line #L70 was not covered by tests

}
}

0 comments on commit 31a12f5

Please sign in to comment.