From 88ccb8189d3850a2e11d86a0dfe0b5418ce66e55 Mon Sep 17 00:00:00 2001 From: Md Rahadul Islam Date: Sun, 30 Aug 2026 20:45:16 +0600 Subject: [PATCH 1/2] fix(mongodb): implement dropObjectStatement for collection drops via UI --- .../MongoDBDriverPlugin/MongoDBPluginDriver.swift | 7 +++++++ .../Core/MongoDB/MongoShellParserTests.swift | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift index 478462791..0f7001441 100644 --- a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift +++ b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift @@ -634,6 +634,13 @@ final class MongoDBPluginDriver: PluginDatabaseDriver, @unchecked Sendable { ) } + /// A collection drop is a shell statement, not a SQL one: `db..drop()`. The + /// app-level fallback would emit `DROP TABLE `, which the Mongo shell parser rejects. + /// Mongo has no schemas or cascade, so both are ignored. + func dropObjectStatement(name: String, objectType: String, schema: String?, cascade: Bool) -> String? { + "db.\(name).drop()" + } + func dropDatabase(name: String) async throws { guard let conn = mongoConnection else { throw MongoDBPluginError.notConnected diff --git a/TableProTests/Core/MongoDB/MongoShellParserTests.swift b/TableProTests/Core/MongoDB/MongoShellParserTests.swift index 96f4e58c3..b7249adea 100644 --- a/TableProTests/Core/MongoDB/MongoShellParserTests.swift +++ b/TableProTests/Core/MongoDB/MongoShellParserTests.swift @@ -312,6 +312,19 @@ struct MongoShellParserTests { } } + @Test("SQL DROP TABLE fallback is rejected for MongoDB collections") + func testDropTableFallbackIsRejected() { + // The sidebar's drop used to fall through to the SQL fallback and emit + // `DROP TABLE ""`, which the Mongo shell parser rejects. Dropping a + // collection must go through `db..drop()` instead. + do { + _ = try MongoShellParser.parse("DROP TABLE \"users\"") + Issue.record("Expected the SQL DROP TABLE fallback to be rejected") + } catch { + // Any parse failure is the point: a Mongo connection must never send SQL. + } + } + @Test("runCommand") func testRunCommand() throws { let op = try MongoShellParser.parse("db.runCommand({\"ping\": 1})") From 097ae141dc639c75643d0fcb3e633ac5bd092b76 Mon Sep 17 00:00:00 2001 From: Md Rahadul Islam Date: Sun, 30 Aug 2026 21:28:10 +0600 Subject: [PATCH 2/2] fix(mongodb): quote and escape collection name in dropObjectStatement --- .../MongoDBDriverPlugin/MongoDBPluginDriver.swift | 6 +++--- .../Core/MongoDB/MongoShellParserTests.swift | 12 +++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift index 0f7001441..211e691a6 100644 --- a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift +++ b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift @@ -634,11 +634,11 @@ final class MongoDBPluginDriver: PluginDatabaseDriver, @unchecked Sendable { ) } - /// A collection drop is a shell statement, not a SQL one: `db..drop()`. The - /// app-level fallback would emit `DROP TABLE `, which the Mongo shell parser rejects. + /// A collection drop is a shell statement, not a SQL one: `db.getCollection("").drop()`. + /// The app-level fallback would emit `DROP TABLE `, which the Mongo shell parser rejects. /// Mongo has no schemas or cascade, so both are ignored. func dropObjectStatement(name: String, objectType: String, schema: String?, cascade: Bool) -> String? { - "db.\(name).drop()" + "db.getCollection(\"\(escapeJsonString(name))\").drop()" } func dropDatabase(name: String) async throws { diff --git a/TableProTests/Core/MongoDB/MongoShellParserTests.swift b/TableProTests/Core/MongoDB/MongoShellParserTests.swift index b7249adea..1448ec4fa 100644 --- a/TableProTests/Core/MongoDB/MongoShellParserTests.swift +++ b/TableProTests/Core/MongoDB/MongoShellParserTests.swift @@ -312,11 +312,21 @@ struct MongoShellParserTests { } } + @Test("getCollection with drop") + func testGetCollectionDrop() throws { + let op = try MongoShellParser.parse("db.getCollection(\"audit-logs.2026\").drop()") + if case .drop(let collection) = op { + #expect(collection == "audit-logs.2026") + } else { + Issue.record("Expected .drop operation") + } + } + @Test("SQL DROP TABLE fallback is rejected for MongoDB collections") func testDropTableFallbackIsRejected() { // The sidebar's drop used to fall through to the SQL fallback and emit // `DROP TABLE ""`, which the Mongo shell parser rejects. Dropping a - // collection must go through `db..drop()` instead. + // collection must go through `db.getCollection("").drop()` instead. do { _ = try MongoShellParser.parse("DROP TABLE \"users\"") Issue.record("Expected the SQL DROP TABLE fallback to be rejected")