Skip to content

Commit e06dbfa

Browse files
DATAMONGO-1480 - Polishing.
Opened up the Meta attributes to now allowing usage of more than one cursor option via dedicated enum. new Query().noCursorTimeout(); and interface PersonRepository extends CrudRepository<Person, String> { @meta(flags = {CursorOptions.NO_TIMEOUT}) Iterable<Person> findBy(); }
1 parent 15119c8 commit e06dbfa

File tree

7 files changed

+116
-25
lines changed

7 files changed

+116
-25
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
9494
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
9595
import org.springframework.data.mongodb.core.query.Criteria;
96+
import org.springframework.data.mongodb.core.query.Meta;
9697
import org.springframework.data.mongodb.core.query.NearQuery;
9798
import org.springframework.data.mongodb.core.query.Query;
9899
import org.springframework.data.mongodb.core.query.Update;
@@ -2372,8 +2373,24 @@ public DBCursor prepare(DBCursor cursor) {
23722373
cursorToUse = cursorToUse.addSpecial(entry.getKey(), entry.getValue());
23732374
}
23742375

2375-
if (query.getMeta().isNoCursorTimeout() != null && query.getMeta().isNoCursorTimeout().booleanValue()) {
2376-
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
2376+
for (Meta.CursorOption option : query.getMeta().getFlags()) {
2377+
2378+
switch (option) {
2379+
case EXHAUST:
2380+
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_EXHAUST);
2381+
break;
2382+
case NO_TIMEOUT:
2383+
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
2384+
break;
2385+
case PARTIAL:
2386+
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_PARTIAL);
2387+
break;
2388+
case SLAVE_OK:
2389+
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_SLAVEOK);
2390+
break;
2391+
default:
2392+
throw new IllegalArgumentException(String.format("%s is no supported flag.", option));
2393+
}
23772394
}
23782395
}
23792396

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
import java.util.Collections;
1919
import java.util.LinkedHashMap;
20+
import java.util.LinkedHashSet;
2021
import java.util.Map;
2122
import java.util.Map.Entry;
23+
import java.util.Set;
2224
import java.util.concurrent.TimeUnit;
2325

2426
import org.springframework.util.Assert;
@@ -46,7 +48,7 @@ private enum MetaKey {
4648
}
4749

4850
private final Map<String, Object> values = new LinkedHashMap<String, Object>(2);
49-
private Boolean noCursorTimeout;
51+
private final Set<CursorOption> flags = new LinkedHashSet<CursorOption>();
5052

5153
/**
5254
* @return {@literal null} if not set.
@@ -123,28 +125,31 @@ public boolean getSnapshot() {
123125
}
124126

125127
/**
126-
* @return {@literal null} if not set.
128+
* Add {@link CursorOption} influencing behavior of the {@link com.mongodb.DBCursor}.
129+
*
130+
* @param option must not be {@literal null}.
131+
* @return
127132
* @since 1.10
128133
*/
129-
public Boolean isNoCursorTimeout() {
130-
return this.noCursorTimeout;
134+
public boolean addFlag(CursorOption option) {
135+
136+
Assert.notNull(option, "CursorOption must not be null!");
137+
return this.flags.add(option);
131138
}
132139

133140
/**
134-
* Instructs the server to avoid closing a cursor automatically after a period of inactivity.
135-
*
136-
* @param noCursorTimeout
141+
* @return never {@literal null}.
137142
* @since 1.10
138143
*/
139-
public void setNoCursorTimeout(boolean noCursorTimeout) {
140-
this.noCursorTimeout = noCursorTimeout;
144+
public Set<CursorOption> getFlags() {
145+
return flags;
141146
}
142147

143148
/**
144149
* @return
145150
*/
146151
public boolean hasValues() {
147-
return !this.values.isEmpty() || this.noCursorTimeout != null;
152+
return !this.values.isEmpty() || !this.flags.isEmpty();
148153
}
149154

150155
/**
@@ -189,7 +194,10 @@ private <T> T getValue(String key, T defaultValue) {
189194
*/
190195
@Override
191196
public int hashCode() {
192-
return ObjectUtils.nullSafeHashCode(this.values);
197+
198+
int hash = ObjectUtils.nullSafeHashCode(this.values);
199+
hash += ObjectUtils.nullSafeHashCode(this.flags);
200+
return hash;
193201
}
194202

195203
/*
@@ -208,6 +216,35 @@ public boolean equals(Object obj) {
208216
}
209217

210218
Meta other = (Meta) obj;
211-
return ObjectUtils.nullSafeEquals(this.values, other.values);
219+
if (!ObjectUtils.nullSafeEquals(this.values, other.values)) {
220+
return false;
221+
}
222+
return ObjectUtils.nullSafeEquals(this.flags, other.flags);
223+
}
224+
225+
/**
226+
* {@link CursorOption} represents {@code OP_QUERY} wire protocol flags to change the behavior of queries.
227+
*
228+
* @author Christoph Strobl
229+
* @since 1.10
230+
*/
231+
public enum CursorOption {
232+
233+
/** Prevents the server from timing out idle cursors. */
234+
NO_TIMEOUT,
235+
236+
/**
237+
* Sets the cursor to return all data returned by the query at once rather than splitting the results into batches.
238+
*/
239+
EXHAUST,
240+
241+
/** Allows querying of a replica slave. */
242+
SLAVE_OK,
243+
244+
/**
245+
* Sets the cursor to return partial data from a query against a sharded cluster in which some shards do not respond
246+
* rather than throwing an error.
247+
*/
248+
PARTIAL
212249
}
213250
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,45 @@ public Query useSnapshot() {
339339

340340
/**
341341
* @return
342-
* @see Meta#setNoCursorTimeout(boolean)
342+
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#NO_TIMEOUT
343343
* @since 1.10
344344
*/
345345
public Query noCursorTimeout() {
346346

347-
meta.setNoCursorTimeout(true);
347+
meta.addFlag(Meta.CursorOption.NO_TIMEOUT);
348+
return this;
349+
}
350+
351+
/**
352+
* @return
353+
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#EXHAUST
354+
* @since 1.10
355+
*/
356+
public Query exhaust() {
357+
358+
meta.addFlag(Meta.CursorOption.EXHAUST);
359+
return this;
360+
}
361+
362+
/**
363+
* @return
364+
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#SLAVE_OK
365+
* @since 1.10
366+
*/
367+
public Query slaveOk() {
368+
369+
meta.addFlag(Meta.CursorOption.SLAVE_OK);
370+
return this;
371+
}
372+
373+
/**
374+
* @return
375+
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#PARTIAL
376+
* @since 1.10
377+
*/
378+
public Query partialResults() {
379+
380+
meta.addFlag(Meta.CursorOption.PARTIAL);
348381
return this;
349382
}
350383

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/Meta.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@
7676
boolean snapshot() default false;
7777

7878
/**
79-
* Instructs the server to avoid closing a cursor automatically after a period of inactivity.
79+
* Set {@link org.springframework.data.mongodb.core.query.Meta.CursorOption} to be used when executing query.
8080
*
81-
* @return
81+
* @return never {@literal null}.
8282
* @since 1.10
8383
*/
84-
boolean noCursorTimeout() default false;
84+
org.springframework.data.mongodb.core.query.Meta.CursorOption[] flags() default {};
8585

8686
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.data.util.TypeInformation;
3838
import org.springframework.util.Assert;
3939
import org.springframework.util.ClassUtils;
40+
import org.springframework.util.ObjectUtils;
4041
import org.springframework.util.StringUtils;
4142

4243
/**
@@ -248,8 +249,11 @@ public org.springframework.data.mongodb.core.query.Meta getQueryMetaAttributes()
248249
metaAttributes.setSnapshot(meta.snapshot());
249250
}
250251

251-
if (meta.noCursorTimeout()) {
252-
metaAttributes.setNoCursorTimeout(meta.noCursorTimeout());
252+
if (!ObjectUtils.isEmpty(meta.flags())) {
253+
254+
for (org.springframework.data.mongodb.core.query.Meta.CursorOption option : meta.flags()) {
255+
metaAttributes.addFlag(option);
256+
}
253257
}
254258

255259
return metaAttributes;

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ private interface Repo extends MongoRepository<Person, Long> {
347347

348348
List<Person> findByFirstname(String firstname);
349349

350-
@Meta(comment = "comment", noCursorTimeout = true)
350+
@Meta(comment = "comment", flags = {org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT})
351351
Page<Person> findByFirstname(String firstnanme, Pageable pageable);
352352

353353
@Meta(comment = "comment")

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryMethodUnitTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ public void createsMongoQueryMethodWithMaxExecutionTimeCorrectly() throws Except
152152
assertThat(method.getQueryMetaAttributes().getMaxTimeMsec(), is(100L));
153153
}
154154

155-
156155
/**
157156
* @see DATAMONGO-1403
158157
*/
@@ -210,7 +209,8 @@ public void createsMongoQueryMethodWithNoCursorTimeoutCorrectly() throws Excepti
210209
MongoQueryMethod method = queryMethod(PersonRepository.class, "metaWithNoCursorTimeout");
211210

212211
assertThat(method.hasQueryMetaAttributes(), is(true));
213-
assertThat(method.getQueryMetaAttributes().isNoCursorTimeout(), is(true));
212+
assertThat(method.getQueryMetaAttributes().getFlags(),
213+
containsInAnyOrder(org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT));
214214
}
215215

216216
/**
@@ -262,7 +262,7 @@ interface PersonRepository extends Repository<User, Long> {
262262
@Meta(snapshot = true)
263263
List<User> metaWithSnapshotUsage();
264264

265-
@Meta(noCursorTimeout = true)
265+
@Meta(flags = { org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT })
266266
List<User> metaWithNoCursorTimeout();
267267

268268
/**

0 commit comments

Comments
 (0)