Skip to content

Commit 1815e1d

Browse files
authored
fix(connection-form): show the right default socket path per database type (#1902) (#1904)
1 parent 656a2a4 commit 1815e1d

8 files changed

Lines changed: 85 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4040
- Fixed the query result row cap returning a single row when it was set to unlimited. (#1884)
4141
- Fixed SSH tunnels that could accept a database connection and then go quiet instead of forwarding it or failing, which showed up as MySQL and MariaDB connections timing out while reading the server greeting. A tunnel that cannot open its forwarding channel now gives up after 10 seconds, closes the connection, and logs the reason, instead of leaving the driver to wait out its own timeout with no explanation. (#1883)
4242
- Fixed connections being reset when a single database session opened several at once through one SSH tunnel, which could happen while browsing schemas. (#1883)
43+
- Fixed the connection form's SSH tunnel Socket Path hint always showing the PostgreSQL socket path. It now shows the right default for the database type, such as `/var/run/mysqld/mysqld.sock` for MySQL and MariaDB. (#1902)
4344
- Per-column display formats (Display As) are now kept per table, so two tables with the same name in different databases or schemas no longer share formatting.
4445
- Reopening a table now restores a saved filter's AND/OR match mode, instead of always resetting it to AND.
4546

TablePro/Core/Plugins/PluginManager+Registration.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ extension PluginManager {
397397
.schema.containerEntityName ?? "Database"
398398
}
399399

400+
func defaultUnixSocketPath(for databaseType: DatabaseType) -> String? {
401+
PluginMetadataRegistry.shared.snapshot(forTypeId: databaseType.pluginTypeId)?
402+
.connection.defaultUnixSocketPath
403+
}
404+
400405
func containerEntityNamePlural(for databaseType: DatabaseType) -> String {
401406
containerEntityName(for: databaseType) + "s"
402407
}

TablePro/Core/Plugins/PluginMetadataRegistry+RegistryDefaults.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ extension PluginMetadataRegistry {
152152
)
153153
],
154154
category: .keyValue,
155-
tagline: String(localized: "In-memory data store and cache")
155+
tagline: String(localized: "In-memory data store and cache"),
156+
defaultUnixSocketPath: "/var/run/redis/redis.sock"
156157
)
157158
)),
158159
("SQL Server", PluginMetadataSnapshot(

TablePro/Core/Plugins/PluginMetadataRegistry.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,20 @@ struct PluginMetadataSnapshot: Sendable {
171171
let category: DatabaseCategory
172172
let tagline: String
173173
let hidesBuiltInPassword: Bool
174+
let defaultUnixSocketPath: String?
174175

175176
init(
176177
additionalConnectionFields: [ConnectionField] = [],
177178
category: DatabaseCategory = .other,
178179
tagline: String = "",
179-
hidesBuiltInPassword: Bool = false
180+
hidesBuiltInPassword: Bool = false,
181+
defaultUnixSocketPath: String? = nil
180182
) {
181183
self.additionalConnectionFields = additionalConnectionFields
182184
self.category = category
183185
self.tagline = tagline
184186
self.hidesBuiltInPassword = hidesBuiltInPassword
187+
self.defaultUnixSocketPath = defaultUnixSocketPath
185188
}
186189

187190
static let defaults = ConnectionConfig()
@@ -543,7 +546,8 @@ final class PluginMetadataRegistry: @unchecked Sendable {
543546
connection: PluginMetadataSnapshot.ConnectionConfig(
544547
additionalConnectionFields: awsIAMFields,
545548
category: .relational,
546-
tagline: String(localized: "Most popular open-source SQL database")
549+
tagline: String(localized: "Most popular open-source SQL database"),
550+
defaultUnixSocketPath: "/var/run/mysqld/mysqld.sock"
547551
)
548552
)),
549553
("MariaDB", PluginMetadataSnapshot(
@@ -594,7 +598,8 @@ final class PluginMetadataRegistry: @unchecked Sendable {
594598
connection: PluginMetadataSnapshot.ConnectionConfig(
595599
additionalConnectionFields: awsIAMFields,
596600
category: .relational,
597-
tagline: String(localized: "Open-source fork of MySQL")
601+
tagline: String(localized: "Open-source fork of MySQL"),
602+
defaultUnixSocketPath: "/var/run/mysqld/mysqld.sock"
598603
)
599604
)),
600605
("PostgreSQL", PluginMetadataSnapshot(
@@ -646,7 +651,8 @@ final class PluginMetadataRegistry: @unchecked Sendable {
646651
connection: PluginMetadataSnapshot.ConnectionConfig(
647652
additionalConnectionFields: [pgpassField, connectionOptionsField] + awsIAMFields,
648653
category: .relational,
649-
tagline: String(localized: "Advanced object-relational SQL")
654+
tagline: String(localized: "Advanced object-relational SQL"),
655+
defaultUnixSocketPath: "/var/run/postgresql/.s.PGSQL.5432"
650656
)
651657
)),
652658
("Redshift", PluginMetadataSnapshot(
@@ -1023,7 +1029,8 @@ final class PluginMetadataRegistry: @unchecked Sendable {
10231029
?? Self.fallbackCategory(forTypeId: driverType.databaseTypeId),
10241030
tagline: existingSnapshot?.connection.tagline
10251031
?? Self.fallbackTagline(forTypeId: driverType.databaseTypeId),
1026-
hidesBuiltInPassword: existingSnapshot?.connection.hidesBuiltInPassword ?? false
1032+
hidesBuiltInPassword: existingSnapshot?.connection.hidesBuiltInPassword ?? false,
1033+
defaultUnixSocketPath: existingSnapshot?.connection.defaultUnixSocketPath
10271034
)
10281035
)
10291036
}

TablePro/Views/ConnectionForm/Panes/GeneralPaneView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ struct GeneralPaneView: View {
174174
TextField(
175175
String(localized: "Socket Path"),
176176
text: $coordinator.network.sshForwardUnixSocketPath,
177-
prompt: Text(verbatim: "/var/run/postgresql/.s.PGSQL.5432")
177+
prompt: Text(verbatim: coordinator.network.socketPathPrompt)
178178
)
179179
switch coordinator.network.socketPathIssue {
180180
case .notAbsolute:

TablePro/Views/ConnectionForm/ViewModels/NetworkPaneViewModel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ final class NetworkPaneViewModel {
4444
return port == 0 ? "" : String(port)
4545
}
4646

47+
var socketPathPrompt: String {
48+
PluginManager.shared.defaultUnixSocketPath(for: type) ?? "/path/to/database.sock"
49+
}
50+
4751
var resolvedHost: String {
4852
host.trimmingCharacters(in: .whitespaces).isEmpty ? "localhost" : host
4953
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// SocketPathPlaceholderTests.swift
3+
// TableProTests
4+
//
5+
6+
import Foundation
7+
@testable import TablePro
8+
import TableProPluginKit
9+
import Testing
10+
11+
@MainActor
12+
@Suite("Default Unix socket path per database type")
13+
struct SocketPathPlaceholderTests {
14+
@Test("MySQL and MariaDB use the mysqld socket")
15+
func mysqlFamilyUsesMysqldSocket() {
16+
#expect(PluginManager.shared.defaultUnixSocketPath(for: .mysql) == "/var/run/mysqld/mysqld.sock")
17+
#expect(PluginManager.shared.defaultUnixSocketPath(for: .mariadb) == "/var/run/mysqld/mysqld.sock")
18+
}
19+
20+
@Test("PostgreSQL uses the PGSQL socket")
21+
func postgresqlUsesPgsqlSocket() {
22+
#expect(PluginManager.shared.defaultUnixSocketPath(for: .postgresql) == "/var/run/postgresql/.s.PGSQL.5432")
23+
}
24+
25+
@Test("Redis uses the redis socket")
26+
func redisUsesRedisSocket() {
27+
#expect(PluginManager.shared.defaultUnixSocketPath(for: .redis) == "/var/run/redis/redis.sock")
28+
}
29+
30+
@Test("Types without a socket convention have no default")
31+
func typesWithoutSocketHaveNoDefault() {
32+
#expect(PluginManager.shared.defaultUnixSocketPath(for: .sqlite) == nil)
33+
#expect(PluginManager.shared.defaultUnixSocketPath(for: .clickhouse) == nil)
34+
}
35+
36+
@Test("Unknown type has no default")
37+
func unknownTypeHasNoDefault() {
38+
let unknown = DatabaseType(rawValue: "FuturePlugin")
39+
#expect(PluginManager.shared.defaultUnixSocketPath(for: unknown) == nil)
40+
}
41+
}

TableProTests/Views/ConnectionForm/NetworkPaneSocketForwardTests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,23 @@ struct NetworkPaneSocketForwardTests {
7070
#expect(fields[DatabaseConnection.sshForwardUnixSocketPathKey] == nil)
7171
#expect(viewModel.forwardsToUnixSocket == false)
7272
}
73+
74+
@Test("The socket path prompt follows the database type")
75+
func socketPromptFollowsType() {
76+
let viewModel = NetworkPaneViewModel()
77+
78+
viewModel.type = .mysql
79+
#expect(viewModel.socketPathPrompt == "/var/run/mysqld/mysqld.sock")
80+
81+
viewModel.type = .postgresql
82+
#expect(viewModel.socketPathPrompt == "/var/run/postgresql/.s.PGSQL.5432")
83+
}
84+
85+
@Test("A type without a socket convention falls back to a generic prompt")
86+
func socketPromptFallsBackForSocketlessType() {
87+
let viewModel = NetworkPaneViewModel()
88+
viewModel.type = .clickhouse
89+
90+
#expect(viewModel.socketPathPrompt == "/path/to/database.sock")
91+
}
7392
}

0 commit comments

Comments
 (0)