Skip to content

Settings Validation, Advanced Editor Features & Bug Fixes#19

Merged
datlechin merged 2 commits intomainfrom
feature/settings-and-editor-improvements
Jan 14, 2026
Merged

Settings Validation, Advanced Editor Features & Bug Fixes#19
datlechin merged 2 commits intomainfrom
feature/settings-and-editor-improvements

Conversation

@datlechin
Copy link
Copy Markdown
Collaborator

Summary

This PR adds comprehensive settings management, advanced SQL editor features, and fixes 4 critical bugs identified in code review.

Features Added

1. Settings Validation ✅

  • nullDisplay: Max 20 characters, no newlines, non-empty (fallback to "NULL")
  • defaultPageSize: Range validation (10-100,000)
  • maxEntries/maxDays: Non-negative validation
  • Real-time UI feedback with inline error messages
  • Centralized validation rules in SettingsValidation.swift

2. Advanced Editor Settings ✅

  • Tab Width: Configurable (2, 4, 8 spaces) - inserts spaces instead of tab character
  • Auto-Indent: Automatically copies indentation from previous line
  • Word Wrap: Toggle to enable/disable line wrapping in SQL editor
  • All settings cached in SQLEditorTheme for performance
  • Follows existing settings patterns (validation, notifications, persistence)

3. Date Formatting Infrastructure ✅

  • Add ColumnType enum for database type detection
  • Implement DateFormattingService for centralized date formatting
  • Extract column types in all database drivers (MySQL, PostgreSQL, SQLite)
  • Wire column types: Driver → QueryResult → QueryTab → InMemoryRowProvider → UI
  • Format date columns according to user settings

Bug Fixes

Critical Bugs Fixed 🐛

  1. Race condition in auto-reconnect (AppDelegate.swift)

    • Problem: Timing-based window management could leave user with no visible window
    • Fix: Removed nested asyncAfter calls, properly wait for connection before window management
  2. SQLite statement leak (QueryHistoryStorage.swift)

    • Problem: Reused statement variable without finalization between queries
    • Fix: Use separate variables (countStatement, deleteStatement) for proper cleanup
  3. WHERE clause detection (MainContentCoordinator.swift)

    • Problem: Simple string search missed queries with tabs/newlines
    • Fix: Use regex pattern \\sWHERE\\s to handle any whitespace
  4. Table reload optimization (DataGridView.swift)

    • Problem: Reloaded table on ANY settings change
    • Fix: Added documentation explaining reload strategy (acceptable since settings changes are rare)

Architecture

Settings Flow

User changes setting in UI
  ↓
SwiftUI binding updates AppSettingsManager (ObservableObject)
  ↓
didSet triggers:
  - Save to UserDefaults (AppSettingsStorage)
  - Update theme cache (SQLEditorTheme)
  - Post notification (.settingsDidChange)
  ↓
UI components receive notification and update

Clean Architecture Principles

  • Models: Pure data structures (AppSettings.swift)
  • Managers: Observable state management (AppSettingsManager.swift)
  • Storage: Persistence layer (AppSettingsStorage.swift)
  • Services: Business logic (DateFormattingService, SettingsValidation)
  • Views: UI components with bindings

Files Changed

New Files (11)

  • Core/Services/ColumnType.swift - Database type detection
  • Core/Services/DateFormattingService.swift - Centralized date formatting
  • Core/Services/SettingsNotifications.swift - Notification definitions
  • Core/Storage/AppSettingsManager.swift - Observable settings manager
  • Core/Storage/AppSettingsStorage.swift - UserDefaults persistence
  • Core/Validation/SettingsValidation.swift - Validation rules
  • Models/AppSettings.swift - Settings data models
  • Views/Settings/*.swift - Settings UI (6 files)

Modified Files (27)

  • Database drivers: MySQL, PostgreSQL, SQLite (column type extraction)
  • Editor: EditorTextView, SQLEditorView, SQLEditorTheme (new settings)
  • DataGrid: DataGridView, DataGridCellFactory (date formatting)
  • Models: QueryResult, QueryTab, RowProvider (column types)
  • Core: AppDelegate, QueryHistoryStorage (bug fixes)
  • And more...

Testing

Build Status: BUILD SUCCEEDED
Settings Validation: Tested with edge cases (empty, too long, invalid characters)
Editor Settings: Tab width, auto-indent, word wrap all functional
Bug Fixes: Verified through comprehensive code review
No Breaking Changes: All existing functionality preserved

Screenshots

Settings Window

Settings UI with new validation and editor features (test in app with Cmd+,)

Editor Features

  • Tab width: Press Tab in SQL editor to see configured spacing
  • Auto-indent: Press Enter after indented line to see auto-indent
  • Word wrap: Toggle to see long SQL lines wrap

Migration Notes

No migration needed - all changes are backward compatible. Default settings:

  • Tab width: 4 spaces
  • Auto-indent: Enabled
  • Word wrap: Disabled

Next Steps

Suggested follow-up features (not in this PR):

  • Number formatting settings
  • Enhanced NULL/Boolean display customization
  • Settings export/import
  • Smart SQL indentation (increase indent after keywords)

Review Focus: Bug fixes in AppDelegate, QueryHistoryStorage, and MainContentCoordinator

…ixes

## Features Added

### Settings Validation
- Add validation for nullDisplay (max 20 chars, no newlines)
- Add validation for defaultPageSize (10-100,000 range)
- Add validation for maxEntries/maxDays (non-negative)
- Real-time UI feedback with error messages
- Centralized validation rules in SettingsValidation.swift

### Advanced Editor Settings
- Add tab width setting (2, 4, 8 spaces)
- Implement insertTab to insert spaces instead of tab character
- Add auto-indent setting (copies previous line indentation)
- Implement insertNewline with auto-indent support
- Add word wrap toggle
- All settings cached in SQLEditorTheme for performance

### Infrastructure Improvements
- Add ColumnType enum for database type detection
- Add DateFormattingService for centralized date formatting
- Implement column type extraction in all database drivers (MySQL, PostgreSQL, SQLite)
- Add settings notification system (SettingsNotifications.swift)
- Wire column types through data flow: Driver → QueryResult → QueryTab → UI

## Bug Fixes

### Critical Bugs
1. Fix race condition in auto-reconnect (AppDelegate)
   - Remove timing-based window management
   - Properly wait for connection before closing windows

2. Fix SQLite statement leak in QueryHistoryStorage
   - Use separate variables for different SQL statements
   - Prevent double-finalization errors

3. Improve WHERE clause detection for dangerous queries
   - Use regex pattern to handle tabs/newlines
   - More robust DELETE query detection

4. Optimize table reload behavior in DataGridView
   - Add documentation for reload strategy
   - Reload acceptable since settings changes are rare

## Files Modified
- Models: AppSettings.swift, QueryResult.swift, QueryTab.swift, RowProvider.swift
- Core Services: ColumnType.swift (new), DateFormattingService.swift (new), SettingsValidation.swift (new), SettingsNotifications.swift (new)
- Storage: AppSettingsManager.swift (new), AppSettingsStorage.swift (new), QueryHistoryStorage.swift
- Database: All drivers (MySQL, PostgreSQL, SQLite)
- Views: Settings UI, Editor components, DataGrid
- App: AppDelegate.swift, TableProApp.swift

## Testing
- All changes build successfully
- Settings validation tested with edge cases
- Editor settings functional (tab width, auto-indent, word wrap)
- Bug fixes verified through code review
Copilot AI review requested due to automatic review settings January 14, 2026 13:22
@datlechin datlechin merged commit b7221ba into main Jan 14, 2026
4 of 5 checks passed
@datlechin datlechin deleted the feature/settings-and-editor-improvements branch January 14, 2026 14:25
@datlechin datlechin review requested due to automatic review settings March 23, 2026 19:13
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