new tests

This commit is contained in:
Mark Gregory
2026-10-19 10:14:12 +01:00
parent 271f4a44bc
commit ab8783a1f7
2 changed files with 67 additions and 12 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ struct DBSynApp: App {
let icon = NSImage(contentsOfFile: Bundle.main.path(forResource: "DBSynBrand", ofType: "png") ?? "")
NSApplication.shared.orderFrontStandardAboutPanel(options: [
.applicationName: "DBSyn",
.applicationIcon: icon ?? NSApplication.shared.applicationIconImage ?? NSImage(),
.applicationIcon: icon ?? NSApplication.shared.applicationIconImage,
.version: Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "1.0",
.credits: NSAttributedString(string: "Native MySQL client for macOS")
])
+66 -11
View File
@@ -124,6 +124,7 @@ struct LaravelMigrationView: View {
@State private var generated = ""
@State private var errorText = ""
@State private var tableName = ""
@State private var chosenDatabase = ""
@State private var isLoading = false
var body: some View {
VStack(alignment: .leading, spacing: 14) {
@@ -135,11 +136,46 @@ struct LaravelMigrationView: View {
}
Spacer()
}
HStack {
TextField("Table name", text: $tableName).frame(maxWidth: 260)
Button("Load from Connected Database") { loadTable() }.disabled(tableName.isEmpty || model.selected == nil || isLoading)
Button("Open SQL File…") { openFile() }
Spacer()
VStack(alignment: .leading, spacing: 10) {
HStack(spacing: 12) {
Text("Database").frame(width: 80, alignment: .leading)
Picker("Database", selection: $chosenDatabase) {
Text("Select database…").tag("")
ForEach(databaseOptions, id: \.self) { name in
Text(name).tag(name)
}
}
.labelsHidden()
.frame(maxWidth: 330)
Button("Use Current Database") {
chosenDatabase = model.completionDatabase
}
.disabled(model.completionDatabase.isEmpty)
Spacer()
}
HStack(spacing: 12) {
Text("Table").frame(width: 80, alignment: .leading)
TextField("Enter a table name", text: $tableName)
.frame(maxWidth: 330)
if !availableTables.isEmpty {
Picker("Choose table", selection: $tableName) {
Text("Choose table…").tag("")
ForEach(availableTables, id: \.self) { name in
Text(name).tag(name)
}
}
.labelsHidden()
.frame(maxWidth: 230)
}
Button(isLoading ? "Loading…" : "Load Table") { loadTable() }
.disabled(tableName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || chosenDatabase.isEmpty || model.selected == nil || isLoading)
Button("Open SQL File…") { openFile() }
Spacer()
}
if chosenDatabase.isEmpty {
Text("Choose a database before loading a table. SQL files can be opened without a connection.")
.font(.caption).foregroundStyle(.secondary)
}
}
HSplitView {
VStack(alignment: .leading) {
@@ -161,7 +197,19 @@ struct LaravelMigrationView: View {
}
}
.padding(22)
.frame(minWidth: 850, minHeight: 600)
.frame(minWidth: 980, minHeight: 650)
.onAppear {
if chosenDatabase.isEmpty {
chosenDatabase = model.completionDatabase
}
}
.onChange(of: chosenDatabase) { _, _ in tableName = "" }
}
private var databaseOptions: [String] {
Array(Set(model.databases + model.schemaTables.keys + [model.completionDatabase].filter { !$0.isEmpty })).sorted()
}
private var availableTables: [String] {
model.schemaTables[chosenDatabase] ?? []
}
private func generate() {
do { generated = try LaravelMigrationGenerator.generate(sourceSQL); errorText = "" }
@@ -177,14 +225,21 @@ struct LaravelMigrationView: View {
private func loadTable() {
guard let profile = model.selected else { return }
isLoading = true
let db = model.selectedDatabase.isEmpty ? profile.database : model.selectedDatabase
let escaped = tableName.replacingOccurrences(of: "`", with: "``")
let db = chosenDatabase.trimmingCharacters(in: .whitespacesAndNewlines)
guard !db.isEmpty else {
errorText = "Select a database before loading a table."
isLoading = false
return
}
let escaped = tableName.trimmingCharacters(in: .whitespacesAndNewlines).replacingOccurrences(of: "`", with: "``")
let escapedDB = db.replacingOccurrences(of: "`", with: "``")
errorText = ""
Task {
do {
let result = try await NativeMySQLRunner.run(profile: profile, database: db, password: PasswordStore.read(profile.id), sql: "SHOW CREATE TABLE `\(escaped)`")
guard let ddl = result.rows.first?.last else { throw NSError(domain: "DBSyn.Migration", code: 3, userInfo: [NSLocalizedDescriptionKey: "No table definition returned."]) }
let result = try await NativeMySQLRunner.run(profile: profile, database: db, password: PasswordStore.read(profile.id), sql: "SHOW CREATE TABLE `\(escapedDB)`.`\(escaped)`")
guard let ddl = result.rows.first?.last, !ddl.isEmpty else { throw NSError(domain: "DBSyn.Migration", code: 3, userInfo: [NSLocalizedDescriptionKey: "No table definition returned."]) }
sourceSQL = ddl; generate()
} catch { errorText = error.localizedDescription }
} catch { errorText = "Could not load \(db).\(tableName): \(error.localizedDescription)" }
isLoading = false
}
}