From 1d98b77f3d9811d795d18a1db69b2ef135005bf8 Mon Sep 17 00:00:00 2001 From: Denis Zavedeev Date: Sat, 9 Nov 2019 23:34:26 +0300 Subject: [PATCH] DATAMONGO-765 - Support skip and limit parameters in GridFsTemplate and ReactiveGridFsTemplate. Leverage `skip` and `limit` methods exposed in `GridFSFindIterable` to support limiting and skipping results. In particular these changes allow the `find(Query)` method to correctly consider parameters of a page request. Original pull request: #806. --- .../data/mongodb/gridfs/GridFsTemplate.java | 11 ++++++-- .../gridfs/ReactiveGridFsTemplate.java | 8 +++++- .../GridFsTemplateIntegrationTests.java | 21 +++++++++++++++ .../gridfs/ReactiveGridFsTemplateTests.java | 27 +++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java index 98990d2d9..617e9164c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import org.bson.BsonObjectId; import org.bson.Document; import org.bson.types.ObjectId; import org.springframework.core.io.support.ResourcePatternResolver; @@ -51,6 +50,7 @@ import com.mongodb.client.gridfs.model.GridFSFile; * @author Mark Paluch * @author Hartmut Lang * @author Niklas Helge Hanft + * @author Denis Zavedeev */ public class GridFsTemplate extends GridFsOperationsSupport implements GridFsOperations, ResourcePatternResolver { @@ -166,7 +166,14 @@ public class GridFsTemplate extends GridFsOperationsSupport implements GridFsOpe Document queryObject = getMappedQuery(query.getQueryObject()); Document sortObject = getMappedQuery(query.getSortObject()); - return getGridFs().find(queryObject).sort(sortObject); + GridFSFindIterable iterable = getGridFs().find(queryObject).sort(sortObject); + if (query.getSkip() > 0) { + iterable = iterable.skip(Math.toIntExact(query.getSkip())); + } + if (query.getLimit() > 0) { + iterable = iterable.limit(query.getLimit()); + } + return iterable; } /* diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java index cec693763..dd7de6ce4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java @@ -50,6 +50,7 @@ import com.mongodb.reactivestreams.client.gridfs.GridFSFindPublisher; * * @author Mark Paluch * @author Nick Stolwijk + * @author Denis Zavedeev * @since 2.2 */ public class ReactiveGridFsTemplate extends GridFsOperationsSupport implements ReactiveGridFsOperations { @@ -261,7 +262,12 @@ public class ReactiveGridFsTemplate extends GridFsOperationsSupport implements R Document sortObject = getMappedQuery(query.getSortObject()); GridFSFindPublisher publisherToUse = getGridFs().find(queryObject).sort(sortObject); - + if (query.getLimit() > 0) { + publisherToUse = publisherToUse.limit(query.getLimit()); + } + if (query.getSkip() > 0) { + publisherToUse = publisherToUse.skip(Math.toIntExact(query.getSkip())); + } Integer cursorBatchSize = query.getMeta().getCursorBatchSize(); if (cursorBatchSize != null) { publisherToUse = publisherToUse.batchSize(cursorBatchSize); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java index 4ddef1418..4d8c98c42 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java @@ -20,6 +20,7 @@ import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; import static org.springframework.data.mongodb.gridfs.GridFsCriteria.*; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -27,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; +import java.util.stream.Stream; import org.bson.BsonObjectId; import org.bson.Document; @@ -38,6 +40,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; @@ -61,6 +64,7 @@ import com.mongodb.gridfs.GridFSInputFile; * @author Martin Baumgartner * @author Hartmut Lang * @author Mark Paluch + * @author Denis Zavedeev */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:gridfs/gridfs.xml") @@ -289,6 +293,23 @@ public class GridFsTemplateIntegrationTests { } } + @Test // DATAMONGO-2411 + public void considersSkipLimitWhenQueryingFiles() { + Stream.of( // + "a", "aa", "aaa", // + "b", "bb", "bb", // + "c", "cc", "ccc", // + "d", "dd", "ddd") // + .forEach(filename -> operations.store(new ByteArrayInputStream(new byte[0]), filename)); + + PageRequest pageRequest = PageRequest.of(2, 3, Direction.ASC, "filename"); + List filenames = operations.find(new Query().with(pageRequest)) // + .map(GridFSFile::getFilename) // + .into(new ArrayList<>()); + + assertThat(filenames).containsExactly("c", "cc", "ccc"); + } + class Metadata { String version; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java index 9914443c8..edaac16c5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java @@ -21,6 +21,7 @@ import static org.springframework.data.mongodb.core.query.Query.*; import static org.springframework.data.mongodb.gridfs.GridFsCriteria.*; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.io.IOException; @@ -36,10 +37,14 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.convert.MongoConverter; @@ -48,6 +53,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StreamUtils; +import com.mongodb.client.gridfs.model.GridFSFile; import com.mongodb.gridfs.GridFS; import com.mongodb.gridfs.GridFSInputFile; import com.mongodb.internal.HexUtils; @@ -60,6 +66,7 @@ import com.mongodb.reactivestreams.client.gridfs.helpers.AsyncStreamHelper; * @author Mark Paluch * @author Christoph Strobl * @author Nick Stolwijk + * @author Denis Zavedeev */ @RunWith(SpringRunner.class) @ContextConfiguration("classpath:gridfs/reactive-gridfs.xml") @@ -282,6 +289,26 @@ public class ReactiveGridFsTemplateTests { .verifyComplete(); } + @Test // DATAMONGO-2411 + public void considersSkipLimitWhenQueryingFiles() { + DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); + DataBuffer buffer = bufferFactory.allocateBuffer(0); + Flux.just( // + "a", "aa", "aaa", // + "b", "bb", "bbb", // + "c", "cc", "ccc", // + "d", "dd", "ddd") // + .flatMap(fileName -> operations.store(Mono.just(buffer), fileName)) // + .blockLast(); + + PageRequest pageRequest = PageRequest.of(2, 3, Sort.Direction.ASC, "filename"); + operations.find(new Query().with(pageRequest)) // + .map(GridFSFile::getFilename) // + .as(StepVerifier::create) // + .expectNext("c", "cc", "ccc") // + .verifyComplete(); + } + static class Metadata { String version; }