new tests
This commit is contained in:
+39
-50
@@ -2483,81 +2483,70 @@ private struct WorkbenchExplainView: View {
|
||||
struct ConnectionEditor: View {
|
||||
@Binding var profile: ConnectionProfile
|
||||
@Binding var password: String
|
||||
|
||||
let save: () -> Void
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var testMessage = ""
|
||||
@State private var testing = false
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 14) {
|
||||
VStack(alignment: .leading, spacing: 18) {
|
||||
HStack {
|
||||
Text("Connection Settings").font(.title2.bold())
|
||||
Label("Connection Settings", systemImage: "server.rack").font(.title2.bold())
|
||||
Spacer()
|
||||
Button { dismiss() } label: { Image(systemName: "xmark.circle.fill") }
|
||||
.buttonStyle(.borderless)
|
||||
.help("Close")
|
||||
.buttonStyle(.plain).help("Close")
|
||||
}
|
||||
|
||||
Form {
|
||||
TextField(
|
||||
"Connection Name",
|
||||
text: $profile.name
|
||||
)
|
||||
|
||||
TextField(
|
||||
"Hostname",
|
||||
text: $profile.host
|
||||
)
|
||||
|
||||
TextField("Port", value: $profile.port, format: .number.grouping(.never))
|
||||
|
||||
TextField(
|
||||
"Username",
|
||||
text: $profile.username
|
||||
)
|
||||
|
||||
SecureField(
|
||||
"Password (macOS Keychain)",
|
||||
text: $password
|
||||
)
|
||||
|
||||
TextField("Default Schema", text: $profile.database)
|
||||
Text("Remote MySQL requires a trusted SSH tunnel until native TLS support is available.")
|
||||
.font(.caption).foregroundStyle(.secondary)
|
||||
Section("MySQL") {
|
||||
TextField("Connection Name", text: $profile.name)
|
||||
TextField("Hostname", text: $profile.host)
|
||||
TextField("Port", value: $profile.port, format: .number.grouping(.never))
|
||||
TextField("Username", text: $profile.username)
|
||||
SecureField("Password (Keychain)", text: $password)
|
||||
TextField("Default Schema", text: $profile.database)
|
||||
}
|
||||
Section("Secure Transport") {
|
||||
Toggle("Connect through SSH tunnel", isOn: $profile.useSSHTunnel)
|
||||
if profile.useSSHTunnel {
|
||||
TextField("SSH Host", text: $profile.sshHost)
|
||||
TextField("SSH Port", value: $profile.sshPort, format: .number.grouping(.never))
|
||||
TextField("SSH Username", text: $profile.sshUser)
|
||||
TextField("SSH Private Key (optional)", text: $profile.sshIdentityFile)
|
||||
Text("Uses your system SSH keys and known_hosts. MySQL hostname is resolved from the SSH server.")
|
||||
.font(.caption).foregroundStyle(.secondary)
|
||||
} else {
|
||||
Text("Direct remote MySQL requires TLS, which DBSyn does not yet implement. Enable SSH for remote servers.")
|
||||
.font(.caption).foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.formStyle(.grouped)
|
||||
if !testMessage.isEmpty {
|
||||
Text(testMessage).font(.caption).foregroundStyle(.secondary)
|
||||
Text(testMessage).font(.callout).foregroundStyle(testMessage.hasPrefix("Connected") ? .green : .red)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
HStack {
|
||||
Button("Test Connection") {
|
||||
Button(testing ? "Testing…" : "Test Connection") {
|
||||
testing = true
|
||||
testMessage = ""
|
||||
let candidate = profile
|
||||
let secret = password
|
||||
Task {
|
||||
defer { testing = false }
|
||||
do {
|
||||
let result = try await NativeMySQLRunner.run(
|
||||
profile: candidate, database: candidate.database,
|
||||
password: secret, sql: "SELECT VERSION()")
|
||||
testMessage = "Connection successful: " + (result.rows.first?.first ?? "MySQL")
|
||||
let result = try await NativeMySQLRunner.run(profile: candidate, database: candidate.database, password: secret, sql: "SELECT VERSION()")
|
||||
testMessage = "Connected: " + (result.rows.first?.first ?? "MySQL")
|
||||
} catch { testMessage = error.localizedDescription }
|
||||
NativeMySQLRunner.disconnect(profileID: candidate.id)
|
||||
}
|
||||
}
|
||||
}.disabled(testing)
|
||||
Spacer()
|
||||
|
||||
Button("Cancel") {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
Button("Save") {
|
||||
save()
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
Button("Cancel") { dismiss() }
|
||||
Button("Save") { save() }.buttonStyle(.borderedProminent)
|
||||
}
|
||||
}
|
||||
.padding(24)
|
||||
.frame(width: 520)
|
||||
.frame(minWidth: 720, idealWidth: 780, minHeight: 660)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user