new tests
This commit is contained in:
+1
-1
@@ -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")
|
||||
])
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user