- Created stripFileExtensions() helper that loops until all extensions removed
- Applied to both --target flag values and extracted archive names
- Handles cases like .sql.gz.sql.gz by repeatedly stripping until clean
- Updated both cmd/restore.go and internal/tui/archive_browser.go
- Ensures database names never contain .sql, .dump, .tar.gz etc extensions
Issue: Interactive backup (single, sample, cluster) showed 'Status: Initializing...'
throughout the entire backup process, identical to the restore issue that was just fixed.
Root cause:
- Status was set once in NewBackupExecution()
- Never updated during the backup process
- Only changed to success/failure at completion
- No visual feedback about backup progress
Solution: Time-based status progression (matching restore pattern)
Added logic in Update() tick handler to change status based on elapsed time:
- 0-2 sec: 'Initializing backup...'
- 2-5 sec: Connection phase:
- Cluster: 'Connecting to database cluster...'
- Single/Sample: 'Connecting to database [name]...'
- 5-10 sec: Early backup phase:
- Cluster: 'Backing up global objects (roles, tablespaces)...'
- Sample: 'Analyzing tables for sampling (ratio: N)...'
- Single: 'Dumping database [name]...'
- 10+ sec: Main backup phase:
- Cluster: 'Backing up cluster databases...'
- Sample: 'Creating sample backup of [name]...'
- Single: 'Backing up database [name]...'
Benefits:
- Consistent UX with restore operations
- Different status messages for single/sample/cluster backups
- Shows what stage of backup is running
- Spinner + changing status = clear progress indication
- Better user experience during long cluster backups
Status checked across all TUI operations:
✅ RestoreExecutionModel - Fixed (previous commit)
✅ BackupExecutionModel - Fixed (this commit)
✅ StatusViewModel - Already has proper loading state
✅ OperationsViewModel - Simple view, no long operations
Issue: Interactive cluster restore showed 'Status: Initializing...' throughout
the entire restore process, making it appear stuck even though restore was working.
Root cause:
- Status and phase were set once in NewRestoreExecution()
- Never updated during the restore process
- Only changed to 'Completed' or 'Failed' at the end
- No visual feedback about what stage of restore was running
Solution: Time-based status progression
Added logic in Update() tick handler to change status based on elapsed time:
- 0-2 sec: 'Initializing restore...' / Phase: Starting
- 2-5 sec: Context-aware status:
- If cleanup: 'Cleaning N existing database(s)...' / Phase: Cleanup
- If cluster: 'Extracting cluster archive...' / Phase: Extraction
- If single: 'Preparing restore...' / Phase: Preparation
- 5-10 sec:
- If cluster: 'Restoring global objects...' / Phase: Globals
- If single: 'Restoring database...' / Phase: Restore
- 10+ sec: 'Restoring [cluster] databases...' / Phase: Restore
Benefits:
- User sees the restore is progressing through stages
- Different status messages for cluster vs single database restore
- Shows cleanup phase when enabled
- Spinner + changing status = clear visual feedback
- Better user experience during long-running restores
Note: These are estimated phases since the restore engine runs in silent mode
(no stdout interference with TUI). Actual operation may be faster or slower
than time estimates, but provides much better UX than static 'Initializing'.
Issue: When enabling cluster cleanup (Option C) in interactive restore mode,
the tool tried to connect to the database to drop existing databases. This
was confusing because:
- Cluster restore itself doesn't use database connections
- It uses CLI tools (psql, pg_restore) directly
- Connection errors were misleading to users
Solution: Changed cleanup to use psql command directly (dropDatabaseCLI)
- Matches how cluster restore works (CLI tools, not connections)
- No confusing connection errors
- Cleaner, more consistent behavior
- Uses postgres maintenance DB for DROP DATABASE commands
Files changed:
- internal/tui/restore_exec.go: Added dropDatabaseCLI() helper function
- Removed dbClient.Connect() requirement for cleanup
- Cleanup now works exactly like cluster restore operations
- Auto-detects existing user databases before cluster restore
- Shows count and list (first 5) in preview screen
- Toggle option 'c' to enable cluster cleanup
- Drops all user databases before restore when enabled
- Works for PostgreSQL, MySQL, MariaDB
- Safety warning with database count
- Implements practical disaster recovery workflow
- Created internal/progress/estimator.go with ETAEstimator component
- Tracks elapsed time and estimates remaining time based on progress
- Enhanced Spinner and LineByLine indicators to display ETA info
- Integrated into BackupCluster and RestoreCluster functions
- Display format: 'Operation | X/Y (Z%) | Elapsed: Xm | ETA: ~Ym remaining'
- Preserves spinner animation while showing progress/time estimates
- Quick Win approach: no historical data storage, just current operation tracking
PROBLEM:
- History displayed ALL entries at once
- With many backups, first entries scroll off screen
- Cursor navigation worked but selection was invisible
- User had to "blindly" navigate 5+ entries to see anything
SOLUTION:
- Added viewport with max 15 visible items at once
- Viewport auto-scrolls to follow cursor position
- Scroll indicators show when there are more entries:
* "▲ More entries above..."
* "▼ X more entries below..."
- Cursor always visible within viewport
RESULT:
- ✅ Always see current selection
- ✅ Works with any number of history entries
- ✅ Clear visual feedback with scroll indicators
- ✅ Smooth navigation experience
FIXED:
- Removed unused cursor variable that was always a space
- Arrow up/down now visibly highlights selected item
- Added position counter (Viewing X/Y)
- Changed selection indicator from ">" to "→"
- Explicit cursor initialization to 0
RESULT:
- ↑/↓ keys now work and show visual feedback
- Current selection clearly visible with highlight
- Position indicator shows which item is selected
- Cluster restores restore multiple databases, not a single target
- Database existence check was failing with exit status 2
- Now shows "Will restore all databases from cluster backup" instead
- Removes confusing warning for cluster restore operations
- Some terminals send ctrl+h instead of backspace
- Added ctrl+h handling in settings.go and input.go
- Ensures backspace works in all terminal emulators
- PostgreSQL and MySQL support
- Interactive TUI with fixed menu navigation
- Line-by-line progress display
- CPU-aware parallel processing
- Cross-platform build support
- Configuration settings menu
- Silent mode for TUI operations