summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands.h
diff options
context:
space:
mode:
authorMoustafa Maher <m.maher@10gen.com>2021-01-15 01:52:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-01-20 00:16:26 +0000
commit4b51940f6e36878261dc18b8867c27f44c4975a9 (patch)
tree3565b85c42b595567f21303af1ac3658c6fd0d07 /src/mongo/db/commands.h
parentf75145df24d968c4c8b659f6528f7e86da02aa46 (diff)
downloadmongo-4b51940f6e36878261dc18b8867c27f44c4975a9.tar.gz
SERVER-52547 Avoid reparsing the command object multiple times
Diffstat (limited to 'src/mongo/db/commands.h')
-rw-r--r--src/mongo/db/commands.h49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index dc1a53f2e8f..5dcd2d94b77 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -958,10 +958,11 @@ public:
*
*/
template <typename Derived>
-class BasicCommandWithRequestParser : public BasicCommand {
-public:
+class BasicCommandWithRequestParser : public BasicCommandWithReplyBuilderInterface {
+protected:
// Commands that only have a single name don't need to define any constructors.
- BasicCommandWithRequestParser() : BasicCommand(Derived::Request::kCommandName) {}
+ BasicCommandWithRequestParser()
+ : BasicCommandWithReplyBuilderInterface(Derived::Request::kCommandName) {}
bool runWithReplyBuilder(OperationContext* opCtx,
const std::string& db,
@@ -970,21 +971,51 @@ public:
auto result = replyBuilder->getBodyBuilder();
// To enforce API versioning
- using RequestType = typename Derived::Request;
- auto request = RequestType::parse(
- IDLParserErrorContext(Derived::Request::kCommandName,
- APIParameters::get(opCtx).getAPIStrict().value_or(false)),
- cmdObj);
+ auto requestParser = RequestParser(opCtx, cmdObj);
- auto cmdDone = run(opCtx, db, request.toBSON(cmdObj), result);
+ auto cmdDone = runWithRequestParser(opCtx, db, cmdObj, requestParser, result);
validateResult(result.asTempObj());
return cmdDone;
}
+ class RequestParser;
+
+ /**
+ * Runs the given command. Returns true upon success.
+ */
+ virtual bool runWithRequestParser(OperationContext* opCtx,
+ const std::string& db,
+ const BSONObj& cmdObj,
+ const RequestParser& requestParser,
+ BSONObjBuilder& result) = 0;
+
// Custom logic to validate results to enforce API versioning.
virtual void validateResult(const BSONObj& resultObj) = 0;
};
+template <typename Derived>
+class BasicCommandWithRequestParser<Derived>::RequestParser {
+public:
+ using RequestType = typename Derived::Request;
+
+ RequestParser(OperationContext* opCtx, const BSONObj& cmdObj)
+ : _request{_parseRequest(opCtx, cmdObj)} {}
+
+ const RequestType& request() const {
+ return _request;
+ }
+
+private:
+ static RequestType _parseRequest(OperationContext* opCtx, const BSONObj& cmdObj) {
+ return RequestType::parse(
+ IDLParserErrorContext(RequestType::kCommandName,
+ APIParameters::get(opCtx).getAPIStrict().value_or(false)),
+ cmdObj);
+ }
+
+ RequestType _request;
+};
+
/**
* Deprecated. Do not add new subclasses.
*/