diff options
Diffstat (limited to 'src/mongo/client')
-rw-r--r-- | src/mongo/client/client_deprecated.cpp | 68 | ||||
-rw-r--r-- | src/mongo/client/client_deprecated.h | 92 | ||||
-rw-r--r-- | src/mongo/client/dbclient_base.cpp | 61 | ||||
-rw-r--r-- | src/mongo/client/dbclient_base.h | 24 | ||||
-rw-r--r-- | src/mongo/client/dbclient_connection.cpp | 61 | ||||
-rw-r--r-- | src/mongo/client/dbclient_connection.h | 33 | ||||
-rw-r--r-- | src/mongo/client/dbclient_cursor.cpp | 216 | ||||
-rw-r--r-- | src/mongo/client/dbclient_cursor.h | 121 | ||||
-rw-r--r-- | src/mongo/client/dbclient_mockcursor.cpp | 2 | ||||
-rw-r--r-- | src/mongo/client/dbclient_mockcursor.h | 3 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs.cpp | 255 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs.h | 13 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs_test.cpp | 223 |
13 files changed, 131 insertions, 1041 deletions
diff --git a/src/mongo/client/client_deprecated.cpp b/src/mongo/client/client_deprecated.cpp index e8bbf0542f3..2df1d1be3ac 100644 --- a/src/mongo/client/client_deprecated.cpp +++ b/src/mongo/client/client_deprecated.cpp @@ -201,74 +201,6 @@ Status initFindFromOpQueryObj(const BSONObj& querySettings, FindCommandRequest* } // namespace -const BSONField<BSONObj> Query::ReadPrefField("$readPreference"); - -void Query::makeComplex() { - if (isComplex()) - return; - BSONObjBuilder b; - b.append("query", obj); - obj = b.obj(); -} - -Query& Query::sort(const BSONObj& s) { - appendComplex("orderby", s); - return *this; -} - -Query& Query::hint(BSONObj keyPattern) { - appendComplex("$hint", keyPattern); - return *this; -} - -Query& Query::readPref(ReadPreference pref, const BSONArray& tags) { - appendComplex(ReadPrefField.name().c_str(), - ReadPreferenceSetting(pref, TagSet(tags)).toInnerBSON()); - return *this; -} - -bool Query::isComplex(bool* hasDollar) const { - return isComplexQueryObj(obj, hasDollar); -} - -Query& Query::appendElements(BSONObj elements) { - makeComplex(); - BSONObjBuilder b(std::move(obj)); - b.appendElements(elements); - obj = b.obj(); - return *this; -} - -Query& Query::requestResumeToken(bool enable) { - appendComplex("$_requestResumeToken", enable); - return *this; -} - -Query& Query::resumeAfter(BSONObj point) { - appendComplex("$_resumeAfter", point); - return *this; -} - -Query& Query::maxTimeMS(long long timeout) { - appendComplex("$maxTimeMS", timeout); - return *this; -} - -Query& Query::term(long long value) { - appendComplex("term", value); - return *this; -} - -Query& Query::readConcern(BSONObj rc) { - appendComplex("readConcern", rc); - return *this; -} - -Query& Query::readOnce(bool enable) { - appendComplex("$readOnce", enable); - return *this; -} - void initFindFromLegacyOptions(BSONObj bsonOptions, int options, FindCommandRequest* findCommand) { invariant(findCommand); BSONObj filter = filterFromOpQueryObj(bsonOptions); diff --git a/src/mongo/client/client_deprecated.h b/src/mongo/client/client_deprecated.h index d8eb80e5afa..fa4509c62f8 100644 --- a/src/mongo/client/client_deprecated.h +++ b/src/mongo/client/client_deprecated.h @@ -41,98 +41,6 @@ namespace mongo { * added because OP_QUERY is no longer supported by the shell or server. */ namespace client_deprecated { - -/** - * Represents a subset of query settings, such as sort, hint, etc. It is only used in the context of - * the deprecated query API in 'DBClientBase', which has been superseded by `DBClientBase::find()` - * and friends. Additional uses of this class should not be added to the code base! - */ -class Query { -public: - static const BSONField<BSONObj> ReadPrefField; - - /** - * Creating a Query object from raw BSON is on its way out. Please don't add new callers under - * any circumstances. - */ - static Query fromBSONDeprecated(const BSONObj& b) { - Query q; - q.obj = b; - return q; - } - - Query() : obj(BSONObj()) {} - - /** Add a sort (ORDER BY) criteria to the query expression. - @param sortPattern the sort order template. For example to order by name ascending, time - descending: - { name : 1, ts : -1 } - i.e. - BSON( "name" << 1 << "ts" << -1 ) - or - fromjson(" name : 1, ts : -1 ") - */ - Query& sort(const BSONObj& sortPattern); - - /** Provide a hint to the query. - @param keyPattern Key pattern for the index to use. - Example: - hint("{ts:1}") - */ - Query& hint(BSONObj keyPattern); - - /** - * Sets the read preference for this query. - * - * @param pref the read preference mode for this query. - * @param tags the set of tags to use for this query. - */ - Query& readPref(ReadPreference pref, const BSONArray& tags); - - /** - * A temporary accessor that returns a reference to the internal BSON object. No new callers - * should be introduced! - * NB: must be implemented in the header because db/query/query_request cannot link against - * client/client_query. - */ - const BSONObj& getFullSettingsDeprecated() const { - return obj; - } - - /** - * The setters below were added to make the contents of the Query's settings internal BSON - * explicit. They will be reviewed and deprecated/removed as appropriate. - */ - Query& appendElements(BSONObj elements); - Query& requestResumeToken(bool enable); - Query& resumeAfter(BSONObj point); - Query& maxTimeMS(long long timeout); - Query& term(long long value); - Query& readConcern(BSONObj rc); - Query& readOnce(bool enable); - -private: - BSONObj obj; - - /** - * @return true if this query has an orderby, hint, or some other field - */ - bool isComplex(bool* hasDollar = nullptr) const; - - void makeComplex(); - template <class T> - void appendComplex(const char* fieldName, const T& val) { - makeComplex(); - BSONObjBuilder b(std::move(obj)); - b.append(fieldName, val); - obj = b.obj(); - } -}; - -inline std::ostream& operator<<(std::ostream& s, const Query& q) { - return s << q.getFullSettingsDeprecated().toString(); -} - /** * WARNING: This function exists only to support special code paths that use an OP_QUERY-style query * representation (even though the OP_QUERY wire protocol message itself is no longer supported). Do diff --git a/src/mongo/client/dbclient_base.cpp b/src/mongo/client/dbclient_base.cpp index 5c2238ebec9..2c2bcf36412 100644 --- a/src/mongo/client/dbclient_base.cpp +++ b/src/mongo/client/dbclient_base.cpp @@ -584,31 +584,6 @@ bool DBClientBase::exists(const string& ns) { const uint64_t DBClientBase::INVALID_SOCK_CREATION_TIME = std::numeric_limits<uint64_t>::max(); -unique_ptr<DBClientCursor> DBClientBase::query_DEPRECATED( - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - boost::optional<BSONObj> readConcernObj) { - unique_ptr<DBClientCursor> c(new DBClientCursor(this, - nsOrUuid, - filter, - querySettings, - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj)); - if (c->init()) - return c; - return nullptr; -} - std::unique_ptr<DBClientCursor> DBClientBase::find(FindCommandRequest findRequest, const ReadPreferenceSetting& readPref, ExhaustMode exhaustMode) { @@ -651,46 +626,12 @@ BSONObj DBClientBase::findOne(const NamespaceStringOrUUID& nssOrUuid, BSONObj fi unique_ptr<DBClientCursor> DBClientBase::getMore(const string& ns, long long cursorId) { unique_ptr<DBClientCursor> c( - new DBClientCursor(this, NamespaceString(ns), cursorId, 0 /* limit */, 0 /* options */)); + new DBClientCursor(this, NamespaceString(ns), cursorId, false /*isExhaust*/)); if (c->init()) return c; return nullptr; } -unsigned long long DBClientBase::query_DEPRECATED( - std::function<void(DBClientCursorBatchIterator&)> f, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - boost::optional<BSONObj> readConcernObj) { - // mask options - queryOptions &= (int)(QueryOption_NoCursorTimeout | QueryOption_SecondaryOk); - - unique_ptr<DBClientCursor> c(this->query_DEPRECATED(nsOrUuid, - filter, - querySettings, - 0, - 0, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj)); - // query_DEPRECATED() throws on network error so OK to uassert with numeric code here. - uassert(16090, "socket error for mapping query", c.get()); - - unsigned long long n = 0; - - while (c->more()) { - DBClientCursorBatchIterator i(*c); - f(i); - n += i.n(); - } - return n; -} - namespace { OpMsgRequest createInsertRequest(const string& ns, const vector<BSONObj>& v, diff --git a/src/mongo/client/dbclient_base.h b/src/mongo/client/dbclient_base.h index 0a1c7bdd77d..3c933f6d3d3 100644 --- a/src/mongo/client/dbclient_base.h +++ b/src/mongo/client/dbclient_base.h @@ -35,7 +35,6 @@ #include "mongo/base/string_data.h" #include "mongo/client/authenticate.h" #include "mongo/client/client_api_version_parameters_gen.h" -#include "mongo/client/client_deprecated.h" #include "mongo/client/connection_string.h" #include "mongo/client/dbclient_cursor.h" #include "mongo/client/index_spec.h" @@ -578,29 +577,6 @@ public: BSONObj findOne(const NamespaceStringOrUUID& nssOrUuid, BSONObj filter); /** - * Legacy find API. Do not add new callers! Use the 'find*()' methods above instead. - */ - virtual std::unique_ptr<DBClientCursor> query_DEPRECATED( - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings = client_deprecated::Query(), - int limit = 0, - int nToSkip = 0, - const BSONObj* fieldsToReturn = nullptr, - int queryOptions = 0, - int batchSize = 0, - boost::optional<BSONObj> readConcernObj = boost::none); - virtual unsigned long long query_DEPRECATED( - std::function<void(DBClientCursorBatchIterator&)> f, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings = client_deprecated::Query(), - const BSONObj* fieldsToReturn = nullptr, - int queryOptions = QueryOption_Exhaust, - int batchSize = 0, - boost::optional<BSONObj> readConcernObj = boost::none); - - /** * Don't use this - called automatically by DBClientCursor for you. * 'cursorId': Id of cursor to retrieve. * Returns an handle to a previously allocated cursor. diff --git a/src/mongo/client/dbclient_connection.cpp b/src/mongo/client/dbclient_connection.cpp index c3651edb01c..1b87829c1cd 100644 --- a/src/mongo/client/dbclient_connection.cpp +++ b/src/mongo/client/dbclient_connection.cpp @@ -625,67 +625,6 @@ uint64_t DBClientConnection::getSockCreationMicroSec() const { } } -unsigned long long DBClientConnection::query_DEPRECATED( - std::function<void(DBClientCursorBatchIterator&)> f, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - boost::optional<BSONObj> readConcernObj) { - if (!(queryOptions & QueryOption_Exhaust)) { - return DBClientBase::query_DEPRECATED(f, - nsOrUuid, - filter, - querySettings, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj); - } - - // mask options - queryOptions &= - (int)(QueryOption_NoCursorTimeout | QueryOption_SecondaryOk | QueryOption_Exhaust); - - unique_ptr<DBClientCursor> c(this->query_DEPRECATED(nsOrUuid, - filter, - querySettings, - 0, - 0, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj)); - // Note that this->query will throw for network errors, so it is OK to return a numeric - // error code here. - uassert(13386, "socket error for mapping query", c.get()); - - unsigned long long n = 0; - - try { - while (1) { - while (c->moreInCurrentBatch()) { - DBClientCursorBatchIterator i(*c); - f(i); - n += i.n(); - } - - if (!c->more()) - break; - } - } catch (std::exception&) { - /* connection CANNOT be used anymore as more data may be on the way from the server. - we have to reconnect. - */ - _markFailed(kEndSession); - throw; - } - - return n; -} - DBClientConnection::DBClientConnection(bool _autoReconnect, double so_timeout, MongoURI uri, diff --git a/src/mongo/client/dbclient_connection.h b/src/mongo/client/dbclient_connection.h index 45ffcf97b78..61096ba59b3 100644 --- a/src/mongo/client/dbclient_connection.h +++ b/src/mongo/client/dbclient_connection.h @@ -62,7 +62,6 @@ struct RemoteCommandResponse; } class DBClientCursor; -class DBClientCursorBatchIterator; /** * A basic connection to the database. @@ -142,38 +141,6 @@ public: */ void logout(const std::string& dbname, BSONObj& info) override; - std::unique_ptr<DBClientCursor> query_DEPRECATED( - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings = client_deprecated::Query(), - int limit = 0, - int nToSkip = 0, - const BSONObj* fieldsToReturn = nullptr, - int queryOptions = 0, - int batchSize = 0, - boost::optional<BSONObj> readConcernObj = boost::none) override { - checkConnection(); - return DBClientBase::query_DEPRECATED(nsOrUuid, - filter, - querySettings, - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj); - } - - unsigned long long query_DEPRECATED( - std::function<void(DBClientCursorBatchIterator&)>, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize = 0, - boost::optional<BSONObj> readConcernObj = boost::none) override; - using DBClientBase::runCommandWithTarget; std::pair<rpc::UniqueReply, DBClientBase*> runCommandWithTarget(OpMsgRequest request) override; std::pair<rpc::UniqueReply, std::shared_ptr<DBClientBase>> runCommandWithTarget( diff --git a/src/mongo/client/dbclient_cursor.cpp b/src/mongo/client/dbclient_cursor.cpp index 33fb9e86508..dc6a32acd07 100644 --- a/src/mongo/client/dbclient_cursor.cpp +++ b/src/mongo/client/dbclient_cursor.cpp @@ -72,137 +72,32 @@ BSONObj addMetadata(DBClientBase* client, BSONObj command) { } } -Message assembleCommandRequest(DBClientBase* cli, +Message assembleCommandRequest(DBClientBase* client, StringData database, - int legacyQueryOptions, - BSONObj legacyQuery) { - auto request = rpc::upconvertRequest(database, std::move(legacyQuery), legacyQueryOptions); - request.body = addMetadata(cli, std::move(request.body)); - return request.serialize(); -} - -Message assembleFromFindCommandRequest(DBClientBase* client, - StringData database, - const FindCommandRequest& request, - const ReadPreferenceSetting& readPref) { - BSONObj findCmd = request.toBSON(BSONObj()); - + BSONObj commandObj, + const ReadPreferenceSetting& readPref) { // Add the $readPreference field to the request. { - BSONObjBuilder builder{findCmd}; + BSONObjBuilder builder{commandObj}; readPref.toContainingBSON(&builder); - findCmd = builder.obj(); + commandObj = builder.obj(); } - findCmd = addMetadata(client, std::move(findCmd)); - auto opMsgRequest = OpMsgRequest::fromDBAndBody(database, findCmd); + commandObj = addMetadata(client, std::move(commandObj)); + auto opMsgRequest = OpMsgRequest::fromDBAndBody(database, commandObj); return opMsgRequest.serialize(); } - -std::unique_ptr<FindCommandRequest> fromLegacyQuery(NamespaceStringOrUUID nssOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - const BSONObj& proj, - int ntoskip, - int queryOptions) { - auto findCommand = std::make_unique<FindCommandRequest>(std::move(nssOrUuid)); - - client_deprecated::initFindFromLegacyOptions( - querySettings.getFullSettingsDeprecated(), queryOptions, findCommand.get()); - - findCommand->setFilter(filter.getOwned()); - - if (!proj.isEmpty()) { - findCommand->setProjection(proj.getOwned()); - } - if (ntoskip) { - findCommand->setSkip(ntoskip); - } - - uassertStatusOK(query_request_helper::validateFindCommandRequest(*findCommand)); - - return findCommand; -} - -int queryOptionsFromFindCommand(const FindCommandRequest& findCmd, - const ReadPreferenceSetting& readPref, - bool isExhaust) { - int queryOptions = 0; - if (readPref.canRunOnSecondary()) { - queryOptions = queryOptions | QueryOption_SecondaryOk; - } - if (findCmd.getTailable()) { - queryOptions = queryOptions | QueryOption_CursorTailable; - } - if (findCmd.getNoCursorTimeout()) { - queryOptions = queryOptions | QueryOption_NoCursorTimeout; - } - if (findCmd.getAwaitData()) { - queryOptions = queryOptions | QueryOption_AwaitData; - } - if (findCmd.getAllowPartialResults()) { - queryOptions = queryOptions | QueryOption_PartialResults; - } - if (isExhaust) { - queryOptions = queryOptions | QueryOption_Exhaust; - } - return queryOptions; -} - } // namespace -Message DBClientCursor::initFromLegacyRequest() { - auto findCommand = fromLegacyQuery(_nsOrUuid, - _filter, - _querySettings, - _fieldsToReturn ? *_fieldsToReturn : BSONObj(), - _nToSkip, - _opts); - - if (_limit) { - findCommand->setLimit(_limit); - } - if (_batchSize) { - findCommand->setBatchSize(_batchSize); - } - - const BSONObj querySettings = _querySettings.getFullSettingsDeprecated(); - // We prioritize the readConcern parsed from the query object over '_readConcernObj'. - if (!findCommand->getReadConcern()) { - if (_readConcernObj) { - findCommand->setReadConcern(_readConcernObj); - } else { - // If no readConcern was specified, initialize it to an empty readConcern object, ie. - // equivalent to `readConcern: {}`. This ensures that mongos passes this empty - // readConcern to shards. - findCommand->setReadConcern(BSONObj()); - } - } - - BSONObj cmd = findCommand->toBSON(BSONObj()); - if (auto readPref = querySettings["$readPreference"]) { - // FindCommandRequest doesn't handle $readPreference. - cmd = BSONObjBuilder(std::move(cmd)).append(readPref).obj(); - } - - return assembleCommandRequest(_client, _ns.db(), _opts, std::move(cmd)); -} - Message DBClientCursor::assembleInit() { if (_cursorId) { return assembleGetMore(); } // We haven't gotten a cursorId yet so we need to issue the initial find command. - if (_findRequest) { - // The caller described their find command using the modern 'FindCommandRequest' API. - return assembleFromFindCommandRequest(_client, _ns.db(), *_findRequest, _readPref); - } else { - // The caller used a legacy API to describe the find operation, which may include $-prefixed - // directives in the format previously expected for an OP_QUERY. We need to upconvert this - // OP_QUERY-inspired format to a find command. - return initFromLegacyRequest(); - } + invariant(_findRequest); + BSONObj findCmd = _findRequest->toBSON(BSONObj()); + return assembleCommandRequest(_client, _ns.db(), std::move(findCmd), _readPref); } Message DBClientCursor::assembleGetMore() { @@ -217,10 +112,10 @@ Message DBClientCursor::assembleGetMore() { getMoreRequest.setTerm(static_cast<std::int64_t>(*_term)); } getMoreRequest.setLastKnownCommittedOpTime(_lastKnownCommittedOpTime); - auto msg = assembleCommandRequest(_client, _ns.db(), _opts, getMoreRequest.toBSON({})); + auto msg = assembleCommandRequest(_client, _ns.db(), getMoreRequest.toBSON({}), _readPref); // Set the exhaust flag if needed. - if (_opts & QueryOption_Exhaust && msg.operation() == dbMsg) { + if (_isExhaust) { OpMsg::setFlag(&msg, OpMsg::kExhaustSupported); } return msg; @@ -251,8 +146,7 @@ bool DBClientCursor::init() { void DBClientCursor::requestMore() { // For exhaust queries, once the stream has been initiated we get data blasted to us // from the remote server, without a need to send any more 'getMore' requests. - const auto isExhaust = _opts & QueryOption_Exhaust; - if (isExhaust && _connectionHasPendingReplies) { + if (_isExhaust && _connectionHasPendingReplies) { return exhaustReceiveMore(); } @@ -277,7 +171,7 @@ void DBClientCursor::requestMore() { } /** - * With QueryOption_Exhaust, the server just blasts data at us. The end of a stream is marked with a + * For exhaust cursors, the server just blasts data at us. The end of a stream is marked with a * cursor id of 0. */ void DBClientCursor::exhaustReceiveMore() { @@ -295,9 +189,9 @@ BSONObj DBClientCursor::commandDataReceived(const Message& reply) { invariant(op == opReply || op == dbMsg); // Check if the reply indicates that it is part of an exhaust stream. - const auto isExhaust = OpMsg::isFlagSet(reply, OpMsg::kMoreToCome); - _connectionHasPendingReplies = isExhaust; - if (isExhaust) { + const auto isExhaustReply = OpMsg::isFlagSet(reply, OpMsg::kMoreToCome); + _connectionHasPendingReplies = isExhaustReply; + if (isExhaustReply) { _lastRequestId = reply.header().getId(); } @@ -431,83 +325,20 @@ void DBClientCursor::attach(AScopedConnection* conn) { DBClientCursor::DBClientCursor(DBClientBase* client, const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - boost::optional<BSONObj> readConcernObj) - : DBClientCursor(client, - nsOrUuid, - filter, - querySettings, - 0, // cursorId - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - {}, - readConcernObj, - boost::none) {} - -DBClientCursor::DBClientCursor(DBClientBase* client, - const NamespaceStringOrUUID& nsOrUuid, long long cursorId, - int limit, - int queryOptions, + bool isExhaust, std::vector<BSONObj> initialBatch, boost::optional<Timestamp> operationTime, boost::optional<BSONObj> postBatchResumeToken) - : DBClientCursor(client, - nsOrUuid, - BSONObj(), // filter - client_deprecated::Query(), - cursorId, - limit, - 0, // nToSkip - nullptr, // fieldsToReturn - queryOptions, - 0, - std::move(initialBatch), // batchSize - boost::none, - operationTime, - postBatchResumeToken) {} - -DBClientCursor::DBClientCursor(DBClientBase* client, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - long long cursorId, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - std::vector<BSONObj> initialBatch, - boost::optional<BSONObj> readConcernObj, - boost::optional<Timestamp> operationTime, - boost::optional<BSONObj> postBatchResumeToken) : _batch{std::move(initialBatch)}, _client(client), _originalHost(_client->getServerAddress()), _nsOrUuid(nsOrUuid), _ns(nsOrUuid.nss() ? *nsOrUuid.nss() : NamespaceString(nsOrUuid.dbname())), _cursorId(cursorId), - _batchSize(batchSize == 1 ? 2 : batchSize), - _limit(limit), - _filter(filter), - _querySettings(querySettings), - _nToSkip(nToSkip), - _fieldsToReturn(fieldsToReturn), - _readConcernObj(readConcernObj), - _opts(queryOptions), + _isExhaust(isExhaust), _operationTime(operationTime), - _postBatchResumeToken(postBatchResumeToken) { - tassert(5746103, "DBClientCursor limit must be non-negative", _limit >= 0); -} + _postBatchResumeToken(postBatchResumeToken) {} DBClientCursor::DBClientCursor(DBClientBase* client, FindCommandRequest findRequest, @@ -518,10 +349,9 @@ DBClientCursor::DBClientCursor(DBClientBase* client, _nsOrUuid(findRequest.getNamespaceOrUUID()), _ns(_nsOrUuid.nss() ? *_nsOrUuid.nss() : NamespaceString(_nsOrUuid.dbname())), _batchSize(findRequest.getBatchSize().value_or(0)), - _limit(findRequest.getLimit().value_or(0)), _findRequest(std::move(findRequest)), _readPref(readPref), - _opts(queryOptionsFromFindCommand(*_findRequest, _readPref, isExhaust)) { + _isExhaust(isExhaust) { // Internal clients should always pass an explicit readConcern. If the caller did not already // pass a readConcern than we must explicitly initialize an empty readConcern so that it ends up // in the serialized version of the find command which will be sent across the wire. @@ -565,8 +395,7 @@ StatusWith<std::unique_ptr<DBClientCursor>> DBClientCursor::fromAggregationReque return {std::make_unique<DBClientCursor>(client, aggRequest.getNamespace(), cursorId, - 0, - useExhaust ? QueryOption_Exhaust : 0, + useExhaust, firstBatch, operationTime, postBatchResumeToken)}; @@ -594,5 +423,4 @@ void DBClientCursor::kill() { _cursorId = 0; } - } // namespace mongo diff --git a/src/mongo/client/dbclient_cursor.h b/src/mongo/client/dbclient_cursor.h index 941eda47318..f13f861d96c 100644 --- a/src/mongo/client/dbclient_cursor.h +++ b/src/mongo/client/dbclient_cursor.h @@ -31,10 +31,8 @@ #include <stack> -#include "mongo/client/client_deprecated.h" +#include "mongo/client/read_preference.h" #include "mongo/db/dbmessage.h" -#include "mongo/db/jsobj.h" -#include "mongo/db/json.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/find_command_gen.h" #include "mongo/rpc/message.h" @@ -61,31 +59,26 @@ public: bool secondaryOk, bool useExhaust); + /** + * Constructs a 'DBClientCursor' that will be opened by issuing the find command described by + * 'findRequest'. + */ DBClientCursor(DBClientBase* client, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int bs, - boost::optional<BSONObj> readConcernObj = boost::none); + FindCommandRequest findRequest, + const ReadPreferenceSetting& readPref, + bool isExhaust); + /** + * Constructs a 'DBClientCursor' from a pre-existing cursor id. + */ DBClientCursor(DBClientBase* client, const NamespaceStringOrUUID& nsOrUuid, long long cursorId, - int limit, - int options, + bool isExhaust, std::vector<BSONObj> initialBatch = {}, boost::optional<Timestamp> operationTime = boost::none, boost::optional<BSONObj> postBatchResumeToken = boost::none); - DBClientCursor(DBClientBase* client, - FindCommandRequest findRequest, - const ReadPreferenceSetting& readPref, - bool isExhaust); - virtual ~DBClientCursor(); /** @@ -170,11 +163,11 @@ public: } bool tailable() const { - return (_opts & QueryOption_CursorTailable) != 0; + return _findRequest && _findRequest->getTailable(); } bool tailableAwaitData() const { - return tailable() && (_opts & QueryOption_AwaitData); + return tailable() && _findRequest->getAwaitData(); } /** @@ -277,21 +270,6 @@ protected: Batch _batch; private: - DBClientCursor(DBClientBase* client, - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - long long cursorId, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int bs, - std::vector<BSONObj> initialBatch, - boost::optional<BSONObj> readConcernObj, - boost::optional<Timestamp> operationTime, - boost::optional<BSONObj> postBatchResumeToken = boost::none); - void dataReceived(const Message& reply) { bool retry; std::string lazyHost; @@ -312,13 +290,6 @@ private: Message assembleInit(); Message assembleGetMore(); - /** - * Constructs the initial find commmand request based on a legacy OP_QUERY-style description of - * the find operation. Only used if the caller constructed the 'DBClientCursor' with the legacy - * API. - */ - Message initFromLegacyRequest(); - DBClientBase* _client; std::string _originalHost; NamespaceStringOrUUID _nsOrUuid; @@ -336,32 +307,16 @@ private: bool _connectionHasPendingReplies = false; int _lastRequestId = 0; - int _batchSize; - int _limit = 0; + int _batchSize = 0; - // If the caller describes the find command being executed by this cursor as a - // 'FindCommandRequest', then that request object and the associated read preference are set - // here. Otherwise, if the caller uses the legacy OP_QUERY-inspired API, these members are - // default-initialized but never used. + // A description of the find command provided by the caller which is used to open the cursor. + // + // Has a value of boost::none if the caller constructed this cursor using a pre-existing cursor + // id. boost::optional<FindCommandRequest> _findRequest; - ReadPreferenceSetting _readPref; - // These data members are only used if the cursor was constructed using the legacy - // OP_QUERY-inspired API. If the cursor was constructed using the 'FindCommandRequest'-based - // API, these are initialized to their default values but never used. - BSONObj _filter; - client_deprecated::Query _querySettings; - int _nToSkip = 0; - const BSONObj* _fieldsToReturn = nullptr; - boost::optional<BSONObj> _readConcernObj; - - // This has the same meaning as the flags bit vector from the no-longer-supported OP_QUERY wire - // protocol message. However, it is initialized even if the caller constructed the cursor using - // the 'FindCommandRequest`-based API. - // - // We should eventually stop using the OP_QUERY flags bit vector in server code, since OP_QUERY - // is no longer supported. - int _opts; + ReadPreferenceSetting _readPref; + bool _isExhaust; Milliseconds _awaitDataTimeout = Milliseconds{0}; boost::optional<long long> _term; @@ -370,38 +325,4 @@ private: boost::optional<BSONObj> _postBatchResumeToken; }; -/** iterate over objects in current batch only - will not cause a network call - */ -class DBClientCursorBatchIterator { -public: - DBClientCursorBatchIterator(DBClientCursor& c) : _c(c), _n() {} - bool moreInCurrentBatch() { - return _c.moreInCurrentBatch(); - } - BSONObj nextSafe() { - massert(13383, "BatchIterator empty", moreInCurrentBatch()); - ++_n; - return _c.nextSafe(); - } - int n() const { - return _n; - } - // getNamespaceString() will return the NamespaceString returned by the 'find' command. - const NamespaceString& getNamespaceString() { - return _c.getNamespaceString(); - } - - long long getCursorId() const { - return _c.getCursorId(); - } - - boost::optional<BSONObj> getPostBatchResumeToken() const { - return _c.getPostBatchResumeToken(); - } - -private: - DBClientCursor& _c; - int _n; -}; - } // namespace mongo diff --git a/src/mongo/client/dbclient_mockcursor.cpp b/src/mongo/client/dbclient_mockcursor.cpp index 7082f55517e..0e33d4360d1 100644 --- a/src/mongo/client/dbclient_mockcursor.cpp +++ b/src/mongo/client/dbclient_mockcursor.cpp @@ -42,7 +42,7 @@ DBClientMockCursor::DBClientMockCursor(mongo::DBClientBase* client, const BSONArray& mockCollection, const bool provideResumeToken, unsigned long batchSize) - : mongo::DBClientCursor(client, NamespaceString(), 0, 0, 0), + : mongo::DBClientCursor(client, NamespaceString(), 0 /*cursorId*/, false /*isExhaust*/), _collectionArray(mockCollection), _iter(_collectionArray), _provideResumeToken(provideResumeToken), diff --git a/src/mongo/client/dbclient_mockcursor.h b/src/mongo/client/dbclient_mockcursor.h index 1138ee41286..7430a1aa3cb 100644 --- a/src/mongo/client/dbclient_mockcursor.h +++ b/src/mongo/client/dbclient_mockcursor.h @@ -35,9 +35,6 @@ namespace mongo { -// DBClientMockCursor supports only a small subset of DBClientCursor operations. -// It supports only iteration, including use of DBClientCursorBatchIterator. If a batchsize -// is given, iteration is broken up into multiple batches at batchSize boundaries. class DBClientMockCursor : public DBClientCursor { public: DBClientMockCursor(mongo::DBClientBase* client, diff --git a/src/mongo/client/dbclient_rs.cpp b/src/mongo/client/dbclient_rs.cpp index bf4259dd6ed..a48fe50a2fa 100644 --- a/src/mongo/client/dbclient_rs.cpp +++ b/src/mongo/client/dbclient_rs.cpp @@ -27,15 +27,13 @@ * it in the license file. */ - -#include "mongo/platform/basic.h" - #include "mongo/client/dbclient_rs.h" #include <memory> #include <utility> #include "mongo/bson/util/builder.h" +#include "mongo/client/client_deprecated.h" #include "mongo/client/connpool.h" #include "mongo/client/dbclient_cursor.h" #include "mongo/client/global_conn_pool.h" @@ -87,42 +85,6 @@ public: */ const size_t MAX_RETRY = 3; -/** - * Extracts the read preference settings from the query document. Note that this method - * assumes that the query is ok for secondaries so it defaults to - * ReadPreference::SecondaryPreferred when nothing is specified. Supports the following - * format: - * - * Format A (official format): - * { query: <actual query>, $readPreference: <read pref obj> } - * - * Format B (unofficial internal format from mongos): - * { <actual query>, $queryOptions: { $readPreference: <read pref obj> }} - * - * @param query the raw query document - * - * @return the read preference setting if a read preference exists, otherwise the default read - * preference of Primary_Only. If the tags field was not present, it will contain one - * empty tag document {} which matches any tag. - * - * @throws AssertionException if the read preference object is malformed - */ -std::unique_ptr<ReadPreferenceSetting> _extractReadPref( - const client_deprecated::Query& querySettings, int queryOptions) { - // Default read pref is primary only or secondary preferred with secondaryOK - const auto defaultReadPref = queryOptions & QueryOption_SecondaryOk - ? ReadPreference::SecondaryPreferred - : ReadPreference::PrimaryOnly; - - BSONObj readPrefContainingObj = querySettings.getFullSettingsDeprecated(); - if (auto elem = readPrefContainingObj["$queryOptions"]) { - // The readPreference is embedded in the $queryOptions field. - readPrefContainingObj = elem.Obj(); - } - return std::make_unique<ReadPreferenceSetting>(uassertStatusOK( - ReadPreferenceSetting::fromContainingBSON(readPrefContainingObj, defaultReadPref))); -} - } // namespace // -------------------------------- @@ -592,89 +554,6 @@ std::unique_ptr<DBClientCursor> DBClientReplicaSet::find(FindCommandRequest find return checkPrimary()->find(std::move(findRequest), readPref, exhaustMode); } -unique_ptr<DBClientCursor> DBClientReplicaSet::query_DEPRECATED( - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - boost::optional<BSONObj> readConcernObj) { - shared_ptr<ReadPreferenceSetting> readPref(_extractReadPref(querySettings, queryOptions)); - invariant(nsOrUuid.nss()); - const string ns = nsOrUuid.nss()->ns(); - if (_isSecondaryQuery(ns, filter, *readPref)) { - LOGV2_DEBUG(20133, - 3, - "dbclient_rs query using secondary or tagged node selection in {replicaSet}, " - "read pref is {readPref} " - "(primary : {primary}, lastTagged : {lastTagged})", - "dbclient_rs query using secondary or tagged node selection", - "replicaSet"_attr = _getMonitor()->getName(), - "readPref"_attr = readPref->toString(), - "primary"_attr = - (_primary.get() != nullptr ? _primary->getServerAddress() : "[not cached]"), - "lastTagged"_attr = (_lastSecondaryOkConn.get() != nullptr - ? _lastSecondaryOkConn->getServerAddress() - : "[not cached]")); - - string lastNodeErrMsg; - - for (size_t retry = 0; retry < MAX_RETRY; retry++) { - try { - DBClientConnection* conn = selectNodeUsingTags(readPref); - - if (conn == nullptr) { - break; - } - - unique_ptr<DBClientCursor> cursor = conn->query_DEPRECATED(nsOrUuid, - filter, - querySettings, - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj); - - return checkSecondaryQueryResult(std::move(cursor)); - } catch (const DBException& ex) { - const Status status = ex.toStatus(str::stream() << "can't query replica set node " - << _lastSecondaryOkHost); - lastNodeErrMsg = status.reason(); - _invalidateLastSecondaryOkCache(status); - } - } - - StringBuilder assertMsg; - assertMsg << "Failed to do query, no good nodes in " << _getMonitor()->getName(); - if (!lastNodeErrMsg.empty()) { - assertMsg << ", last error: " << lastNodeErrMsg; - } - - uasserted(16370, assertMsg.str()); - } - - LOGV2_DEBUG(20134, - 3, - "dbclient_rs query to primary node in {replicaSet}", - "dbclient_rs query to primary node", - "replicaSet"_attr = _getMonitor()->getName()); - - return checkPrimary()->query_DEPRECATED(nsOrUuid, - filter, - querySettings, - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj); -} - void DBClientReplicaSet::killCursor(const NamespaceString& ns, long long cursorID) { // we should never call killCursor on a replica set connection // since we don't know which server it belongs to @@ -819,70 +698,6 @@ void DBClientReplicaSet::say(Message& toSend, bool isRetry, string* actualServer if (!isRetry) _lastClient = nullptr; - const int lastOp = toSend.operation(); - - if (lastOp == dbQuery) { - // TODO: might be possible to do this faster by changing api - DbMessage dm(toSend); - QueryMessage qm(dm); - - shared_ptr<ReadPreferenceSetting> readPref(_extractReadPref( - client_deprecated::Query::fromBSONDeprecated(qm.query), qm.queryOptions)); - if (_isSecondaryQuery(qm.ns, qm.query, *readPref)) { - LOGV2_DEBUG(20141, - 3, - "dbclient_rs say using secondary or tagged node selection in {replicaSet}, " - "read pref is {readPref} " - "(primary : {primary}, lastTagged : {lastTagged})", - "dbclient_rs say using secondary or tagged node selection", - "replicaSet"_attr = _getMonitor()->getName(), - "readPref"_attr = readPref->toString(), - "primary"_attr = (_primary.get() != nullptr ? _primary->getServerAddress() - : "[not cached]"), - "lastTagged"_attr = (_lastSecondaryOkConn.get() != nullptr - ? _lastSecondaryOkConn->getServerAddress() - : "[not cached]")); - - string lastNodeErrMsg; - - for (size_t retry = 0; retry < MAX_RETRY; retry++) { - try { - DBClientConnection* conn = selectNodeUsingTags(readPref); - - if (conn == nullptr) { - break; - } - - if (actualServer != nullptr) { - *actualServer = conn->getServerAddress(); - } - - conn->say(toSend); - - _lastClient = conn; - } catch (const DBException& ex) { - const Status status = - ex.toStatus(str::stream() << "can't callLazy replica set node " - << _lastSecondaryOkHost.toString()); - lastNodeErrMsg = status.reason(); - _invalidateLastSecondaryOkCache(status); - - continue; - } - - return; - } - - StringBuilder assertMsg; - assertMsg << "Failed to call say, no good nodes in " << _getMonitor()->getName(); - if (!lastNodeErrMsg.empty()) { - assertMsg << ", last error: " << lastNodeErrMsg; - } - - uasserted(16380, assertMsg.str()); - } - } - LOGV2_DEBUG(20142, 3, "dbclient_rs say to primary node in {replicaSet}", @@ -984,60 +799,6 @@ bool DBClientReplicaSet::call(Message& toSend, Message& response, bool assertOk, string* actualServer) { - const char* ns = nullptr; - - if (toSend.operation() == dbQuery) { - // TODO: might be possible to do this faster by changing api - DbMessage dm(toSend); - QueryMessage qm(dm); - ns = qm.ns; - - shared_ptr<ReadPreferenceSetting> readPref(_extractReadPref( - client_deprecated::Query::fromBSONDeprecated(qm.query), qm.queryOptions)); - if (_isSecondaryQuery(ns, qm.query, *readPref)) { - LOGV2_DEBUG( - 20145, - 3, - "dbclient_rs call using secondary or tagged node selection in {replicaSet}, " - "read pref is {readPref} " - "(primary : {primary}, lastTagged : {lastTagged})", - "dbclient_rs call using secondary or tagged node selection", - "replicaSet"_attr = _getMonitor()->getName(), - "readPref"_attr = readPref->toString(), - "primary"_attr = - (_primary.get() != nullptr ? _primary->getServerAddress() : "[not cached]"), - "lastTagged"_attr = (_lastSecondaryOkConn.get() != nullptr - ? _lastSecondaryOkConn->getServerAddress() - : "[not cached]")); - - for (size_t retry = 0; retry < MAX_RETRY; retry++) { - try { - DBClientConnection* conn = selectNodeUsingTags(readPref); - - if (conn == nullptr) { - return false; - } - - if (actualServer != nullptr) { - *actualServer = conn->getServerAddress(); - } - - return conn->call(toSend, response, assertOk, nullptr); - } catch (const DBException& ex) { - if (actualServer) - *actualServer = ""; - - const Status status = ex.toStatus(); - _invalidateLastSecondaryOkCache(status.withContext( - str::stream() << "can't call replica set node " << _lastSecondaryOkHost)); - } - } - - // Was not able to successfully send after max retries - return false; - } - } - LOGV2_DEBUG(20146, 3, "dbclient_rs call to primary node in {replicaSet}", @@ -1051,20 +812,6 @@ bool DBClientReplicaSet::call(Message& toSend, if (!m->call(toSend, response, assertOk, nullptr)) return false; - if (ns) { - QueryResult::View res = response.singleData().view2ptr(); - if (res.getNReturned() == 1) { - BSONObj x(res.data()); - if (str::contains(ns, "$cmd")) { - if (isNotPrimaryErrorString(x["errmsg"])) - isNotPrimary(); - } else { - if (isNotPrimaryErrorString(getErrField(x))) - isNotPrimary(); - } - } - } - return true; } diff --git a/src/mongo/client/dbclient_rs.h b/src/mongo/client/dbclient_rs.h index ebab6854ffc..fa796039f2c 100644 --- a/src/mongo/client/dbclient_rs.h +++ b/src/mongo/client/dbclient_rs.h @@ -58,7 +58,6 @@ typedef std::shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr; class DBClientReplicaSet : public DBClientBase { public: using DBClientBase::find; - using DBClientBase::query_DEPRECATED; /** Call connect() after constructing. autoReconnect is always on for DBClientReplicaSet * connections. */ @@ -93,18 +92,6 @@ public: const ReadPreferenceSetting& readPref, ExhaustMode exhaustMode) override; - /** throws userassertion "no primary found" */ - std::unique_ptr<DBClientCursor> query_DEPRECATED( - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const client_deprecated::Query& querySettings, - int limit = 0, - int nToSkip = 0, - const BSONObj* fieldsToReturn = nullptr, - int queryOptions = 0, - int batchSize = 0, - boost::optional<BSONObj> readConcernObj = boost::none) override; - void insert(const std::string& ns, BSONObj obj, bool ordered = true, diff --git a/src/mongo/client/dbclient_rs_test.cpp b/src/mongo/client/dbclient_rs_test.cpp index 2bbbc78858a..7053d8fe623 100644 --- a/src/mongo/client/dbclient_rs_test.cpp +++ b/src/mongo/client/dbclient_rs_test.cpp @@ -152,57 +152,16 @@ void assertNodeSelected(MockReplicaSet* replSet, ReadPreference rp, StringData h assertOneOfNodesSelected(replSet, rp, std::vector<std::string>{host.toString()}); } -/** - * Runs a find operation against 'replConn' using both the modern 'find()' API and the deprecated - * API. In both cases, verifies the results by passing the resulting cursor to 'assertionFunc'. - * - * The operation is a simple find command against the given NamespaceString with no arguments other - * than 'readPref'. - */ -void assertWithBothQueryApis(DBClientReplicaSet& replConn, - const NamespaceString& nss, - ReadPreference readPref, - std::function<void(std::unique_ptr<DBClientCursor>)> assertionFunc) { - std::unique_ptr<DBClientCursor> cursor = - replConn.find(FindCommandRequest{nss}, ReadPreferenceSetting{readPref}); - assertionFunc(std::move(cursor)); - - client_deprecated::Query readPrefHolder; - readPrefHolder.readPref(readPref, BSONArray{}); - cursor = replConn.query_DEPRECATED(nss, BSONObj{}, readPrefHolder); - assertionFunc(std::move(cursor)); -} - -/** - * Runs a find operation against 'replConn' using both the modern 'find()' API and the deprecated - * API. In both cases, verifies that the find operation throws an exception. - * - * The operation is a simple find command against the given NamespaceString with no arguments other - * than 'readPref'. - */ -void assertBothQueryApisThrow(DBClientReplicaSet& replConn, - const NamespaceString& nss, - ReadPreference readPref) { - ASSERT_THROWS(replConn.find(FindCommandRequest{nss}, ReadPreferenceSetting{readPref}), - AssertionException); - - client_deprecated::Query readPrefHolder; - readPrefHolder.readPref(readPref, BSONArray{}); - ASSERT_THROWS(replConn.query_DEPRECATED(nss, BSONObj{}, readPrefHolder), AssertionException); -} - TEST_F(BasicRS, QueryPrimary) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::PrimaryOnly, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryOnly}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); } TEST_F(BasicRS, CommandPrimary) { @@ -214,14 +173,11 @@ TEST_F(BasicRS, QuerySecondaryOnly) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::SecondaryOnly, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), - doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::SecondaryOnly}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); } TEST_F(BasicRS, CommandSecondaryOnly) { @@ -234,13 +190,11 @@ TEST_F(BasicRS, QueryPrimaryPreferred) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::PrimaryPreferred, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryPreferred}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); } TEST_F(BasicRS, CommandPrimaryPreferred) { @@ -252,14 +206,11 @@ TEST_F(BasicRS, QuerySecondaryPreferred) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::SecondaryPreferred, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), - doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = replConn.find(std::move(findCmd), + ReadPreferenceSetting{ReadPreference::SecondaryPreferred}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); } TEST_F(BasicRS, CommandSecondaryPreferred) { @@ -319,7 +270,10 @@ TEST_F(AllNodesDown, QueryPrimary) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow(replConn, NamespaceString{IdentityNS}, ReadPreference::PrimaryOnly); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS( + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryOnly}), + AssertionException); } TEST_F(AllNodesDown, CommandPrimary) { @@ -330,7 +284,10 @@ TEST_F(AllNodesDown, QuerySecondaryOnly) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow(replConn, NamespaceString{IdentityNS}, ReadPreference::SecondaryOnly); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS( + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::SecondaryOnly}), + AssertionException); } TEST_F(AllNodesDown, CommandSecondaryOnly) { @@ -341,8 +298,10 @@ TEST_F(AllNodesDown, QueryPrimaryPreferred) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow( - replConn, NamespaceString{IdentityNS}, ReadPreference::PrimaryPreferred); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS( + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryPreferred}), + AssertionException); } TEST_F(AllNodesDown, CommandPrimaryPreferred) { @@ -353,8 +312,10 @@ TEST_F(AllNodesDown, QuerySecondaryPreferred) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow( - replConn, NamespaceString{IdentityNS}, ReadPreference::SecondaryPreferred); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS(replConn.find(std::move(findCmd), + ReadPreferenceSetting{ReadPreference::SecondaryPreferred}), + AssertionException); } TEST_F(AllNodesDown, CommandSecondaryPreferred) { @@ -365,7 +326,9 @@ TEST_F(AllNodesDown, QueryNearest) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow(replConn, NamespaceString{IdentityNS}, ReadPreference::Nearest); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS(replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::Nearest}), + AssertionException); } TEST_F(AllNodesDown, CommandNearest) { @@ -409,7 +372,10 @@ TEST_F(PrimaryDown, QueryPrimary) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow(replConn, NamespaceString{IdentityNS}, ReadPreference::PrimaryOnly); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS( + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryOnly}), + AssertionException); } TEST_F(PrimaryDown, CommandPrimary) { @@ -421,14 +387,11 @@ TEST_F(PrimaryDown, QuerySecondaryOnly) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::SecondaryOnly, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), - doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::SecondaryOnly}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); } TEST_F(PrimaryDown, CommandSecondaryOnly) { @@ -441,14 +404,11 @@ TEST_F(PrimaryDown, QueryPrimaryPreferred) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::PrimaryPreferred, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), - doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryPreferred}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); } TEST_F(PrimaryDown, CommandPrimaryPreferred) { @@ -461,14 +421,11 @@ TEST_F(PrimaryDown, QuerySecondaryPreferred) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::SecondaryPreferred, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), - doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = replConn.find(std::move(findCmd), + ReadPreferenceSetting{ReadPreference::SecondaryPreferred}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); } TEST_F(PrimaryDown, CommandSecondaryPreferred) { @@ -480,14 +437,10 @@ TEST_F(PrimaryDown, Nearest) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::Nearest, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), - doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::Nearest}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); } /** @@ -529,13 +482,11 @@ TEST_F(SecondaryDown, QueryPrimary) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::PrimaryOnly, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryOnly}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); } TEST_F(SecondaryDown, CommandPrimary) { @@ -546,7 +497,10 @@ TEST_F(SecondaryDown, QuerySecondaryOnly) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertBothQueryApisThrow(replConn, NamespaceString{IdentityNS}, ReadPreference::SecondaryOnly); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + ASSERT_THROWS( + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::SecondaryOnly}), + AssertionException); } TEST_F(SecondaryDown, CommandSecondaryOnly) { @@ -558,13 +512,11 @@ TEST_F(SecondaryDown, QueryPrimaryPreferred) { DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); // Note: IdentityNS contains the name of the server. - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::PrimaryPreferred, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = + replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::PrimaryPreferred}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); } TEST_F(SecondaryDown, CommandPrimaryPreferred) { @@ -575,13 +527,11 @@ TEST_F(SecondaryDown, QuerySecondaryPreferred) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::SecondaryPreferred, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = replConn.find(std::move(findCmd), + ReadPreferenceSetting{ReadPreference::SecondaryPreferred}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); } TEST_F(SecondaryDown, CommandSecondaryPreferred) { @@ -592,13 +542,10 @@ TEST_F(SecondaryDown, QueryNearest) { MockReplicaSet* replSet = getReplSet(); DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts(), StringData()); - assertWithBothQueryApis(replConn, - NamespaceString{IdentityNS}, - ReadPreference::Nearest, - [&](std::unique_ptr<DBClientCursor> cursor) { - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - }); + FindCommandRequest findCmd{NamespaceString{IdentityNS}}; + auto cursor = replConn.find(std::move(findCmd), ReadPreferenceSetting{ReadPreference::Nearest}); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); } TEST_F(SecondaryDown, CommandNearest) { |