From 499dd49ec27d0a4f4c9377f598764e3eb2eb4e34 Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Tue, 20 Oct 2026 09:04:25 +0100 Subject: [PATCH] connection updates --- DBSyn/MainView.swift | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/DBSyn/MainView.swift b/DBSyn/MainView.swift index d48a07c..77bac4f 100644 --- a/DBSyn/MainView.swift +++ b/DBSyn/MainView.swift @@ -1228,7 +1228,7 @@ struct MainView: View { // Arbitrary joins, expressions and aliases cannot be mapped safely to rows. private var editableResultTarget: (database: String, table: String)? { let statements = model.sql.components(separatedBy: ";") - guard let select = statements.last(where: { $0.range(of: #"(?i)\bSELECT\b"#, options: .regularExpression) != nil }) else { return nil } + guard let select = statements.last(where: { $0.range(of: #"(?i)^\s*SELECT\b"#, options: .regularExpression) != nil }) else { return nil } // Permit ordinary filtered/sorted single-table SELECT * results. The // primary-key checks in DBSynInlineRowEditor still guard every UPDATE. // Joins, grouping, unions and computed result sets remain read-only. @@ -1250,8 +1250,8 @@ struct MainView: View { let table = parts.last ?? "" guard !database.isEmpty, let snapshot = model.introspection(for: database), snapshot.tables.contains(where: { $0.caseInsensitiveCompare(table) == .orderedSame }), - let fields = snapshot.columnsByTable[table], - fields.map(\.name).map({ $0.lowercased() }) == model.result.columns.map({ $0.lowercased() }), + let fields = snapshot.columnsByTable.first(where: { $0.key.caseInsensitiveCompare(table) == .orderedSame })?.value, + Set(fields.map { $0.name.lowercased() }) == Set(model.result.columns.map { $0.lowercased() }), fields.contains(where: { $0.key == "PRI" }) else { return nil } return (database, table) } @@ -2637,6 +2637,8 @@ struct NativeResultGrid: NSViewRepresentable { table.menu = menu table.delegate = context.coordinator + table.target = context.coordinator + table.doubleAction = #selector(Coordinator.doubleClickedRow(_:)) table.dataSource = context.coordinator configureColumns(table, hiddenIndices: hiddenColumnIndices) @@ -2713,6 +2715,11 @@ struct NativeResultGrid: NSViewRepresentable { var onEdit: (([String]) -> Void)? weak var tableView: NSTableView? + @objc func doubleClickedRow(_ sender: Any?) { + guard let table = tableView, rows.indices.contains(table.clickedRow) else { return } + onEdit?(rows[table.clickedRow]) + } + @objc func editClickedRow(_ sender: NSMenuItem) { guard let table = tableView else { return } let index = table.clickedRow >= 0 ? table.clickedRow : table.selectedRow @@ -7690,7 +7697,7 @@ private struct DBSynInlineRowEditor: View { } private var metadata: [DatabaseModel.IntrospectedColumn] { - model.introspection(for: database)?.columnsByTable[table] ?? [] + model.introspection(for: database)?.columnsByTable.first(where: { $0.key.caseInsensitiveCompare(table) == .orderedSame })?.value ?? [] } private var primaryIndices: [Int] { @@ -7723,7 +7730,7 @@ private struct DBSynInlineRowEditor: View { // "NULL". Never generate SQL when this representation is ambiguous. let checked = Set(primaryIndices + changedIndices) for i in checked { - if metadata[i].nullable && original[i] == "NULL" { + if metadata.contains(where: { $0.name.caseInsensitiveCompare(columns[i]) == .orderedSame && $0.nullable }) && original[i] == "NULL" { return "Column \(columns[i]) may contain SQL NULL. Editing ambiguous NULL values is disabled." } }