22
22
import org .springframework .data .couchbase .core .ExecutableFindByQueryOperation .ExecutableFindByQuery ;
23
23
import org .springframework .data .couchbase .core .ExecutableFindByQueryOperation .TerminatingFindByQuery ;
24
24
import org .springframework .data .couchbase .core .query .Query ;
25
+ import org .springframework .data .domain .PageImpl ;
25
26
import org .springframework .data .domain .Pageable ;
26
27
import org .springframework .data .domain .Slice ;
27
28
import org .springframework .data .domain .SliceImpl ;
28
29
import org .springframework .data .repository .query .QueryMethod ;
29
- import org .springframework .data .repository .support .PageableExecutionUtils ;
30
30
import org .springframework .util .Assert ;
31
31
32
32
/**
@@ -93,13 +93,13 @@ public Object execute(Query query, Class<?> type, Class<?> returnType, String co
93
93
*/
94
94
final class SlicedExecution implements CouchbaseQueryExecution {
95
95
96
- private final ExecutableFindByQuery <?> find ;
96
+ private final ExecutableFindByQuery <?> operation ;
97
97
private final Pageable pageable ;
98
98
99
- public SlicedExecution (ExecutableFindByQuery find , Pageable pageable ) {
100
- Assert .notNull (find , "Find must not be null!" );
99
+ public SlicedExecution (ExecutableFindByQuery operation , Pageable pageable ) {
100
+ Assert .notNull (operation , "Find must not be null!" );
101
101
Assert .notNull (pageable , "Pageable must not be null!" );
102
- this .find = find ;
102
+ this .operation = operation ;
103
103
this .pageable = pageable ;
104
104
}
105
105
@@ -110,12 +110,14 @@ public SlicedExecution(ExecutableFindByQuery find, Pageable pageable) {
110
110
@ Override
111
111
@ SuppressWarnings ({ "unchecked" , "rawtypes" })
112
112
public Object execute (Query query , Class <?> type , Class <?> returnType , String collection ) {
113
- int pageSize = pageable .getPageSize ();
114
- // Apply Pageable but tweak limit to peek into next page
115
- Query modifiedQuery = query .skip (pageable .getOffset ()).limit (pageSize + 1 );
116
- List result = find .as (returnType ).matching (modifiedQuery ).all ();
117
- boolean hasNext = result .size () > pageSize ;
118
- return new SliceImpl <Object >(hasNext ? result .subList (0 , pageSize ) : result , pageable , hasNext );
113
+ int overallLimit = 0 ; // query.getLimit();
114
+ TerminatingFindByQuery <?> matching = operation .as (returnType ).matching (query );
115
+ // Adjust limit if page would exceed the overall limit
116
+ if (overallLimit != 0 && pageable .getOffset () + pageable .getPageSize () > overallLimit ) {
117
+ query .limit ((int ) (overallLimit - pageable .getOffset ()));
118
+ }
119
+ List <?> results = matching .all ();
120
+ return new SliceImpl (results , pageable , results != null && !results .isEmpty ());
119
121
}
120
122
}
121
123
@@ -146,10 +148,13 @@ public Object execute(Query query, Class<?> type, Class<?> returnType, String co
146
148
if (overallLimit != 0 && pageable .getOffset () + pageable .getPageSize () > overallLimit ) {
147
149
query .limit ((int ) (overallLimit - pageable .getOffset ()));
148
150
}
149
- return PageableExecutionUtils .getPage (matching .all (), pageable , () -> {
150
- long count = operation .matching (query .skip (-1 ).limit (-1 ).withoutSort ()).count ();
151
- return overallLimit != 0 ? Math .min (count , overallLimit ) : count ;
152
- });
151
+
152
+ List <?> result = matching .all (); // this needs to be done before count, as count clears the skip and limit
153
+
154
+ long count = operation .matching (query .skip (-1 ).limit (-1 ).withoutSort ()).count ();
155
+ count = overallLimit != 0 ? Math .min (count , overallLimit ) : count ;
156
+
157
+ return new PageImpl (result , pageable , count );
153
158
}
154
159
}
155
160
0 commit comments