DATAGRAPH-1374 - Add support for sliced queries.

This commit is contained in:
Michael Simons
2020-09-11 15:21:23 +02:00
committed by GitHub
parent 86e314c4e3
commit 2d58a8d2fd
3 changed files with 37 additions and 11 deletions

View File

@@ -18,9 +18,12 @@ package org.springframework.data.neo4j.repository.query;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.LongSupplier;
import org.neo4j.driver.Record;
import org.neo4j.driver.types.TypeSystem;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.neo4j.core.Neo4jOperations;
import org.springframework.data.neo4j.core.PreparedQuery;
import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext;
@@ -42,7 +45,8 @@ abstract class AbstractNeo4jQuery extends Neo4jQuerySupport implements Repositor
protected final Neo4jOperations neo4jOperations;
AbstractNeo4jQuery(Neo4jOperations neo4jOperations, Neo4jMappingContext mappingContext, Neo4jQueryMethod queryMethod,
AbstractNeo4jQuery(Neo4jOperations neo4jOperations, Neo4jMappingContext mappingContext,
Neo4jQueryMethod queryMethod,
Neo4jQueryType queryType) {
super(mappingContext, queryMethod, queryType);
@@ -66,23 +70,29 @@ abstract class AbstractNeo4jQuery extends Neo4jQuerySupport implements Repositor
getInputProperties(resultProcessor), parameterAccessor, null, getMappingFunction(resultProcessor));
Object rawResult = new Neo4jQueryExecution.DefaultQueryExecution(neo4jOperations).execute(preparedQuery,
queryMethod.isCollectionLikeQuery() || queryMethod.isPageQuery());
queryMethod.isCollectionLikeQuery() || queryMethod.isPageQuery() || queryMethod.isSliceQuery());
Object processedResult = resultProcessor.processResult(rawResult, OptionalUnwrappingConverter.INSTANCE);
if (!queryMethod.isPageQuery()) {
return processedResult;
} else {
return PageableExecutionUtils.getPage((List<?>) processedResult, parameterAccessor.getPageable(), () -> {
LongSupplier totalSupplier = () -> {
PreparedQuery<Long> countQuery = prepareQuery(Long.class, Collections.emptyList(), parameterAccessor,
Neo4jQueryType.COUNT, null);
return neo4jOperations.toExecutableQuery(countQuery).getRequiredSingleResult();
});
PreparedQuery<Long> countQuery = prepareQuery(Long.class, Collections.emptyList(), parameterAccessor,
Neo4jQueryType.COUNT, null);
return neo4jOperations.toExecutableQuery(countQuery).getRequiredSingleResult();
};
if (queryMethod.isPageQuery()) {
return PageableExecutionUtils.getPage((List<?>) processedResult, parameterAccessor.getPageable(), totalSupplier);
} else if (queryMethod.isSliceQuery()) {
long total = totalSupplier.getAsLong();
Pageable pageable = parameterAccessor.getPageable();
return new SliceImpl<>((List<?>) processedResult, pageable, pageable.getOffset() + pageable.getPageSize() < total);
} else {
return processedResult;
}
}
protected abstract <T extends Object> PreparedQuery<T> prepareQuery(Class<T> returnedType,
List<String> includedProperties, Neo4jParameterAccessor parameterAccessor, @Nullable Neo4jQueryType queryType,
List<String> includedProperties, Neo4jParameterAccessor parameterAccessor,
@Nullable Neo4jQueryType queryType,
@Nullable BiFunction<TypeSystem, Record, ?> mappingFunction);
}

View File

@@ -67,6 +67,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Range.Bound;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle;
@@ -537,6 +538,18 @@ class RepositoryIT {
List<PersonWithAllConstructor> persons = repository.findAllByNameOrName(TEST_PERSON1_NAME, TEST_PERSON2_NAME);
assertThat(persons).containsExactlyInAnyOrder(person1, person2);
}
@Test // DATAGRAPH-1374
void findSliceShouldWork(@Autowired PersonRepository repository) {
Slice<PersonWithAllConstructor> slice = repository.findSliceByNameOrName(TEST_PERSON1_NAME, TEST_PERSON2_NAME, PageRequest.of(0, 1, Sort.by("name").descending()));
assertThat(slice.get()).hasSize(1).extracting("name").containsExactly(TEST_PERSON2_NAME);
assertThat(slice.hasNext()).isTrue();
slice = repository.findSliceByNameOrName(TEST_PERSON1_NAME, TEST_PERSON2_NAME, slice.nextPageable());
assertThat(slice.get()).hasSize(1).extracting("name").containsExactly(TEST_PERSON1_NAME);
assertThat(slice.hasNext()).isFalse();
}
}
@Nested

View File

@@ -25,6 +25,7 @@ import org.neo4j.driver.types.Point;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Slice;
import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
@@ -109,6 +110,8 @@ public interface PersonRepository extends Neo4jRepository<PersonWithAllConstruct
Page<PersonWithAllConstructor> findAllByNameOrName(String aName, String anotherName, Pageable pageable);
Slice<PersonWithAllConstructor> findSliceByNameOrName(String aName, String anotherName, Pageable pageable);
Long countAllByNameOrName(String aName, String anotherName);
Optional<PersonWithAllConstructor> findOneByNameAndFirstNameAllIgnoreCase(String name, String firstName);