feat(mongodb): support db.collection.renameCollection()

This commit is contained in:
Loc Nguyen authored and GitHub committed 2026-09-18 14:12:39 +08:00
1 parent 392138f59a
commit 2db28fc236
16 files changed
+239 -17

No files matched your search

@@ -11,6 +11,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mongodb.ConnectionString;
import com.mongodb.MongoBulkWriteException;
import com.mongodb.MongoNamespace;
import com.mongodb.MongoCredential;
import com.mongodb.MongoClientSettings;
import com.mongodb.ServerAddress;
@@ -1166,6 +1167,32 @@ public final class MongoAgent {
return result;
}
private static Object renameCollection(JsonObject params) {
MongoClient c = requireClient();
String database = params.get("database").getAsString();
String collection = params.get("collection").getAsString();
String newName = params.get("new_name").getAsString();
requireRenameableCollectionNames(collection, newName);
c.getDatabase(database).getCollection(collection).renameCollection(new MongoNamespace(database, newName));
return Collections.singletonMap("ok", true);
}
/** Mirrors the native driver's checks so both paths reject the same names before asking the server. */
static void requireRenameableCollectionNames(String collection, String newName) {
if (collection == null || collection.isBlank()) {
throw new IllegalArgumentException("Collection name is required");
}
if (newName == null || newName.isBlank()) {
throw new IllegalArgumentException("New collection name is required");
}
if (collection.equals(newName)) {
throw new IllegalArgumentException("New collection name must differ from the current name");
}
if (collection.startsWith("system.") || newName.startsWith("system.")) {
throw new IllegalArgumentException("System collections cannot be renamed");
}
}
private static Object dropCollection(JsonObject params) {
MongoClient c = requireClient();
String database = params.get("database").getAsString();
@@ -2280,6 +2307,7 @@ public final class MongoAgent {
case AgentProtocol.MONGO_METHOD_UPDATE_DOCUMENTS -> updateDocuments(params);
case AgentProtocol.MONGO_METHOD_REPLACE_DOCUMENT -> replaceDocument(params);
case AgentProtocol.MONGO_METHOD_BULK_WRITE -> bulkWrite(params);
case AgentProtocol.MONGO_METHOD_RENAME_COLLECTION -> renameCollection(params);
case AgentProtocol.MONGO_METHOD_DELETE_DOCUMENT -> deleteDocument(params);
case AgentProtocol.MONGO_METHOD_DELETE_DOCUMENTS -> deleteDocuments(params);
case AgentProtocol.MONGO_METHOD_RUN_COMMAND -> runCommand(params);
@@ -1387,6 +1387,34 @@ class MongoAgentTest {
}
}
@Test
void renameCollectionMethodIsRecognizedOverJsonRpc() {
String response = MongoAgent.handleRequest(
"{\"jsonrpc\":\"2.0\",\"id\":13,\"method\":\"rename_collection\","
+ "\"params\":{\"database\":\"app\",\"collection\":\"orders\",\"new_name\":\"orders_2024\"}}");
JsonObject json = JsonParser.parseString(response).getAsJsonObject();
assertEquals(13, json.get("id").getAsInt());
assertEquals("Not connected", json.getAsJsonObject("error").get("message").getAsString());
assertTrue(AgentProtocol.MONGO_LEGACY_METHODS.contains(AgentProtocol.MONGO_METHOD_RENAME_COLLECTION));
assertTrue(AgentProtocol.MONGO_LEGACY_CAPABILITIES.contains(AgentProtocol.CAPABILITY_MONGO_RENAME_COLLECTION));
}
@Test
void rejectsUnrenameableCollectionNames() {
MongoAgent.requireRenameableCollectionNames("orders", "orders_2024");
for (String[] item : new String[][] {
{"", "x", "Collection name is required"},
{"orders", "", "New collection name is required"},
{"orders", "orders", "must differ"},
{"system.users", "x", "System collections cannot be renamed"},
{"orders", "system.x", "System collections cannot be renamed"},
}) {
IllegalArgumentException error = assertThrows(IllegalArgumentException.class, () -> MongoAgent.requireRenameableCollectionNames(item[0], item[1]));
assertTrue(error.getMessage().contains(item[2]), error.getMessage());
}
}
@Test
void parsesBulkWriteOptions() {
assertTrue(MongoAgent.bulkWriteOptionsForWrite(null).isOrdered());