Skip to content

Commit ea175f9

Browse files
committed
feat(MongoDB): add OP_MSG command constants and index-drop helpers
Add curated command-name constants (dropIndexes, listCollections, bulkWrite, collMod, ...) with a new Authentication category, Database::dropIndex()/ dropAllIndexes() helpers mirroring createIndex(), mark collStats deprecated, and replace the hardcoded SCRAM command literals with constants.
1 parent 3a3e8e5 commit ea175f9

7 files changed

Lines changed: 187 additions & 8 deletions

File tree

MongoDB/include/Poco/MongoDB/Database.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,30 @@ class MongoDB_API Database
145145
///
146146
/// The document returned is the createIndexes response body.
147147

148+
Document::Ptr dropIndex(
149+
Connection& connection,
150+
const std::string& collection,
151+
const std::string& indexName);
152+
/// Drops the index with the given name from the collection. Passing "*"
153+
/// drops all indexes except the _id index; prefer dropAllIndexes() for
154+
/// that. The document returned is the dropIndexes response body.
155+
/// (new wire protocol)
156+
157+
Document::Ptr dropIndex(
158+
Connection& connection,
159+
const std::string& collection,
160+
const IndexedFields& indexedFields);
161+
/// Drops the index matching the given key specification (the same
162+
/// IndexedFields form accepted by createIndex). The document returned
163+
/// is the dropIndexes response body. (new wire protocol)
164+
165+
Document::Ptr dropAllIndexes(
166+
Connection& connection,
167+
const std::string& collection);
168+
/// Drops all indexes on the collection except the _id index (and, on a
169+
/// sharded collection, the shard key index). The document returned is
170+
/// the dropIndexes response body. (new wire protocol)
171+
148172
static const std::string AUTH_SCRAM_SHA1;
149173
/// SCRAM-SHA-1 authentication mechanism (MongoDB 3.0+).
150174

MongoDB/include/Poco/MongoDB/OpMsgMessage.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class MongoDB_API OpMsgMessage: public Message
4646
static const std::string CMD_UPDATE;
4747
static const std::string CMD_FIND;
4848
static const std::string CMD_FIND_AND_MODIFY;
49+
static const std::string CMD_BULK_WRITE;
50+
/// Since MongoDB 8.0. Name constant only: the type-1 payload sections
51+
/// (ops/nsInfo) are not wired into commandIdentifier(), so callers must
52+
/// build the command body manually.
4953

5054
// Aggregation
5155
static const std::string CMD_AGGREGATE;
@@ -63,17 +67,34 @@ class MongoDB_API OpMsgMessage: public Message
6367

6468
static const std::string CMD_CREATE;
6569
static const std::string CMD_CREATE_INDEXES;
70+
static const std::string CMD_DROP_INDEXES;
6671
static const std::string CMD_DROP;
6772
static const std::string CMD_DROP_DATABASE;
6873
static const std::string CMD_KILL_CURSORS;
6974
static const std::string CMD_LIST_DATABASES;
7075
static const std::string CMD_LIST_INDEXES;
76+
static const std::string CMD_LIST_COLLECTIONS;
77+
static const std::string CMD_RENAME_COLLECTION;
78+
static const std::string CMD_COLL_MOD;
79+
static const std::string CMD_GET_PARAMETER;
80+
static const std::string CMD_SET_PARAMETER;
7181

7282
// Diagnostic
7383
static const std::string CMD_BUILD_INFO;
84+
POCO_DEPRECATED("Deprecated since MongoDB 6.2; use the $collStats aggregation stage instead.")
7485
static const std::string CMD_COLL_STATS;
7586
static const std::string CMD_DB_STATS;
7687
static const std::string CMD_HOST_INFO;
88+
static const std::string CMD_PING;
89+
static const std::string CMD_SERVER_STATUS;
90+
static const std::string CMD_CONNECTION_STATUS;
91+
static const std::string CMD_EXPLAIN;
92+
static const std::string CMD_LIST_COMMANDS;
93+
static const std::string CMD_GET_LOG;
94+
95+
// Authentication
96+
static const std::string CMD_SASL_START;
97+
static const std::string CMD_SASL_CONTINUE;
7798

7899

79100
enum Flags : UInt32

MongoDB/src/Database.cpp

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ namespace
150150
std::string clientFirstMsg = Poco::format("n=%s,r=%s", username, clientNonce);
151151

152152
Poco::SharedPtr<OpMsgMessage> pCommand = db.createOpMsgMessage("$cmd");
153-
pCommand->setCommandName("saslStart");
153+
pCommand->setCommandName(OpMsgMessage::CMD_SASL_START);
154154
pCommand->body()
155155
.add<std::string>("mechanism", mechanism)
156156
.add<Binary::Ptr>("payload", new Binary(Poco::format("n,,%s", clientFirstMsg)))
@@ -214,7 +214,7 @@ namespace
214214
std::string clientFinal = Poco::format("%s,p=%s", clientFinalNoProof, encodeBase64(clientProof));
215215

216216
pCommand = db.createOpMsgMessage("$cmd");
217-
pCommand->setCommandName("saslContinue");
217+
pCommand->setCommandName(OpMsgMessage::CMD_SASL_CONTINUE);
218218
pCommand->body()
219219
.add<Poco::Int32>("conversationId", conversationId)
220220
.add<Binary::Ptr>("payload", new Binary(clientFinal));
@@ -247,14 +247,25 @@ namespace
247247
throw Poco::ProtocolException("server signature verification failed");
248248

249249
pCommand = db.createOpMsgMessage("$cmd");
250-
pCommand->setCommandName("saslContinue");
250+
pCommand->setCommandName(OpMsgMessage::CMD_SASL_CONTINUE);
251251
pCommand->body()
252252
.add<Poco::Int32>("conversationId", conversationId)
253253
.add<Binary::Ptr>("payload", new Binary);
254254

255255
connection.sendRequest(*pCommand, response);
256256
return response.responseOk();
257257
}
258+
259+
260+
Document::Ptr keysFromIndexedFields(const Database::IndexedFields& indexedFields)
261+
{
262+
Document::Ptr keys = new Document();
263+
for (const auto& [name, ascending]: indexedFields)
264+
{
265+
keys->add(name, ascending ? 1 : -1);
266+
}
267+
return keys;
268+
}
258269
} // namespace
259270

260271

@@ -407,11 +418,7 @@ Poco::MongoDB::Document::Ptr Database::createIndex(
407418
{
408419
// https://www.mongodb.com/docs/manual/reference/command/createIndexes/
409420

410-
MongoDB::Document::Ptr keys = new MongoDB::Document();
411-
412-
for (const auto& [name, ascending]: indexedFields) {
413-
keys->add(name, ascending ? 1 : -1);
414-
}
421+
MongoDB::Document::Ptr keys = keysFromIndexedFields(indexedFields);
415422

416423
MongoDB::Document::Ptr index = new MongoDB::Document();
417424
index->add("key"s, keys);
@@ -467,4 +474,48 @@ Poco::MongoDB::Document::Ptr Database::createIndex(
467474
}
468475

469476

477+
Poco::MongoDB::Document::Ptr Database::dropIndex(
478+
Connection& connection,
479+
const std::string& collection,
480+
const std::string& indexName)
481+
{
482+
// https://www.mongodb.com/docs/manual/reference/command/dropIndexes/
483+
484+
auto request = createOpMsgMessage(collection);
485+
request->setCommandName(OpMsgMessage::CMD_DROP_INDEXES);
486+
request->body().add("index"s, indexName);
487+
488+
OpMsgMessage response;
489+
connection.sendRequest(*request, response);
490+
491+
return new MongoDB::Document(response.body());
492+
}
493+
494+
495+
Poco::MongoDB::Document::Ptr Database::dropIndex(
496+
Connection& connection,
497+
const std::string& collection,
498+
const IndexedFields& indexedFields)
499+
{
500+
// https://www.mongodb.com/docs/manual/reference/command/dropIndexes/
501+
502+
auto request = createOpMsgMessage(collection);
503+
request->setCommandName(OpMsgMessage::CMD_DROP_INDEXES);
504+
request->body().add("index"s, keysFromIndexedFields(indexedFields));
505+
506+
OpMsgMessage response;
507+
connection.sendRequest(*request, response);
508+
509+
return new MongoDB::Document(response.body());
510+
}
511+
512+
513+
Poco::MongoDB::Document::Ptr Database::dropAllIndexes(
514+
Connection& connection,
515+
const std::string& collection)
516+
{
517+
return dropIndex(connection, collection, "*"s);
518+
}
519+
520+
470521
} // namespace Poco::MongoDB

MongoDB/src/OpMsgMessage.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const std::string OpMsgMessage::CMD_DELETE { "delete"s };
3232
const std::string OpMsgMessage::CMD_UPDATE { "update"s };
3333
const std::string OpMsgMessage::CMD_FIND { "find"s };
3434
const std::string OpMsgMessage::CMD_FIND_AND_MODIFY { "findAndModify"s };
35+
const std::string OpMsgMessage::CMD_BULK_WRITE { "bulkWrite"s };
3536
const std::string OpMsgMessage::CMD_GET_MORE { "getMore"s };
3637

3738
// Aggregation
@@ -47,17 +48,33 @@ const std::string OpMsgMessage::CMD_REPL_SET_GET_CONFIG { "replSetGetConfig"s };
4748

4849
const std::string OpMsgMessage::CMD_CREATE { "create"s };
4950
const std::string OpMsgMessage::CMD_CREATE_INDEXES { "createIndexes"s };
51+
const std::string OpMsgMessage::CMD_DROP_INDEXES { "dropIndexes"s };
5052
const std::string OpMsgMessage::CMD_DROP { "drop"s };
5153
const std::string OpMsgMessage::CMD_DROP_DATABASE { "dropDatabase"s };
5254
const std::string OpMsgMessage::CMD_KILL_CURSORS { "killCursors"s };
5355
const std::string OpMsgMessage::CMD_LIST_DATABASES { "listDatabases"s };
5456
const std::string OpMsgMessage::CMD_LIST_INDEXES { "listIndexes"s };
57+
const std::string OpMsgMessage::CMD_LIST_COLLECTIONS { "listCollections"s };
58+
const std::string OpMsgMessage::CMD_RENAME_COLLECTION { "renameCollection"s };
59+
const std::string OpMsgMessage::CMD_COLL_MOD { "collMod"s };
60+
const std::string OpMsgMessage::CMD_GET_PARAMETER { "getParameter"s };
61+
const std::string OpMsgMessage::CMD_SET_PARAMETER { "setParameter"s };
5562

5663
// Diagnostic
5764
const std::string OpMsgMessage::CMD_BUILD_INFO { "buildInfo"s };
5865
const std::string OpMsgMessage::CMD_COLL_STATS { "collStats"s };
5966
const std::string OpMsgMessage::CMD_DB_STATS { "dbStats"s };
6067
const std::string OpMsgMessage::CMD_HOST_INFO { "hostInfo"s };
68+
const std::string OpMsgMessage::CMD_PING { "ping"s };
69+
const std::string OpMsgMessage::CMD_SERVER_STATUS { "serverStatus"s };
70+
const std::string OpMsgMessage::CMD_CONNECTION_STATUS { "connectionStatus"s };
71+
const std::string OpMsgMessage::CMD_EXPLAIN { "explain"s };
72+
const std::string OpMsgMessage::CMD_LIST_COMMANDS { "listCommands"s };
73+
const std::string OpMsgMessage::CMD_GET_LOG { "getLog"s };
74+
75+
// Authentication
76+
const std::string OpMsgMessage::CMD_SASL_START { "saslStart"s };
77+
const std::string OpMsgMessage::CMD_SASL_CONTINUE { "saslContinue"s };
6178

6279

6380
static const std::string& commandIdentifier(const std::string& command);

MongoDB/testsuite/src/MongoDBTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ CppUnit::Test* MongoDBTest::suite()
224224

225225
CppUnit_addTest(pSuite, MongoDBTest, testDBCount);
226226

227+
CppUnit_addTest(pSuite, MongoDBTest, testOpCmdDropIndex);
228+
227229
CppUnit_addTest(pSuite, MongoDBTest, testOpCmdDropDatabase);
228230
}
229231

MongoDB/testsuite/src/MongoDBTest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class MongoDBTest: public CppUnit::TestCase
4747
void testOpCmdUnaknowledgedInsert();
4848
void testOpCmdConnectionPool();
4949
void testOpCmdDropDatabase();
50+
void testOpCmdDropIndex();
5051
void testDBCount();
5152

5253
static CppUnit::Test* suite();

MongoDB/testsuite/src/MongoDBTestOpMsg.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <iostream>
2424
#include <sstream>
25+
#include <tuple>
2526

2627

2728
using namespace Poco::MongoDB;
@@ -454,4 +455,66 @@ void MongoDBTest::testOpCmdDropDatabase()
454455
}
455456

456457

458+
void MongoDBTest::testOpCmdDropIndex()
459+
{
460+
Database db("team");
461+
462+
// Start from a clean collection.
463+
Poco::SharedPtr<OpMsgMessage> request = db.createOpMsgMessage("players");
464+
OpMsgMessage response;
465+
request->setCommandName(OpMsgMessage::CMD_DROP);
466+
_mongo->sendRequest(*request, response); // Ignore result: the collection may not exist yet.
467+
468+
// Insert one document so the collection exists.
469+
request = db.createOpMsgMessage("players");
470+
request->setCommandName(OpMsgMessage::CMD_INSERT);
471+
Document::Ptr player = new Document();
472+
player->add("lastname"s, "Braem"s).add("firstname"s, "Franky"s);
473+
request->documents().push_back(player);
474+
_mongo->sendRequest(*request, response);
475+
assertTrue(response.responseOk());
476+
477+
Database::IndexedFields lastnameField;
478+
lastnameField.push_back(std::make_tuple("lastname", true));
479+
Database::IndexedFields firstnameField;
480+
firstnameField.push_back(std::make_tuple("firstname", true));
481+
482+
// 1. Drop by name.
483+
Document::Ptr result = db.createIndex(*_mongo, "players", lastnameField, "lastname_1");
484+
assertTrue(result->getInteger("ok") == 1);
485+
result = db.dropIndex(*_mongo, "players", "lastname_1");
486+
assertTrue(result->getInteger("ok") == 1);
487+
488+
// 2. Drop by key specification.
489+
result = db.createIndex(*_mongo, "players", firstnameField, "firstname_1");
490+
assertTrue(result->getInteger("ok") == 1);
491+
result = db.dropIndex(*_mongo, "players", firstnameField);
492+
assertTrue(result->getInteger("ok") == 1);
493+
494+
// 3. Drop all indexes: create two, then drop them at once.
495+
db.createIndex(*_mongo, "players", lastnameField, "lastname_1");
496+
db.createIndex(*_mongo, "players", firstnameField, "firstname_1");
497+
result = db.dropAllIndexes(*_mongo, "players");
498+
assertTrue(result->getInteger("ok") == 1);
499+
500+
// Only the _id index remains.
501+
Poco::SharedPtr<OpMsgCursor> cursor = db.createOpMsgCursor("players");
502+
cursor->query().setCommandName(OpMsgMessage::CMD_LIST_INDEXES);
503+
auto listResponse = cursor->next(*_mongo);
504+
int indexCount = 0;
505+
while (true)
506+
{
507+
indexCount += static_cast<int>(listResponse.documents().size());
508+
if (cursor->cursorID() == 0) break;
509+
listResponse = cursor->next(*_mongo);
510+
}
511+
assertEquals (1, indexCount);
512+
513+
// Cleanup.
514+
request = db.createOpMsgMessage("players");
515+
request->setCommandName(OpMsgMessage::CMD_DROP);
516+
_mongo->sendRequest(*request, response);
517+
}
518+
519+
457520

0 commit comments

Comments
 (0)