DATAMONGO-1480 - Polishing.
Opened up 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();
}
Original Pull Request: #390
This commit is contained in:
@@ -93,6 +93,7 @@ import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
|
||||
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
||||
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Meta;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
@@ -2372,8 +2373,24 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
cursorToUse = cursorToUse.addSpecial(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
if (query.getMeta().isNoCursorTimeout() != null && query.getMeta().isNoCursorTimeout().booleanValue()) {
|
||||
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
|
||||
for (Meta.CursorOption option : query.getMeta().getFlags()) {
|
||||
|
||||
switch (option) {
|
||||
case EXHAUST:
|
||||
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_EXHAUST);
|
||||
break;
|
||||
case NO_TIMEOUT:
|
||||
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
|
||||
break;
|
||||
case PARTIAL:
|
||||
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_PARTIAL);
|
||||
break;
|
||||
case SLAVE_OK:
|
||||
cursorToUse = cursorToUse.addOption(Bytes.QUERYOPTION_SLAVEOK);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(String.format("%s is no supported flag.", option));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
@@ -46,7 +48,7 @@ public class Meta {
|
||||
}
|
||||
|
||||
private final Map<String, Object> values = new LinkedHashMap<String, Object>(2);
|
||||
private Boolean noCursorTimeout;
|
||||
private final Set<CursorOption> flags = new LinkedHashSet<CursorOption>();
|
||||
|
||||
/**
|
||||
* @return {@literal null} if not set.
|
||||
@@ -123,28 +125,31 @@ public class Meta {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal null} if not set.
|
||||
* Add {@link CursorOption} influencing behavior of the {@link com.mongodb.DBCursor}.
|
||||
*
|
||||
* @param option must not be {@literal null}.
|
||||
* @return
|
||||
* @since 1.10
|
||||
*/
|
||||
public Boolean isNoCursorTimeout() {
|
||||
return this.noCursorTimeout;
|
||||
public boolean addFlag(CursorOption option) {
|
||||
|
||||
Assert.notNull(option, "CursorOption must not be null!");
|
||||
return this.flags.add(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the server to avoid closing a cursor automatically after a period of inactivity.
|
||||
*
|
||||
* @param noCursorTimeout
|
||||
* @return never {@literal null}.
|
||||
* @since 1.10
|
||||
*/
|
||||
public void setNoCursorTimeout(boolean noCursorTimeout) {
|
||||
this.noCursorTimeout = noCursorTimeout;
|
||||
public Set<CursorOption> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean hasValues() {
|
||||
return !this.values.isEmpty() || this.noCursorTimeout != null;
|
||||
return !this.values.isEmpty() || !this.flags.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +194,10 @@ public class Meta {
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(this.values);
|
||||
|
||||
int hash = ObjectUtils.nullSafeHashCode(this.values);
|
||||
hash += ObjectUtils.nullSafeHashCode(this.flags);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,6 +216,35 @@ public class Meta {
|
||||
}
|
||||
|
||||
Meta other = (Meta) obj;
|
||||
return ObjectUtils.nullSafeEquals(this.values, other.values);
|
||||
if (!ObjectUtils.nullSafeEquals(this.values, other.values)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(this.flags, other.flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CursorOption} represents {@code OP_QUERY} wire protocol flags to change the behavior of queries.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 1.10
|
||||
*/
|
||||
public enum CursorOption {
|
||||
|
||||
/** Prevents the server from timing out idle cursors. */
|
||||
NO_TIMEOUT,
|
||||
|
||||
/**
|
||||
* Sets the cursor to return all data returned by the query at once rather than splitting the results into batches.
|
||||
*/
|
||||
EXHAUST,
|
||||
|
||||
/** Allows querying of a replica slave. */
|
||||
SLAVE_OK,
|
||||
|
||||
/**
|
||||
* Sets the cursor to return partial data from a query against a sharded cluster in which some shards do not respond
|
||||
* rather than throwing an error.
|
||||
*/
|
||||
PARTIAL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,12 +339,45 @@ public class Query {
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see Meta#setNoCursorTimeout(boolean)
|
||||
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#NO_TIMEOUT
|
||||
* @since 1.10
|
||||
*/
|
||||
public Query noCursorTimeout() {
|
||||
|
||||
meta.setNoCursorTimeout(true);
|
||||
meta.addFlag(Meta.CursorOption.NO_TIMEOUT);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#EXHAUST
|
||||
* @since 1.10
|
||||
*/
|
||||
public Query exhaust() {
|
||||
|
||||
meta.addFlag(Meta.CursorOption.EXHAUST);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#SLAVE_OK
|
||||
* @since 1.10
|
||||
*/
|
||||
public Query slaveOk() {
|
||||
|
||||
meta.addFlag(Meta.CursorOption.SLAVE_OK);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see org.springframework.data.mongodb.core.query.Meta.CursorOption#PARTIAL
|
||||
* @since 1.10
|
||||
*/
|
||||
public Query partialResults() {
|
||||
|
||||
meta.addFlag(Meta.CursorOption.PARTIAL);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,11 +76,11 @@ public @interface Meta {
|
||||
boolean snapshot() default false;
|
||||
|
||||
/**
|
||||
* Instructs the server to avoid closing a cursor automatically after a period of inactivity.
|
||||
* Set {@link org.springframework.data.mongodb.core.query.Meta.CursorOption} to be used when executing query.
|
||||
*
|
||||
* @return
|
||||
* @return never {@literal null}.
|
||||
* @since 1.10
|
||||
*/
|
||||
boolean noCursorTimeout() default false;
|
||||
org.springframework.data.mongodb.core.query.Meta.CursorOption[] flags() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -248,8 +249,11 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
metaAttributes.setSnapshot(meta.snapshot());
|
||||
}
|
||||
|
||||
if (meta.noCursorTimeout()) {
|
||||
metaAttributes.setNoCursorTimeout(meta.noCursorTimeout());
|
||||
if (!ObjectUtils.isEmpty(meta.flags())) {
|
||||
|
||||
for (org.springframework.data.mongodb.core.query.Meta.CursorOption option : meta.flags()) {
|
||||
metaAttributes.addFlag(option);
|
||||
}
|
||||
}
|
||||
|
||||
return metaAttributes;
|
||||
|
||||
@@ -347,7 +347,7 @@ public class AbstractMongoQueryUnitTests {
|
||||
|
||||
List<Person> findByFirstname(String firstname);
|
||||
|
||||
@Meta(comment = "comment", noCursorTimeout = true)
|
||||
@Meta(comment = "comment", flags = {org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT})
|
||||
Page<Person> findByFirstname(String firstnanme, Pageable pageable);
|
||||
|
||||
@Meta(comment = "comment")
|
||||
|
||||
@@ -152,7 +152,6 @@ public class MongoQueryMethodUnitTests {
|
||||
assertThat(method.getQueryMetaAttributes().getMaxTimeMsec(), is(100L));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1403
|
||||
*/
|
||||
@@ -210,7 +209,21 @@ public class MongoQueryMethodUnitTests {
|
||||
MongoQueryMethod method = queryMethod(PersonRepository.class, "metaWithNoCursorTimeout");
|
||||
|
||||
assertThat(method.hasQueryMetaAttributes(), is(true));
|
||||
assertThat(method.getQueryMetaAttributes().isNoCursorTimeout(), is(true));
|
||||
assertThat(method.getQueryMetaAttributes().getFlags(),
|
||||
containsInAnyOrder(org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1480
|
||||
*/
|
||||
@Test
|
||||
public void createsMongoQueryMethodWithMultipleFlagsCorrectly() throws Exception {
|
||||
|
||||
MongoQueryMethod method = queryMethod(PersonRepository.class, "metaWithMultipleFlags");
|
||||
|
||||
assertThat(method.hasQueryMetaAttributes(), is(true));
|
||||
assertThat(method.getQueryMetaAttributes().getFlags(),
|
||||
containsInAnyOrder(org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT, org.springframework.data.mongodb.core.query.Meta.CursorOption.SLAVE_OK));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,9 +275,12 @@ public class MongoQueryMethodUnitTests {
|
||||
@Meta(snapshot = true)
|
||||
List<User> metaWithSnapshotUsage();
|
||||
|
||||
@Meta(noCursorTimeout = true)
|
||||
@Meta(flags = { org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT })
|
||||
List<User> metaWithNoCursorTimeout();
|
||||
|
||||
@Meta(flags = { org.springframework.data.mongodb.core.query.Meta.CursorOption.NO_TIMEOUT, org.springframework.data.mongodb.core.query.Meta.CursorOption.SLAVE_OK })
|
||||
List<User> metaWithMultipleFlags();
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1266
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user