Skip to content

refactor: rewrite query results system with clean architecture#512

Merged
datlechin merged 33 commits intomainfrom
rewrite/query-results
Mar 31, 2026
Merged

refactor: rewrite query results system with clean architecture#512
datlechin merged 33 commits intomainfrom
rewrite/query-results

Conversation

@datlechin
Copy link
Copy Markdown
Collaborator

Summary

Full rewrite of the query results system with clean architecture, native macOS design, and new features.

New Architecture

  • ResultSet (@Observable class) — single result set per SQL statement, replacing monolithic single-result properties on QueryTab
  • DataGridCoordinator — extracted from 1000-line DataGridView.swift into separate file (structural refactor, zero behavior change)
  • ResultsPanelView — new container orchestrating result tabs, error banners, and content area
  • ResultTabBar — horizontal scrollable tabs for multiple result sets with pin/close
  • InlineErrorBanner — red dismissable error banner replacing NSAlert for query errors
  • ResultSuccessView — compact DDL/DML success view

Features Added

  • Collapsible results panel — Cmd+Opt+R toggles results visibility, auto-expands on query execution
  • Multiple result set tabs — each statement in multi-query produces its own ResultSet tab
  • Pinnable results — right-click → Pin to preserve results from overwrite on re-execution
  • Inline error display — errors shown as red banner in results area
  • Keyboard shortcuts — Cmd+Opt+R (toggle), Cmd+[ (prev result), Cmd+] (next result)
  • View menu items — Toggle Results, Previous Result, Next Result

What's Preserved (unchanged)

  • DataGridView NSTableView wrapper + all 6 extensions
  • KeyHandlingTableView, DataGridCellFactory, all cell editors/popovers
  • RowBuffer, InMemoryRowProvider
  • 2-phase query execution pipeline
  • FilterPanelView, PaginationControlsView, MainStatusBarView

Files

Category Files
New (8) ResultSet.swift, DataGridCoordinator.swift, ResultsPanelView.swift, ResultTabBar.swift, InlineErrorBanner.swift, ResultSuccessView.swift
Rewritten (1) DataGridView.swift (coordinator extracted)
Modified (7) QueryTab.swift, MainEditorContentView.swift, MainContentCoordinator+MultiStatement.swift, MainContentCoordinator+QueryHelpers.swift, KeyboardShortcutModels.swift, TableProApp.swift, MainContentCommandActions.swift

Test plan

  • Single SELECT → results in grid with execution time
  • Multiple SELECTs (; separated) → each gets own ResultSet in tab.resultSets
  • INSERT/UPDATE/DELETE → ResultSuccessView shows rows affected
  • Invalid SQL → InlineErrorBanner shows error (not NSAlert)
  • Cmd+Opt+R → results panel collapses/expands with animation
  • Run query while collapsed → auto-expands
  • Cmd+[ / Cmd+] → switch between result tabs
  • Right-click result tab → Pin → re-execute → pinned preserved
  • Table browsing tab → DataGridView works as before
  • Structure tab → schema editing works as before
  • Create Table → still works

Phase 0: Add ResultSet @observable class and extend QueryTab with
resultSets array, activeResultSetId, isResultsCollapsed.

Phase 1: Extract TableViewCoordinator from DataGridView.swift into
DataGridCoordinator.swift. DataGridView.swift now contains only the
NSViewRepresentable shell + helper types. Zero behavior change.
- Cmd+Opt+R: Toggle Results panel collapse/expand
- Cmd+[: Previous Result tab
- Cmd+]: Next Result tab
- View menu items + command actions wired
- Keyboard shortcuts docs updated
…ccessView

- ResultsPanelView: orchestrates result tab bar, error banner, content area
- ResultTabBar: horizontal scrollable tabs with pin/close/close-others
- InlineErrorBanner: red dismissable error banner with optional AI fix button
- ResultSuccessView: compact DDL/DML success (replaces full-screen QuerySuccessView)
- Wrap resultsSection in conditional on isResultsCollapsed in queryTabContent
- Smooth animation (200ms easeInOut) when toggling collapse
- Auto-expand results when new query results arrive (single + multi-statement)
- Table tabs and structure tabs unaffected
- executeMultipleStatements builds a ResultSet for each statement with
  deep-copied rows, column types, execution time, and table name
- applyPhase1Result creates a ResultSet sharing the same RowBuffer
- Pinned results preserved on re-execution, unpinned replaced
- Auto-expand collapsed results panel on new data
…resultsSection

Replace old QuerySuccessView with ResultSuccessView, add result tab bar
for multi-result display, add inline error banner. Uses real DataGridView
(not placeholder). Structure and Explain paths unchanged.
1. Delete dead code ResultsPanelView.swift (never integrated)
2. Fix sortIndicesForTab to use active ResultSet data instead of tab-level
3. Change Cmd+[/] to Cmd+Opt+[/] to avoid system navigation conflict
4. Fix ResultSuccessView localization (use String(format:localized:))
5. Extract closeResultSet(id:) to coordinator, remove 3x duplication
6. Toolbar toggle button icon reflects collapsed/expanded state
1. Pin toggle routes through coordinator + bumps resultVersion for
   SwiftUI reactivity (was mutating class directly, bypassing Equatable)
2. Remove dead onAIFix API from InlineErrorBanner
3. Use NSColor.selectedControlColor for active tab (was wrong
   .selectedContentBackgroundColor.opacity(0.3), broken in dark mode)
4. ResultTabBar height 28→32pt (HIG minimum), replace deprecated
   .cornerRadius with RoundedRectangle, localize context menu strings
5. Consolidate dual ResultSuccessView paths into single branch
…results rewrite

- Fix Previous/Next Result shortcuts: Cmd+[ → Cmd+Opt+[ (matches code)
- Add sql-editor.mdx sections: collapsible panel, multi-result tabs,
  pinning, inline errors, non-SELECT success view
- Expand CHANGELOG [Unreleased] with all PR #512 features
@datlechin datlechin merged commit 7deb5b1 into main Mar 31, 2026
2 checks passed
@datlechin datlechin deleted the rewrite/query-results branch March 31, 2026 02:16
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