Skip to content

fix: add SQL fallbacks for DROP/TRUNCATE and fix MySQL FK metadata after db switch#353

Merged
datlechin merged 3 commits intomainfrom
fix/table-ops-and-mysql-fk-after-db-switch
Mar 17, 2026
Merged

fix: add SQL fallbacks for DROP/TRUNCATE and fix MySQL FK metadata after db switch#353
datlechin merged 3 commits intomainfrom
fix/table-ops-and-mysql-fk-after-db-switch

Conversation

@datlechin
Copy link
Copy Markdown
Collaborator

@datlechin datlechin commented Mar 17, 2026

Summary

  • DROP/TRUNCATE producing no SQL: PluginDriverAdapter now generates standard SQL fallbacks (DROP TABLE/VIEW, TRUNCATE TABLE) when plugin returns nil. Previously all SQL databases silently produced empty statements. Coordinator simplified to pure delegation.
  • MySQL FK chevrons missing after Cmd+K: MySQL plugin now tracks _activeDatabase and updates it on switchDatabase(). Previously fetchForeignKeys, fetchAllColumns, and fetchApproximateRowCount used stale config.database after switching databases.

Test plan

  • Right-click table in sidebar → Delete → eye button should show DROP TABLE \tablename``
  • Same for Truncate → should show TRUNCATE TABLE \tablename``
  • CASCADE option appends correctly when checked
  • Connect to MySQL, Cmd+K switch to fk_test_db, browse order_items — FK chevrons should appear on order_id and product_id
  • Click FK chevron → navigates to referenced table with correct filter
  • Direct connection to fk_test_db still works as before

Summary by CodeRabbit

  • Bug Fixes

    • Sidebar DROP and TRUNCATE now reliably produce SQL for plugin-based drivers.
    • Foreign key navigation arrows correctly reappear after switching databases (MySQL).
    • Database scoping follows the active database after switching.
  • Refactor

    • Simplified table operation flow and removed per-table quoting paths; adapters provide deterministic fallback statements.
  • Tests

    • Added tests for default SQL generation and plugin-provided overrides for drop/truncate.
  • Documentation

    • Changelog updated to note these fixes.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e89c5944-eb0c-454c-8722-beebecca6a65

📥 Commits

Reviewing files that changed from the base of the PR and between c71a9ab and 1ae79ef.

📒 Files selected for processing (1)
  • Plugins/MySQLDriverPlugin/MySQLPluginDriver.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • Plugins/MySQLDriverPlugin/MySQLPluginDriver.swift

📝 Walkthrough

Walkthrough

High-level changes: Adjusted plugin table-operation APIs and adapter fallbacks, removed per-table quoting in table operations, added MySQL driver internal active-database state, updated tests for adapter table ops, and updated CHANGELOG entry.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added two Fixed items under Unreleased describing sidebar/TRUNCATE/DROP SQL and FK navigation fix.
MySQL plugin
Plugins/MySQLDriverPlugin/MySQLPluginDriver.swift
Added private _activeDatabase state initialized from config; replaced uses of config.database with _activeDatabase; switchDatabase(to:) updates _activeDatabase.
Plugin adapter
TablePro/Core/Plugins/PluginDriverAdapter.swift
Changed truncateTableStatements(...) return type from [String]?[String] and dropObjectStatement(...) from String?String; adapter now returns driver-provided value or deterministic fallback SQL.
UI / Coordinator
TablePro/Views/Main/Extensions/MainContentCoordinator+TableOperations.swift
Removed per-table quoting logic and dbType branching; simplified truncateStatements and dropTableStatement signatures and delegates directly to adapter methods (no quotedName/dbType).
Tests
TableProTests/Core/Plugins/PluginDriverAdapterTableOpsTests.swift
Added tests and a StubTableOpsDriver verifying adapter fallbacks and driver override behavior for DROP/TRUNCATE statements (schema qualification and CASCADE cases).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant UI as MainContentCoordinator
participant Adapter as PluginDriverAdapter
participant Driver as PluginDatabaseDriver (e.g., MySQLPluginDriver)
participant DB as Database

UI->>Adapter: request truncate/drop for table
Adapter->>Driver: call truncateTableStatements / dropObjectStatement
alt Driver returns statements
Driver-->>Adapter: custom SQL statements
Adapter-->>UI: return custom SQL
else Driver returns no statements
Adapter->>Adapter: construct deterministic SQL (qualified name, CASCADE)
Adapter-->>UI: return fallback SQL
end
UI->>DB: execute selected SQL (via existing execution path)
note right of Driver: MySQLPluginDriver uses _activeDatabase for scoping\n(updated by switchDatabase)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: plugin extensibility #294: Changes to PluginDriverAdapter table-operation methods and adapter fallbacks that overlap with this PR's API and behavior adjustments.

"I hopped through branches with a whisker twitch,
Found SQL in burrows both fallback and rich,
MySQL now remembers which hole it's in,
Plugins improvise when drivers have been thin,
A rabbit's small cheer for tidy table-switch!" 🐇

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the two main fixes: SQL fallbacks for DROP/TRUNCATE operations and MySQL foreign key metadata correction after database switching.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/table-ops-and-mysql-fk-after-db-switch
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@datlechin datlechin force-pushed the fix/table-ops-and-mysql-fk-after-db-switch branch from 76000bf to 53a9ae0 Compare March 17, 2026 03:41
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
TablePro/Views/Main/Extensions/MainContentCoordinator+TableOperations.swift (2)

114-123: Same cleanup opportunity for quotedName and dbType parameters.

Similar to truncateStatements, the quotedName parameter is now unused. Additionally, dbType is no longer used in this method since the adapter handles everything.

♻️ Suggested cleanup
 private func dropTableStatement(
-    tableName: String, quotedName: String, isView: Bool,
-    options: TableOperationOptions, dbType: DatabaseType
+    tableName: String, isView: Bool, options: TableOperationOptions
 ) -> String {
     let keyword = isView ? "VIEW" : "TABLE"
     guard let adapter = currentPluginDriverAdapter else { return "" }
     return adapter.dropObjectStatement(
         name: tableName, objectType: keyword, schema: nil, cascade: options.cascade
     )
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TablePro/Views/Main/Extensions/MainContentCoordinator`+TableOperations.swift
around lines 114 - 123, The dropTableStatement method currently accepts unused
parameters quotedName and dbType; update the signature of dropTableStatement to
remove those unused parameters (keep tableName, isView, and options), and adjust
any callers to match the new signature, then let the method continue to use
currentPluginDriverAdapter.dropObjectStatement(name:objectType:schema:cascade:)
as it does now; reference the dropTableStatement function, the quotedName and
dbType parameters, and currentPluginDriverAdapter.dropObjectStatement when
making the changes.

105-112: Consider removing unused quotedName parameter.

The quotedName parameter is still being passed to this method but is no longer used since the adapter now handles all quoting internally. This creates dead code in the function signature and at the call site (line 53).

♻️ Suggested cleanup
 private func truncateStatements(
-    tableName: String, quotedName: String, options: TableOperationOptions, dbType: DatabaseType
+    tableName: String, options: TableOperationOptions, dbType: DatabaseType
 ) -> [String] {
     guard let adapter = currentPluginDriverAdapter else { return [] }
     return adapter.truncateTableStatements(
         table: tableName, schema: nil, cascade: options.cascade
     )
 }

And update the call site at line 55-57:

 statements.append(contentsOf: truncateStatements(
-    tableName: tableName, quotedName: quotedName, options: tableOptions, dbType: dbType
+    tableName: tableName, options: tableOptions, dbType: dbType
 ))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TablePro/Views/Main/Extensions/MainContentCoordinator`+TableOperations.swift
around lines 105 - 112, The function truncateStatements currently declares an
unused parameter quotedName; remove quotedName from the truncateStatements
signature and from any calls, leaving parameters (tableName: String, options:
TableOperationOptions, dbType: DatabaseType), and update its body to continue
using currentPluginDriverAdapter and adapter.truncateTableStatements(table:
tableName, schema: nil, cascade: options.cascade) unchanged; also update all
call sites that still pass quotedName to call the revised truncateStatements
without that argument.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@TablePro/Views/Main/Extensions/MainContentCoordinator`+TableOperations.swift:
- Around line 114-123: The dropTableStatement method currently accepts unused
parameters quotedName and dbType; update the signature of dropTableStatement to
remove those unused parameters (keep tableName, isView, and options), and adjust
any callers to match the new signature, then let the method continue to use
currentPluginDriverAdapter.dropObjectStatement(name:objectType:schema:cascade:)
as it does now; reference the dropTableStatement function, the quotedName and
dbType parameters, and currentPluginDriverAdapter.dropObjectStatement when
making the changes.
- Around line 105-112: The function truncateStatements currently declares an
unused parameter quotedName; remove quotedName from the truncateStatements
signature and from any calls, leaving parameters (tableName: String, options:
TableOperationOptions, dbType: DatabaseType), and update its body to continue
using currentPluginDriverAdapter and adapter.truncateTableStatements(table:
tableName, schema: nil, cascade: options.cascade) unchanged; also update all
call sites that still pass quotedName to call the revised truncateStatements
without that argument.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d0aaa60c-300f-45d5-bcfe-068f4ed9f491

📥 Commits

Reviewing files that changed from the base of the PR and between 3d82787 and 76000bf.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • Plugins/MySQLDriverPlugin/MySQLPluginDriver.swift
  • TablePro/Core/Plugins/PluginDriverAdapter.swift
  • TablePro/Views/Main/Extensions/MainContentCoordinator+TableOperations.swift
  • TableProTests/Core/Plugins/PluginDriverAdapterTableOpsTests.swift

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
TablePro/Views/Main/Extensions/MainContentCoordinator+TableOperations.swift (1)

105-122: Remove now-unused parameters from private SQL builders.

After the delegation change (Line 108 and Line 119), quotedName and dbType are no longer used in these helper signatures or implementations.

♻️ Suggested cleanup
-    private func truncateStatements(
-        tableName: String, quotedName: String, options: TableOperationOptions, dbType: DatabaseType
-    ) -> [String] {
+    private func truncateStatements(
+        tableName: String, options: TableOperationOptions
+    ) -> [String] {
         guard let adapter = currentPluginDriverAdapter else { return [] }
         return adapter.truncateTableStatements(
             table: tableName, schema: nil, cascade: options.cascade
         )
     }

-    private func dropTableStatement(
-        tableName: String, quotedName: String, isView: Bool,
-        options: TableOperationOptions, dbType: DatabaseType
-    ) -> String {
+    private func dropTableStatement(
+        tableName: String, isView: Bool, options: TableOperationOptions
+    ) -> String {
         let keyword = isView ? "VIEW" : "TABLE"
         guard let adapter = currentPluginDriverAdapter else { return "" }
         return adapter.dropObjectStatement(
             name: tableName, objectType: keyword, schema: nil, cascade: options.cascade
         )
     }
-            statements.append(contentsOf: truncateStatements(
-                tableName: tableName, quotedName: quotedName, options: tableOptions, dbType: dbType
-            ))
+            statements.append(contentsOf: truncateStatements(
+                tableName: tableName, options: tableOptions
+            ))

-            let stmt = dropTableStatement(
-                tableName: tableName, quotedName: quotedName,
-                isView: viewNames.contains(tableName), options: tableOptions, dbType: dbType
-            )
+            let stmt = dropTableStatement(
+                tableName: tableName,
+                isView: viewNames.contains(tableName), options: tableOptions
+            )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TablePro/Views/Main/Extensions/MainContentCoordinator`+TableOperations.swift
around lines 105 - 122, The private helpers
truncateStatements(tableName:quotedName:options:dbType:) and
dropTableStatement(tableName:quotedName:isView:options:dbType:) still declare
unused parameters (quotedName and dbType); remove those parameters from both
function signatures and from their implementations so they become
truncateStatements(tableName:options:) and
dropTableStatement(tableName:isView:options:), update any internal
references/call sites to pass the reduced argument list, and ensure
imports/types (TableOperationOptions, DatabaseType) remain only where actually
used so the code compiles.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Plugins/MySQLDriverPlugin/MySQLPluginDriver.swift`:
- Around line 580-584: switchDatabase(to:) updates the in-memory _activeDatabase
but connect() (and reconnects) still use config.database, so a transient
reconnect can revert the DB; fix by making the state persistent: either have
connect() prefer _activeDatabase if set, or update config.database when
switching. Concretely, inside switchDatabase(to:) assign the new database into
config.database in addition to setting _activeDatabase (or modify connect() to
use _activeDatabase when non-nil) so reconnect()/connect() will open the same
active database.

---

Nitpick comments:
In `@TablePro/Views/Main/Extensions/MainContentCoordinator`+TableOperations.swift:
- Around line 105-122: The private helpers
truncateStatements(tableName:quotedName:options:dbType:) and
dropTableStatement(tableName:quotedName:isView:options:dbType:) still declare
unused parameters (quotedName and dbType); remove those parameters from both
function signatures and from their implementations so they become
truncateStatements(tableName:options:) and
dropTableStatement(tableName:isView:options:), update any internal
references/call sites to pass the reduced argument list, and ensure
imports/types (TableOperationOptions, DatabaseType) remain only where actually
used so the code compiles.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe7f701a-2e43-4766-964e-681d7798ef62

📥 Commits

Reviewing files that changed from the base of the PR and between 76000bf and 53a9ae0.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • Plugins/MySQLDriverPlugin/MySQLPluginDriver.swift
  • TablePro/Core/Plugins/PluginDriverAdapter.swift
  • TablePro/Views/Main/Extensions/MainContentCoordinator+TableOperations.swift
  • TableProTests/Core/Plugins/PluginDriverAdapterTableOpsTests.swift
🚧 Files skipped from review as they are similar to previous changes (2)
  • TableProTests/Core/Plugins/PluginDriverAdapterTableOpsTests.swift
  • CHANGELOG.md

@datlechin datlechin merged commit 1b2d43a into main Mar 17, 2026
2 checks passed
@datlechin datlechin deleted the fix/table-ops-and-mysql-fk-after-db-switch branch March 17, 2026 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant