Skip to content

Commit fcec305

Browse files
committed
CXX-184 Add MaxTimeMs support to command helpers
1 parent 08901fd commit fcec305

File tree

3 files changed

+53
-25
lines changed

3 files changed

+53
-25
lines changed

src/mongo/client/dbclient.cpp

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ namespace mongo {
267267
return *this;
268268
}
269269

270+
Query& Query::maxTimeMs(int millis) {
271+
appendComplex( "$maxTimeMS", millis );
272+
return *this;
273+
}
274+
270275
Query& Query::explain() {
271276
appendComplex( "$explain", true );
272277
return *this;
@@ -301,6 +306,21 @@ namespace mongo {
301306
return false;
302307
}
303308

309+
BSONObj Query::getModifiers() const {
310+
std::set<string> names;
311+
obj.getFieldNames(names);
312+
313+
BSONObjBuilder complexFields;
314+
315+
std::set<string>::const_iterator nameIterator;
316+
for(nameIterator = names.begin(); nameIterator != names.end(); ++nameIterator) {
317+
if (nameIterator->find('$') == '0')
318+
complexFields.append(obj.getField(*nameIterator));
319+
}
320+
321+
return complexFields.obj();
322+
}
323+
304324
Query& Query::readPref(ReadPreference pref, const BSONArray& tags) {
305325
string mode;
306326

@@ -353,6 +373,10 @@ namespace mongo {
353373
return hasReadPreference(obj);
354374
}
355375

376+
bool Query::hasMaxTimeMs() const {
377+
return obj.hasField( "$maxTimeMS" );
378+
}
379+
356380
BSONObj Query::getFilter() const {
357381
bool hasDollar;
358382
if ( ! isComplex( &hasDollar ) )
@@ -378,6 +402,10 @@ namespace mongo {
378402
return obj.getObjectField(ReadPrefField.name());
379403
}
380404

405+
int Query::getMaxTimeMs() const {
406+
return obj.getIntField("maxTimeMs");
407+
}
408+
381409
bool Query::isExplain() const {
382410
return isComplex() && obj.getBoolField( "$explain" );
383411
}
@@ -472,8 +500,8 @@ namespace mongo {
472500
if ( skip )
473501
b.append( "skip" , skip );
474502

475-
if (query.hasReadPreference())
476-
b.append(query.ReadPrefField.name(), query.getReadPref());
503+
if (query.isComplex())
504+
b.appendElements(query.getModifiers());
477505

478506
return b.obj();
479507
}
@@ -817,8 +845,9 @@ namespace mongo {
817845

818846
if( !query.obj.isEmpty() )
819847
b.append("query", query.getFilter());
820-
if (query.hasReadPreference())
821-
b.append(query.ReadPrefField.name(), query.getReadPref());
848+
849+
if (query.isComplex())
850+
b.appendElements(query.getModifiers());
822851

823852
b.append("out", output.out);
824853
BSONObj info;
@@ -889,8 +918,8 @@ namespace mongo {
889918
BSONObjBuilder commandBuilder;
890919
commandBuilder.append("group", group);
891920

892-
if (query.hasReadPreference())
893-
commandBuilder.append(query.ReadPrefField.name(), query.getReadPref());
921+
if (query.isComplex())
922+
commandBuilder.appendElements(query.getModifiers());
894923

895924
BSONObj result;
896925
bool ok = runCommand(nsGetDB(ns.toString()), commandBuilder.obj(), result);
@@ -915,8 +944,9 @@ namespace mongo {
915944
commandBuilder.append("distinct", nsGetCollection(ns.toString()));
916945
commandBuilder.append("key", field);
917946
commandBuilder.append("query", query.getFilter());
918-
if (query.hasReadPreference())
919-
commandBuilder.append(query.ReadPrefField.name(), query.getReadPref());
947+
948+
if (query.isComplex())
949+
commandBuilder.appendElements(query.getModifiers());
920950

921951
BSONObj result;
922952
bool ok = runCommand(nsGetDB(ns.toString()), commandBuilder.obj(), result);

src/mongo/client/dbclientinterface.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,12 @@ namespace mongo {
347347
Query& hint(BSONObj keyPattern);
348348
Query& hint(const std::string &jsonKeyPatt);
349349

350+
/**
351+
* Specifies a cumulative time limit in milliseconds for processing an operation.
352+
* MongoDB will interrupt the operation at the earliest following interrupt point.
353+
*/
354+
Query& maxTimeMs(int millis);
355+
350356
/** Provide min and/or max index limits for the query.
351357
min <= x < max
352358
*/
@@ -402,19 +408,22 @@ namespace mongo {
402408
* @return true if this query has an orderby, hint, or some other field
403409
*/
404410
bool isComplex( bool * hasDollar = 0 ) const;
411+
BSONObj getModifiers() const;
405412
static bool MONGO_CLIENT_FUNC isComplex(const BSONObj& obj, bool* hasDollar = 0);
406413

407414
BSONObj getFilter() const;
408415
BSONObj getSort() const;
409416
BSONObj getHint() const;
410417
BSONObj getReadPref() const;
418+
int getMaxTimeMs() const;
411419
bool isExplain() const;
412420

413421
/**
414422
* @return true if the query object contains a read preference specification object.
415423
*/
416424
static bool MONGO_CLIENT_FUNC hasReadPreference(const BSONObj& queryObj);
417425
bool hasReadPreference() const;
426+
bool hasMaxTimeMs() const;
418427

419428
std::string toString() const;
420429
operator std::string() const { return toString(); }

src/mongo/unittest/dbclient_test.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,32 +1024,21 @@ namespace {
10241024
c.insert(TEST_NS, BSON("a" << true));
10251025
BSONObj result;
10261026

1027-
c.runCommand("admin", BSON("buildinfo" << true), result);
1028-
1029-
if (versionCmp(result["version"].toString(), "2.5.3") >= 0) {
1027+
if (serverGTE(&c, 2, 6)) {
10301028
c.runCommand("admin", BSON(
10311029
"configureFailPoint" << "maxTimeAlwaysTimeOut" <<
10321030
"mode" << BSON("times" << 2)
10331031
), result);
10341032

10351033
// First test with a query
1036-
ASSERT_NO_THROW(
1037-
c.findOne(TEST_NS, Query("{$query: {}}"));
1038-
);
1039-
ASSERT_THROWS(
1040-
c.findOne(TEST_NS, Query("{$query: {}, $maxTimeMS: 1}"));
1041-
, DBException);
1034+
ASSERT_NO_THROW(c.findOne(TEST_NS, Query("{}")););
1035+
ASSERT_THROWS(c.findOne(TEST_NS, Query("{}").maxTimeMs(1)), DBException);
10421036

10431037
// Then test with a command
1044-
ASSERT_TRUE(
1045-
c.runCommand(TEST_DB, BSON("count" << TEST_COLL), result)
1046-
);
1047-
ASSERT_FALSE(
1048-
c.runCommand(TEST_DB,
1049-
BSON("count" << TEST_COLL << "maxTimeMS" << 1), result)
1050-
);
1038+
ASSERT_NO_THROW(c.count(TEST_NS, Query("{}")));
1039+
ASSERT_THROWS(c.count(TEST_NS, Query("{}").maxTimeMs(1)), DBException);
10511040
} else {
1052-
// we are not connected to MongoDB >= 2.5.3, skip
1041+
// we are not connected to MongoDB >= 2.6, skip
10531042
SUCCEED();
10541043
}
10551044
}

0 commit comments

Comments
 (0)