@@ -299,47 +299,45 @@ extension MainContentCoordinator {
299299 isSwitchingDatabase = false
300300 }
301301
302+ // Clear stale filter state from previous database/schema
303+ filterStateManager. clearAll ( )
304+
302305 guard let driver = DatabaseManager . shared. driver ( for: connectionId) else {
303306 return
304307 }
305308
309+ // Snapshot current state for rollback on failure
310+ let previousDatabase = toolbarState. databaseName
311+
312+ // Immediately clear UI state so the sidebar shows a loading spinner
313+ // instead of stale tables from the previous database/schema.
314+ toolbarState. databaseName = database
315+ closeSiblingNativeWindows ( )
316+ tabManager. tabs = [ ]
317+ tabManager. selectedTabId = nil
318+ DatabaseManager . shared. updateSession ( connectionId) { session in
319+ session. tables = [ ]
320+ }
321+ // Yield so SwiftUI renders the empty/loading state before async work begins
322+ await Task . yield ( )
323+
306324 do {
307325 // For MySQL/MariaDB/ClickHouse, use USE command
308326 if connection. type == . mysql || connection. type == . mariadb || connection. type == . clickhouse {
309327 _ = try await driver. execute ( query: " USE ` \( database) ` " )
310328
311- // Update session with new database
312329 DatabaseManager . shared. updateSession ( connectionId) { session in
313330 session. currentDatabase = database
314- session. tables = [ ] // triggers SidebarView.loadTables() via onChange
315331 }
316332
317- // Update toolbar state
318- toolbarState. databaseName = database
319-
320- // Close sibling native window-tabs and clear in-app tabs —
321- // previous database's tables/queries are no longer valid
322- closeSiblingNativeWindows ( )
323- tabManager. tabs = [ ]
324- tabManager. selectedTabId = nil
325-
326- // Reload schema for autocomplete.
327- // session.tables was cleared above, which triggers SidebarView.loadTables() via onChange.
328333 await loadSchema ( )
329334 } else if connection. type == . postgresql {
330335 DatabaseManager . shared. updateSession ( connectionId) { session in
331336 session. connection. database = database
332337 session. currentDatabase = database
333338 session. currentSchema = nil
334- session. tables = [ ] // triggers SidebarView.loadTables() via onChange
335339 }
336340
337- toolbarState. databaseName = database
338-
339- closeSiblingNativeWindows ( )
340- tabManager. tabs = [ ]
341- tabManager. selectedTabId = nil
342-
343341 await DatabaseManager . shared. reconnectSession ( connectionId)
344342
345343 await loadSchema ( )
@@ -349,42 +347,21 @@ extension MainContentCoordinator {
349347 guard let schemaDriver = driver as? SchemaSwitchable else { return }
350348 try await schemaDriver. switchSchema ( to: database)
351349
352- // Update session
353350 DatabaseManager . shared. updateSession ( connectionId) { session in
354351 session. currentSchema = database
355- session. tables = [ ] // triggers SidebarView.loadTables() via onChange
356352 }
357353
358- // Update toolbar state
359- toolbarState. databaseName = database
360-
361- // Close sibling native window-tabs and clear in-app tabs —
362- // previous schema's tables/queries are no longer valid
363- closeSiblingNativeWindows ( )
364- tabManager. tabs = [ ]
365- tabManager. selectedTabId = nil
366-
367- // Reload schema for autocomplete
368354 await loadSchema ( )
369355
370- // Force sidebar reload — posting .refreshData ensures loadTables() runs
371- // even when session.tables was already [] (e.g. switching from empty schema back to public)
372356 NotificationCenter . default. post ( name: . refreshData, object: nil )
373357 } else if connection. type == . oracle {
374358 guard let schemaDriver = driver as? SchemaSwitchable else { return }
375359 try await schemaDriver. switchSchema ( to: database)
376360
377361 DatabaseManager . shared. updateSession ( connectionId) { session in
378362 session. currentSchema = database
379- session. tables = [ ]
380363 }
381364
382- toolbarState. databaseName = database
383-
384- closeSiblingNativeWindows ( )
385- tabManager. tabs = [ ]
386- tabManager. selectedTabId = nil
387-
388365 await loadSchema ( )
389366
390367 NotificationCenter . default. post ( name: . refreshData, object: nil )
@@ -396,43 +373,25 @@ extension MainContentCoordinator {
396373 DatabaseManager . shared. updateSession ( connectionId) { session in
397374 session. currentDatabase = database
398375 session. currentSchema = " dbo "
399- session. tables = [ ]
400376 }
401377 AppSettingsStorage . shared. saveLastDatabase ( database, for: connectionId)
402378
403- toolbarState. databaseName = database
404-
405- closeSiblingNativeWindows ( )
406- tabManager. tabs = [ ]
407- tabManager. selectedTabId = nil
408-
409379 await loadSchema ( )
410380
411381 NotificationCenter . default. post ( name: . refreshData, object: nil )
412382 } else if connection. type == . mongodb {
413- // MongoDB: update the driver's connection so fetchTables/execute use the new database
414383 if let adapter = driver as? PluginDriverAdapter {
415384 try await adapter. switchDatabase ( to: database)
416385 }
417386
418387 DatabaseManager . shared. updateSession ( connectionId) { session in
419388 session. currentDatabase = database
420- session. tables = [ ]
421389 }
422390
423- toolbarState. databaseName = database
424-
425- // Close sibling native window-tabs and clear in-app tabs —
426- // previous database's collections are no longer valid
427- closeSiblingNativeWindows ( )
428- tabManager. tabs = [ ]
429- tabManager. selectedTabId = nil
430-
431391 await loadSchema ( )
432392
433393 NotificationCenter . default. post ( name: . refreshData, object: nil )
434394 } else if connection. type == . redis {
435- // Redis: SELECT <db index> to switch logical database
436395 guard let dbIndex = Int ( database) else { return }
437396
438397 if let adapter = driver as? PluginDriverAdapter {
@@ -441,20 +400,18 @@ extension MainContentCoordinator {
441400
442401 DatabaseManager . shared. updateSession ( connectionId) { session in
443402 session. currentDatabase = database
444- session. tables = [ ]
445403 }
446404
447- toolbarState. databaseName = database
448-
449- closeSiblingNativeWindows ( )
450- tabManager. tabs = [ ]
451- tabManager. selectedTabId = nil
452-
453405 await loadSchema ( )
454406
455407 NotificationCenter . default. post ( name: . refreshData, object: nil )
456408 }
457409 } catch {
410+ // Restore toolbar to previous database on failure
411+ toolbarState. databaseName = previousDatabase
412+ // Reload previous tables so sidebar isn't left empty
413+ NotificationCenter . default. post ( name: . refreshData, object: nil )
414+
458415 navigationLogger. error ( " Failed to switch database: \( error. localizedDescription, privacy: . public) " )
459416 AlertHelper . showErrorSheet (
460417 title: String ( localized: " Database Switch Failed " ) ,
@@ -469,25 +426,38 @@ extension MainContentCoordinator {
469426 guard connection. type == . postgresql else { return }
470427 guard let driver = DatabaseManager . shared. driver ( for: connectionId) else { return }
471428
429+ // Clear stale filter state from previous schema
430+ filterStateManager. clearAll ( )
431+
432+ // Snapshot current state for rollback on failure
433+ let previousSchema = toolbarState. databaseName
434+
435+ // Immediately clear UI state so sidebar shows loading state
436+ toolbarState. databaseName = schema
437+ closeSiblingNativeWindows ( )
438+ tabManager. tabs = [ ]
439+ tabManager. selectedTabId = nil
440+ DatabaseManager . shared. updateSession ( connectionId) { session in
441+ session. tables = [ ]
442+ }
443+ await Task . yield ( )
444+
472445 do {
473446 guard let schemaDriver = driver as? SchemaSwitchable else { return }
474447 try await schemaDriver. switchSchema ( to: schema)
475448
476449 DatabaseManager . shared. updateSession ( connectionId) { session in
477450 session. currentSchema = schema
478- session. tables = [ ]
479451 }
480452
481- toolbarState. databaseName = schema
482-
483- closeSiblingNativeWindows ( )
484- tabManager. tabs = [ ]
485- tabManager. selectedTabId = nil
486-
487453 await loadSchema ( )
488454
489455 NotificationCenter . default. post ( name: . refreshData, object: nil )
490456 } catch {
457+ // Restore toolbar to previous schema on failure
458+ toolbarState. databaseName = previousSchema
459+ NotificationCenter . default. post ( name: . refreshData, object: nil )
460+
491461 navigationLogger. error ( " Failed to switch schema: \( error. localizedDescription, privacy: . public) " )
492462 AlertHelper . showErrorSheet (
493463 title: String ( localized: " Schema Switch Failed " ) ,
0 commit comments