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") ?? "")
|
let icon = NSImage(contentsOfFile: Bundle.main.path(forResource: "DBSynBrand", ofType: "png") ?? "")
|
||||||
NSApplication.shared.orderFrontStandardAboutPanel(options: [
|
NSApplication.shared.orderFrontStandardAboutPanel(options: [
|
||||||
.applicationName: "DBSyn",
|
.applicationName: "DBSyn",
|
||||||
.applicationIcon: icon ?? NSApplication.shared.applicationIconImage ?? NSImage(),
|
.applicationIcon: icon ?? NSApplication.shared.applicationIconImage,
|
||||||
.version: Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "1.0",
|
.version: Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "1.0",
|
||||||
.credits: NSAttributedString(string: "Native MySQL client for macOS")
|
.credits: NSAttributedString(string: "Native MySQL client for macOS")
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ struct LaravelMigrationView: View {
|
|||||||
@State private var generated = ""
|
@State private var generated = ""
|
||||||
@State private var errorText = ""
|
@State private var errorText = ""
|
||||||
@State private var tableName = ""
|
@State private var tableName = ""
|
||||||
|
@State private var chosenDatabase = ""
|
||||||
@State private var isLoading = false
|
@State private var isLoading = false
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 14) {
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
@@ -135,11 +136,46 @@ struct LaravelMigrationView: View {
|
|||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
HStack {
|
VStack(alignment: .leading, spacing: 10) {
|
||||||
TextField("Table name", text: $tableName).frame(maxWidth: 260)
|
HStack(spacing: 12) {
|
||||||
Button("Load from Connected Database") { loadTable() }.disabled(tableName.isEmpty || model.selected == nil || isLoading)
|
Text("Database").frame(width: 80, alignment: .leading)
|
||||||
Button("Open SQL File…") { openFile() }
|
Picker("Database", selection: $chosenDatabase) {
|
||||||
Spacer()
|
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 {
|
HSplitView {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
@@ -161,7 +197,19 @@ struct LaravelMigrationView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(22)
|
.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() {
|
private func generate() {
|
||||||
do { generated = try LaravelMigrationGenerator.generate(sourceSQL); errorText = "" }
|
do { generated = try LaravelMigrationGenerator.generate(sourceSQL); errorText = "" }
|
||||||
@@ -177,14 +225,21 @@ struct LaravelMigrationView: View {
|
|||||||
private func loadTable() {
|
private func loadTable() {
|
||||||
guard let profile = model.selected else { return }
|
guard let profile = model.selected else { return }
|
||||||
isLoading = true
|
isLoading = true
|
||||||
let db = model.selectedDatabase.isEmpty ? profile.database : model.selectedDatabase
|
let db = chosenDatabase.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
let escaped = tableName.replacingOccurrences(of: "`", with: "``")
|
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 {
|
Task {
|
||||||
do {
|
do {
|
||||||
let result = try await NativeMySQLRunner.run(profile: profile, database: db, password: PasswordStore.read(profile.id), sql: "SHOW CREATE TABLE `\(escaped)`")
|
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 else { throw NSError(domain: "DBSyn.Migration", code: 3, userInfo: [NSLocalizedDescriptionKey: "No table definition returned."]) }
|
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()
|
sourceSQL = ddl; generate()
|
||||||
} catch { errorText = error.localizedDescription }
|
} catch { errorText = "Could not load \(db).\(tableName): \(error.localizedDescription)" }
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user