@@ -40,12 +40,6 @@ final class DatabaseManager {
4040 /// Health monitors for active connections (MySQL/PostgreSQL only)
4141 private var healthMonitors : [ UUID : ConnectionHealthMonitor ] = [ : ]
4242
43- /// Dedicated lightweight drivers used exclusively for health-check pings.
44- /// Separate from the main driver so pings never queue behind long-running user queries.
45- private var pingDrivers : [ UUID : DatabaseDriver ] = [ : ]
46-
47- private var metadataCreationTasks : [ UUID : Task < Void , Never > ] = [ : ]
48-
4943 /// Current session (computed from currentSessionId)
5044 var currentSession : ConnectionSession ? {
5145 guard let sessionId = currentSessionId else { return nil }
@@ -57,22 +51,11 @@ final class DatabaseManager {
5751 currentSession? . driver
5852 }
5953
60- /// Dedicated driver for metadata queries (columns, FKs, count).
61- /// Runs on a separate serial queue so metadata fetches don't block the main query.
62- var activeMetadataDriver : DatabaseDriver ? {
63- currentSession? . metadataDriver
64- }
65-
6654 /// Resolve the driver for a specific connection (session-scoped, no global state)
6755 func driver( for connectionId: UUID ) -> DatabaseDriver ? {
6856 activeSessions [ connectionId] ? . driver
6957 }
7058
71- /// Resolve the metadata driver for a specific connection
72- func metadataDriver( for connectionId: UUID ) -> DatabaseDriver ? {
73- activeSessions [ connectionId] ? . metadataDriver
74- }
75-
7659 /// Resolve a session by explicit connection ID
7760 func session( for connectionId: UUID ) -> ConnectionSession ? {
7861 activeSessions [ connectionId]
@@ -211,33 +194,6 @@ final class DatabaseManager {
211194 await startHealthMonitor ( for: connection. id)
212195 }
213196
214- // Create a dedicated metadata connection in the background so Phase 2
215- // metadata queries (columns, FKs, count) run in parallel with main queries.
216- let metaConnection = effectiveConnection
217- let metaConnectionId = connection. id
218- let metaTimeout = AppSettingsManager . shared. general. queryTimeoutSeconds
219- metadataCreationTasks [ metaConnectionId] = Task { [ weak self] in
220- guard let self else { return }
221- defer { self . metadataCreationTasks. removeValue ( forKey: metaConnectionId) }
222- do {
223- let metaDriver = try DatabaseDriverFactory . createDriver ( for: metaConnection)
224- try await metaDriver. connect ( )
225- if metaTimeout > 0 {
226- try ? await metaDriver. applyQueryTimeout ( metaTimeout)
227- }
228- await self . executeStartupCommands (
229- connection. startupCommands, on: metaDriver, connectionName: connection. name
230- )
231- if let savedSchema = self . activeSessions [ metaConnectionId] ? . currentSchema,
232- let schemaMetaDriver = metaDriver as? SchemaSwitchable {
233- try ? await schemaMetaDriver. switchSchema ( to: savedSchema)
234- }
235- activeSessions [ metaConnectionId] ? . metadataDriver = metaDriver
236- } catch {
237- // Non-fatal: Phase 2 falls back to main driver if metadata driver unavailable
238- Self . logger. warning ( " Metadata connection failed: \( error. localizedDescription) " )
239- }
240- }
241197 } catch {
242198 // Close tunnel if connection failed
243199 if connection. sshConfig. enabled {
@@ -282,14 +238,9 @@ final class DatabaseManager {
282238 try ? await SSHTunnelManager . shared. closeTunnel ( connectionId: session. connection. id)
283239 }
284240
285- // Cancel any in-flight metadata driver creation
286- metadataCreationTasks [ sessionId] ? . cancel ( )
287- metadataCreationTasks. removeValue ( forKey: sessionId)
288-
289241 // Stop health monitoring
290242 await stopHealthMonitor ( for: sessionId)
291243
292- session. metadataDriver? . disconnect ( )
293244 session. driver? . disconnect ( )
294245 activeSessions. removeValue ( forKey: sessionId)
295246
@@ -318,9 +269,6 @@ final class DatabaseManager {
318269 await stopHealthMonitor ( for: sessionId)
319270 }
320271
321- for task in metadataCreationTasks. values { task. cancel ( ) }
322- metadataCreationTasks. removeAll ( )
323-
324272 let sessionIds = Array ( activeSessions. keys)
325273 for sessionId in sessionIds {
326274 await disconnectSession ( sessionId)
@@ -475,43 +423,15 @@ final class DatabaseManager {
475423 // Stop any existing monitor
476424 await stopHealthMonitor ( for: connectionId)
477425
478- // Create a dedicated lightweight driver for pings so they never
479- // queue behind long-running user queries on the main driver.
480- if let session = activeSessions [ connectionId] {
481- let connectionForPing = session. effectiveConnection ?? session. connection
482- let dedicatedPingDriver : DatabaseDriver
483- do {
484- dedicatedPingDriver = try DatabaseDriverFactory . createDriver ( for: connectionForPing)
485- } catch {
486- Self . logger. warning ( " Failed to create ping driver for \( connectionId) : \( error. localizedDescription) " )
487- return
488- }
489- do {
490- try await dedicatedPingDriver. connect ( )
491- pingDrivers [ connectionId] = dedicatedPingDriver
492- } catch {
493- Self . logger. warning (
494- " Failed to create dedicated ping driver, will fall back to main driver " )
495- }
496- }
497-
498426 let monitor = ConnectionHealthMonitor (
499427 connectionId: connectionId,
500428 pingHandler: { [ weak self] in
501429 guard let self else { return false }
502- // Prefer the dedicated ping driver so pings are never blocked
503- // by long-running user queries on the main driver.
504- let pingDriver = await self . pingDrivers [ connectionId]
505- let driver : DatabaseDriver
506- if let pingDriver {
507- driver = pingDriver
508- } else if let mainDriver = await self . activeSessions [ connectionId] ? . driver {
509- driver = mainDriver
510- } else {
430+ guard let mainDriver = await self . activeSessions [ connectionId] ? . driver else {
511431 return false
512432 }
513433 do {
514- _ = try await driver . execute ( query: " SELECT 1 " )
434+ _ = try await mainDriver . execute ( query: " SELECT 1 " )
515435 return true
516436 } catch {
517437 return false
@@ -527,15 +447,6 @@ final class DatabaseManager {
527447 session. status = . connected
528448 }
529449
530- // Also reconnect the dedicated ping driver so future pings
531- // don't fail immediately after a successful main reconnect.
532- let connectionForPing = session. effectiveConnection ?? session. connection
533- let newPingDriver = try await MainActor . run {
534- try DatabaseDriverFactory . createDriver ( for: connectionForPing)
535- }
536- try await newPingDriver. connect ( )
537- await self . replacePingDriver ( newPingDriver, for: connectionId)
538-
539450 return true
540451 } catch {
541452 return false
@@ -610,22 +521,11 @@ final class DatabaseManager {
610521 return driver
611522 }
612523
613- /// Replace the dedicated ping driver for a connection, disconnecting the old one.
614- private func replacePingDriver( _ newDriver: DatabaseDriver , for connectionId: UUID ) {
615- pingDrivers [ connectionId] ? . disconnect ( )
616- pingDrivers [ connectionId] = newDriver
617- }
618-
619524 /// Stop health monitoring for a connection
620525 private func stopHealthMonitor( for connectionId: UUID ) async {
621526 if let monitor = healthMonitors. removeValue ( forKey: connectionId) {
622527 await monitor. stopMonitoring ( )
623528 }
624-
625- // Disconnect and remove the dedicated ping driver
626- if let pingDriver = pingDrivers. removeValue ( forKey: connectionId) {
627- pingDriver. disconnect ( )
628- }
629529 }
630530
631531 /// Reconnect the current session (called from toolbar Reconnect button)
@@ -650,7 +550,6 @@ final class DatabaseManager {
650550
651551 do {
652552 // Disconnect existing drivers
653- session. metadataDriver? . disconnect ( )
654553 session. driver? . disconnect ( )
655554
656555 // Recreate SSH tunnel if needed and build effective connection
@@ -688,40 +587,6 @@ final class DatabaseManager {
688587 session. effectiveConnection = effectiveConnection
689588 }
690589
691- // Recreate metadata connection in background
692- let metaConnection = effectiveConnection
693- let metaConnectionId = sessionId
694- let metaTimeout = AppSettingsManager . shared. general. queryTimeoutSeconds
695- let startupCmds = session. connection. startupCommands
696- let connName = session. connection. name
697- metadataCreationTasks [ metaConnectionId] = Task { [ weak self] in
698- guard let self else { return }
699- defer { self . metadataCreationTasks. removeValue ( forKey: metaConnectionId) }
700- do {
701- let metaDriver = try DatabaseDriverFactory . createDriver ( for: metaConnection)
702- try await metaDriver. connect ( )
703- if metaTimeout > 0 {
704- try ? await metaDriver. applyQueryTimeout ( metaTimeout)
705- }
706- await self . executeStartupCommands (
707- startupCmds, on: metaDriver, connectionName: connName
708- )
709- if let savedSchema = self . activeSessions [ metaConnectionId] ? . currentSchema,
710- let schemaMetaDriver = metaDriver as? SchemaSwitchable {
711- try ? await schemaMetaDriver. switchSchema ( to: savedSchema)
712- }
713- // Restore database on metadata driver too for MSSQL
714- if let savedDatabase = self . activeSessions [ metaConnectionId] ? . currentDatabase,
715- let adapter = metaDriver as? PluginDriverAdapter {
716- try ? await adapter. switchDatabase ( to: savedDatabase)
717- }
718- activeSessions [ metaConnectionId] ? . metadataDriver = metaDriver
719- } catch {
720- Self . logger. warning (
721- " Metadata reconnection failed: \( error. localizedDescription) " )
722- }
723- }
724-
725590 // Restart health monitoring
726591 if session. connection. type != . sqlite {
727592 await startHealthMonitor ( for: sessionId)
0 commit comments