Improved progress display
Previously, the progress bar updated only after completing an entire table. For large tables such as LIBARC, this could make the application appear to have stopped responding. Phase 10 updates the interface while rows are being exported.
This commit is contained in:
@@ -63,9 +63,73 @@ struct WorkbenchQueryTab: Identifiable {
|
||||
}
|
||||
}
|
||||
|
||||
struct SQLHistoryEntry: Identifiable, Codable {
|
||||
var id = UUID()
|
||||
var executedAt = Date()
|
||||
var connectionName: String
|
||||
var database: String
|
||||
var sql: String
|
||||
var succeeded: Bool
|
||||
var detail: String
|
||||
}
|
||||
|
||||
struct SavedSQLQuery: Identifiable, Codable {
|
||||
var id = UUID()
|
||||
var name: String
|
||||
var sql: String
|
||||
}
|
||||
|
||||
@MainActor
|
||||
final class DatabaseModel: ObservableObject {
|
||||
@Published var profiles: [ConnectionProfile] = []
|
||||
@Published private(set) var queryHistory: [SQLHistoryEntry] = []
|
||||
@Published private(set) var savedQueries: [SavedSQLQuery] = []
|
||||
private let historyKey = "WorkbenchReplacement.queryHistory.v1"
|
||||
private let savedQueriesKey = "WorkbenchReplacement.savedQueries.v1"
|
||||
private let maxHistoryEntries = 200
|
||||
|
||||
func saveCurrentQuery(named name: String) {
|
||||
let clean = name.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !clean.isEmpty, !sql.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
|
||||
savedQueries.insert(SavedSQLQuery(name: clean, sql: sql), at: 0)
|
||||
persistSavedQueries()
|
||||
}
|
||||
|
||||
func openSavedQuery(_ entry: SavedSQLQuery) {
|
||||
newQueryTab()
|
||||
sql = entry.sql
|
||||
if let id = activeQueryID, let index = queryTabs.firstIndex(where: { $0.id == id }) {
|
||||
queryTabs[index].title = entry.name
|
||||
queryTabs[index].sql = entry.sql
|
||||
}
|
||||
}
|
||||
|
||||
func deleteSavedQuery(_ id: UUID) {
|
||||
savedQueries.removeAll { $0.id == id }
|
||||
persistSavedQueries()
|
||||
}
|
||||
|
||||
func clearQueryHistory() {
|
||||
queryHistory.removeAll()
|
||||
UserDefaults.standard.removeObject(forKey: historyKey)
|
||||
}
|
||||
|
||||
private func persistSavedQueries() {
|
||||
if let data = try? JSONEncoder().encode(savedQueries) {
|
||||
UserDefaults.standard.set(data, forKey: savedQueriesKey)
|
||||
}
|
||||
}
|
||||
|
||||
private func recordQuery(_ statement: String, profile: ConnectionProfile, database: String, succeeded: Bool, detail: String) {
|
||||
queryHistory.insert(SQLHistoryEntry(connectionName: profile.name, database: database, sql: statement, succeeded: succeeded, detail: detail), at: 0)
|
||||
if queryHistory.count > maxHistoryEntries {
|
||||
queryHistory.removeLast(queryHistory.count - maxHistoryEntries)
|
||||
}
|
||||
if let data = try? JSONEncoder().encode(queryHistory) {
|
||||
UserDefaults.standard.set(data, forKey: historyKey)
|
||||
}
|
||||
}
|
||||
|
||||
@Published var selectedID: UUID?
|
||||
@Published var queryTabs: [WorkbenchQueryTab] = [
|
||||
WorkbenchQueryTab(
|
||||
@@ -80,11 +144,20 @@ final class DatabaseModel: ObservableObject {
|
||||
@Published var schemaTables: [String: [String]] = [:]
|
||||
@Published var schemaViews: [String: [String]] = [:]
|
||||
@Published var selectedDatabase = ""
|
||||
@Published var queryDurationText = ""
|
||||
@Published var isRunning = false
|
||||
@Published var status = "Not connected"
|
||||
private let storageKey = "WorkbenchReplacement.connectionProfiles.native.v1"
|
||||
|
||||
init() {
|
||||
if let data = UserDefaults.standard.data(forKey: historyKey),
|
||||
let entries = try? JSONDecoder().decode([SQLHistoryEntry].self, from: data) {
|
||||
queryHistory = Array(entries.prefix(maxHistoryEntries))
|
||||
}
|
||||
if let data = UserDefaults.standard.data(forKey: savedQueriesKey),
|
||||
let entries = try? JSONDecoder().decode([SavedSQLQuery].self, from: data) {
|
||||
savedQueries = entries
|
||||
}
|
||||
if let data = UserDefaults.standard.data(forKey: storageKey),
|
||||
let decoded = try? JSONDecoder().decode([ConnectionProfile].self, from: data) { profiles = decoded }
|
||||
if profiles.isEmpty { profiles = [ConnectionProfile()] }
|
||||
@@ -296,10 +369,16 @@ final class DatabaseModel: ObservableObject {
|
||||
}
|
||||
execute(sql, listingDatabases: false)
|
||||
}
|
||||
func runSQL(statement: String) {
|
||||
guard !statement.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
|
||||
execute(statement, listingDatabases: false)
|
||||
}
|
||||
private func execute(_ statement: String, listingDatabases: Bool) {
|
||||
guard let profile = selected else { status = "Select a connection"; return }
|
||||
guard !statement.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
|
||||
isRunning = true
|
||||
if !listingDatabases { queryDurationText = "Running…" }
|
||||
let queryStarted = Date()
|
||||
status = "Connecting…"
|
||||
let activeDB = listingDatabases ? "" : (selectedDatabase.isEmpty ? profile.database : selectedDatabase)
|
||||
let password = PasswordStore.read(profile.id)
|
||||
@@ -317,10 +396,17 @@ final class DatabaseModel: ObservableObject {
|
||||
queryTabs[index].result = parsed
|
||||
}
|
||||
status = "Query completed (\(parsed.rows.count) rows)"
|
||||
recordQuery(statement, profile: profile, database: activeDB, succeeded: true, detail: status)
|
||||
}
|
||||
} catch {
|
||||
status = "Error"
|
||||
result = QueryResult(message: error.localizedDescription)
|
||||
if !listingDatabases {
|
||||
recordQuery(statement, profile: profile, database: activeDB, succeeded: false, detail: error.localizedDescription)
|
||||
}
|
||||
}
|
||||
if !listingDatabases {
|
||||
queryDurationText = String(format: "%.3f s", Date().timeIntervalSince(queryStarted))
|
||||
}
|
||||
isRunning = false
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import SwiftUI
|
||||
import AppKit
|
||||
import CryptoKit
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
// MARK: - Classic Workbench Colours
|
||||
|
||||
@@ -25,8 +26,16 @@ private enum WB {
|
||||
struct MainView: View {
|
||||
@EnvironmentObject private var model: DatabaseModel
|
||||
|
||||
@State private var selectedSQL = ""
|
||||
@State private var resultFilter = ""
|
||||
@State private var resultSortColumn = 0
|
||||
@State private var resultSortAscending = true
|
||||
@State private var showingEditor = false
|
||||
@State private var showingDatabaseTransfer = false
|
||||
@State private var showingQueryHistory = false
|
||||
@State private var showingSavedQueries = false
|
||||
@State private var showingSaveQuery = false
|
||||
@State private var newSavedQueryName = ""
|
||||
|
||||
@State private var editing = ConnectionProfile()
|
||||
@State private var editingPassword = ""
|
||||
@@ -74,6 +83,19 @@ struct MainView: View {
|
||||
model.loadDatabases()
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showingQueryHistory) {
|
||||
SQLHistorySheet(model: model)
|
||||
}
|
||||
.sheet(isPresented: $showingSavedQueries) {
|
||||
SavedSQLQueriesSheet(model: model)
|
||||
}
|
||||
.alert("Save SQL Query", isPresented: $showingSaveQuery) {
|
||||
TextField("Query name", text: $newSavedQueryName)
|
||||
Button("Save") { model.saveCurrentQuery(named: newSavedQueryName) }
|
||||
Button("Cancel", role: .cancel) { }
|
||||
} message: {
|
||||
Text("Save the current SQL in your local query library.")
|
||||
}
|
||||
.sheet(isPresented: $showingDatabaseTransfer) {
|
||||
WorkbenchDatabaseTransferView(model: model)
|
||||
}
|
||||
@@ -650,6 +672,14 @@ struct MainView: View {
|
||||
}
|
||||
.help("Execute SQL")
|
||||
|
||||
Button {
|
||||
model.runSQL(statement: selectedSQL)
|
||||
} label: {
|
||||
Label("Run Selection", systemImage: "selection.pin.in.out")
|
||||
}
|
||||
.disabled(selectedSQL.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
|
||||
.help("Execute selected SQL without modifying the editor")
|
||||
|
||||
Button {
|
||||
model.formatSQL()
|
||||
} label: {
|
||||
@@ -660,6 +690,30 @@ struct MainView: View {
|
||||
Divider()
|
||||
.frame(height: 17)
|
||||
|
||||
Button {
|
||||
showingQueryHistory = true
|
||||
} label: {
|
||||
Label("History", systemImage: "clock.arrow.circlepath")
|
||||
}
|
||||
.help("Query execution history")
|
||||
|
||||
Button {
|
||||
showingSavedQueries = true
|
||||
} label: {
|
||||
Label("Saved", systemImage: "bookmark")
|
||||
}
|
||||
.help("Open saved SQL queries")
|
||||
|
||||
Button {
|
||||
newSavedQueryName = ""
|
||||
showingSaveQuery = true
|
||||
} label: {
|
||||
Image(systemName: "bookmark.fill")
|
||||
}
|
||||
.help("Save current SQL query")
|
||||
|
||||
Divider().frame(height: 17)
|
||||
|
||||
Text("Default Schema:")
|
||||
.font(.system(size: 11))
|
||||
|
||||
@@ -696,7 +750,7 @@ struct MainView: View {
|
||||
.fill(WB.border)
|
||||
.frame(width: 1)
|
||||
|
||||
SQLTextView(text: $model.sql)
|
||||
SQLTextView(text: $model.sql, selectedSQL: $selectedSQL, completions: Array(Set(model.schemaTables.values.flatMap { $0 } + model.schemaViews.values.flatMap { $0 })).sorted())
|
||||
}
|
||||
.background(Color(nsColor: .textBackgroundColor))
|
||||
}
|
||||
@@ -747,6 +801,23 @@ struct MainView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
if !model.result.columns.isEmpty {
|
||||
TextField("Filter rows", text: $resultFilter)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
.frame(width: 170)
|
||||
Picker("Sort", selection: $resultSortColumn) {
|
||||
ForEach(model.result.columns.indices, id: \.self) { index in
|
||||
Text(model.result.columns[index]).tag(index)
|
||||
}
|
||||
}
|
||||
.frame(width: 155)
|
||||
Button(resultSortAscending ? "Ascending" : "Descending") {
|
||||
resultSortAscending.toggle()
|
||||
}
|
||||
Button("Export CSV") { exportResultCSV() }
|
||||
}
|
||||
Text(model.queryDurationText)
|
||||
.foregroundStyle(.secondary)
|
||||
Text(model.result.message)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
@@ -772,10 +843,41 @@ struct MainView: View {
|
||||
|
||||
|
||||
private var resultGrid: some View {
|
||||
NativeResultGrid(
|
||||
columns: model.result.columns,
|
||||
rows: model.result.rows
|
||||
)
|
||||
NativeResultGrid(columns: model.result.columns, rows: displayedRows)
|
||||
}
|
||||
|
||||
private var displayedRows: [[String]] {
|
||||
let filtered = resultFilter.isEmpty ? model.result.rows : model.result.rows.filter { row in
|
||||
row.contains { $0.localizedCaseInsensitiveContains(resultFilter) }
|
||||
}
|
||||
guard !model.result.columns.isEmpty else { return filtered }
|
||||
let index = min(resultSortColumn, model.result.columns.count - 1)
|
||||
return filtered.sorted { left, right in
|
||||
let a = index < left.count ? left[index] : ""
|
||||
let b = index < right.count ? right[index] : ""
|
||||
let comparison = a.localizedStandardCompare(b)
|
||||
return resultSortAscending ? comparison == .orderedAscending : comparison == .orderedDescending
|
||||
}
|
||||
}
|
||||
|
||||
private func exportResultCSV() {
|
||||
let panel = NSSavePanel()
|
||||
panel.nameFieldStringValue = "query-results.csv"
|
||||
panel.allowedContentTypes = [.commaSeparatedText]
|
||||
guard panel.runModal() == .OK, let url = panel.url else { return }
|
||||
func field(_ value: String) -> String {
|
||||
"\"" + value.replacingOccurrences(of: "\"", with: "\"\"") + "\""
|
||||
}
|
||||
let lines = ([model.result.columns] + displayedRows).map { row in
|
||||
row.map(field).joined(separator: ",")
|
||||
}
|
||||
do {
|
||||
try ("\u{FEFF}" + lines.joined(separator: "\r\n") + "\r\n")
|
||||
.write(to: url, atomically: true, encoding: .utf8)
|
||||
model.status = "Exported \(displayedRows.count) rows to \(url.lastPathComponent)"
|
||||
} catch {
|
||||
model.status = "CSV export failed: \(error.localizedDescription)"
|
||||
}
|
||||
}
|
||||
|
||||
private var actionOutput: some View {
|
||||
@@ -885,10 +987,107 @@ struct MainView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Phase 17: Query History and Saved Queries
|
||||
|
||||
private struct SQLHistorySheet: View {
|
||||
@ObservedObject var model: DatabaseModel
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var filter = ""
|
||||
|
||||
private var entries: [SQLHistoryEntry] {
|
||||
model.queryHistory.filter {
|
||||
filter.isEmpty || $0.sql.localizedCaseInsensitiveContains(filter) ||
|
||||
$0.connectionName.localizedCaseInsensitiveContains(filter)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Text("Query History").font(.title2).bold()
|
||||
Spacer()
|
||||
Button("Clear History") { model.clearQueryHistory() }
|
||||
.disabled(model.queryHistory.isEmpty)
|
||||
Button("Done") { dismiss() }
|
||||
}
|
||||
TextField("Filter SQL or connection", text: $filter)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
List(entries) { entry in
|
||||
VStack(alignment: .leading, spacing: 5) {
|
||||
HStack {
|
||||
Image(systemName: entry.succeeded ? "checkmark.circle.fill" : "xmark.circle.fill")
|
||||
.foregroundStyle(entry.succeeded ? .green : .red)
|
||||
Text(entry.executedAt, style: .date)
|
||||
Text(entry.executedAt, style: .time)
|
||||
Text(entry.connectionName).foregroundStyle(.secondary)
|
||||
Text(entry.database).foregroundStyle(.secondary)
|
||||
Spacer()
|
||||
Button("Open in New Tab") {
|
||||
model.newQueryTab()
|
||||
model.sql = entry.sql
|
||||
model.saveActiveQuery()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
Text(entry.sql).font(.system(.body, design: .monospaced))
|
||||
.lineLimit(3).textSelection(.enabled)
|
||||
Text(entry.detail).font(.caption).foregroundStyle(.secondary)
|
||||
}.padding(.vertical, 4)
|
||||
}
|
||||
}
|
||||
.padding(20)
|
||||
.frame(minWidth: 740, minHeight: 460)
|
||||
}
|
||||
}
|
||||
|
||||
private struct SavedSQLQueriesSheet: View {
|
||||
@ObservedObject var model: DatabaseModel
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var filter = ""
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Text("Saved SQL Queries").font(.title2).bold()
|
||||
Spacer()
|
||||
Button("Done") { dismiss() }
|
||||
}
|
||||
TextField("Filter saved queries", text: $filter)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
List(model.savedQueries.filter {
|
||||
filter.isEmpty || $0.name.localizedCaseInsensitiveContains(filter) ||
|
||||
$0.sql.localizedCaseInsensitiveContains(filter)
|
||||
}) { entry in
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(entry.name).font(.headline)
|
||||
Text(entry.sql).font(.system(.caption, design: .monospaced))
|
||||
.lineLimit(2).foregroundStyle(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
Button("Open") {
|
||||
model.openSavedQuery(entry)
|
||||
dismiss()
|
||||
}
|
||||
Button(role: .destructive) {
|
||||
model.deleteSavedQuery(entry.id)
|
||||
} label: {
|
||||
Image(systemName: "trash")
|
||||
}
|
||||
}.padding(.vertical, 5)
|
||||
}
|
||||
}
|
||||
.padding(20)
|
||||
.frame(minWidth: 650, minHeight: 420)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Native SQL Text Editor
|
||||
|
||||
struct SQLTextView: NSViewRepresentable {
|
||||
@Binding var text: String
|
||||
@Binding var selectedSQL: String
|
||||
var completions: [String] = []
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(self)
|
||||
@@ -961,6 +1160,39 @@ struct SQLTextView: NSViewRepresentable {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
private let completionWords = [
|
||||
"SELECT", "FROM", "WHERE", "INSERT INTO", "UPDATE", "DELETE FROM",
|
||||
"CREATE TABLE", "ALTER TABLE", "DROP TABLE", "JOIN", "LEFT JOIN",
|
||||
"INNER JOIN", "GROUP BY", "ORDER BY", "HAVING", "LIMIT",
|
||||
"DISTINCT", "COUNT", "SUM", "AVG", "MIN", "MAX", "AS",
|
||||
"AND", "OR", "NOT", "NULL", "IS NULL", "LIKE", "IN",
|
||||
"BETWEEN", "EXISTS", "UNION", "WITH", "CASE", "WHEN", "THEN",
|
||||
"ELSE", "END", "SHOW TABLES", "SHOW DATABASES", "DESCRIBE",
|
||||
"EXPLAIN", "PRIMARY KEY", "FOREIGN KEY", "INDEX", "VALUES"
|
||||
]
|
||||
|
||||
func textView(_ textView: NSTextView, completions words: [String],
|
||||
forPartialWordRange charRange: NSRange,
|
||||
indexOfSelectedItem index: UnsafeMutablePointer<Int>?) -> [String] {
|
||||
let text = textView.string as NSString
|
||||
guard charRange.location != NSNotFound,
|
||||
NSMaxRange(charRange) <= text.length else { return [] }
|
||||
let prefix = text.substring(with: charRange)
|
||||
guard !prefix.isEmpty else { return [] }
|
||||
return Array(Set(completionWords + parent.completions))
|
||||
.filter { $0.range(of: prefix, options: [.anchored, .caseInsensitive]) != nil }
|
||||
.sorted()
|
||||
}
|
||||
|
||||
func textViewDidChangeSelection(_ notification: Notification) {
|
||||
guard let editor = notification.object as? NSTextView else { return }
|
||||
let range = editor.selectedRange()
|
||||
let value = editor.string as NSString
|
||||
let selection = range.length > 0 && NSMaxRange(range) <= value.length
|
||||
? value.substring(with: range) : ""
|
||||
if parent.selectedSQL != selection { parent.selectedSQL = selection }
|
||||
}
|
||||
|
||||
func textDidChange(_ notification: Notification) {
|
||||
guard let editor = notification.object as? NSTextView else {
|
||||
return
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+327
-119
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
@rpath/WorkbenchReplacement.debug.dylib
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
</plist>
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"" : {
|
||||
"diagnostics" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/WorkbenchReplacement-primary.dia",
|
||||
"emit-module-dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/WorkbenchReplacement-primary-emit-module.d",
|
||||
"emit-module-diagnostics" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/WorkbenchReplacement-primary-emit-module.dia",
|
||||
"pch" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/WorkbenchReplacement-primary-Bridging-header.pch",
|
||||
"swift-dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/WorkbenchReplacement-primary.swiftdeps"
|
||||
},
|
||||
"/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/App.swift" : {
|
||||
"const-values" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.swiftconstvalues",
|
||||
"dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.d",
|
||||
"diagnostics" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.dia",
|
||||
"index-unit-output-path" : "/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.o",
|
||||
"llvm-bc" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.bc",
|
||||
"object" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.o",
|
||||
"swift-dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.swiftdeps",
|
||||
"swiftmodule" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App~partial.swiftmodule"
|
||||
},
|
||||
"/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/DatabaseModel.swift" : {
|
||||
"const-values" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.swiftconstvalues",
|
||||
"dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.d",
|
||||
"diagnostics" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.dia",
|
||||
"index-unit-output-path" : "/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.o",
|
||||
"llvm-bc" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.bc",
|
||||
"object" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.o",
|
||||
"swift-dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.swiftdeps",
|
||||
"swiftmodule" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel~partial.swiftmodule"
|
||||
},
|
||||
"/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/MainView.swift" : {
|
||||
"const-values" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.swiftconstvalues",
|
||||
"dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.d",
|
||||
"diagnostics" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.dia",
|
||||
"index-unit-output-path" : "/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.o",
|
||||
"llvm-bc" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.bc",
|
||||
"object" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.o",
|
||||
"swift-dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.swiftdeps",
|
||||
"swiftmodule" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView~partial.swiftmodule"
|
||||
},
|
||||
"/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/MySQLProtocol.swift" : {
|
||||
"const-values" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.swiftconstvalues",
|
||||
"dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.d",
|
||||
"diagnostics" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.dia",
|
||||
"index-unit-output-path" : "/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.o",
|
||||
"llvm-bc" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.bc",
|
||||
"object" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.o",
|
||||
"swift-dependencies" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.swiftdeps",
|
||||
"swiftmodule" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol~partial.swiftmodule"
|
||||
}
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"case-sensitive":"false","roots":[],"version":0}
|
||||
-1
@@ -1 +0,0 @@
|
||||
["AnyResolverProviding","AppEntity","AppEnum","AppExtension","AppIntent","AppIntentsPackage","AppShortcutProviding","AppShortcutsProvider","AppUnionValue","AppUnionValueCasesProviding","DynamicOptionsProvider","EntityQuery","ExtensionPointDefining","IntentValueQuery","Resolver","TransientEntity","_AssistantIntentsProvider","_GenerativeFunctionExtractable","_IntentValueRepresentable"]
|
||||
BIN
Binary file not shown.
-4
@@ -1,4 +0,0 @@
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.o
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.o
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.o
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.o
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/App.swiftconstvalues
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MainView.swiftconstvalues
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/DatabaseModel.swiftconstvalues
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/WorkbenchReplacement.build/Debug/WorkbenchReplacement.build/Objects-normal/arm64/MySQLProtocol.swiftconstvalues
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/App.swift
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/MainView.swift
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/DatabaseModel.swift
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement/MySQLProtocol.swift
|
||||
-1
@@ -1 +0,0 @@
|
||||
WorkbenchReplacement.debug.dylib
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.get-task-allow</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
-68
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"buildCommand" : {
|
||||
"command" : "build",
|
||||
"skipDependencies" : false,
|
||||
"style" : "buildOnly"
|
||||
},
|
||||
"configuredTargets" : [
|
||||
{
|
||||
"guid" : "34f2007b1d0798da0712fb82baec90fb2878cdfbaa5fcb5fa30c8485a83dfb14"
|
||||
}
|
||||
],
|
||||
"containerPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement.xcodeproj",
|
||||
"continueBuildingAfterErrors" : false,
|
||||
"dependencyScope" : "workspace",
|
||||
"enableIndexBuildArena" : false,
|
||||
"hideShellScriptEnvironment" : false,
|
||||
"parameters" : {
|
||||
"action" : "build",
|
||||
"activeArchitecture" : "arm64",
|
||||
"activeRunDestination" : {
|
||||
"disableOnlyActiveArch" : false,
|
||||
"hostTargetedPlatform" : null,
|
||||
"platform" : "macosx",
|
||||
"sdk" : "macosx27.0",
|
||||
"sdkVariant" : "macos",
|
||||
"supportedArchitectures" : [
|
||||
"arm64e",
|
||||
"arm64",
|
||||
"x86_64"
|
||||
],
|
||||
"targetArchitecture" : "arm64"
|
||||
},
|
||||
"arenaInfo" : {
|
||||
"buildIntermediatesPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex",
|
||||
"buildProductsPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Products",
|
||||
"derivedDataPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/build",
|
||||
"indexDataStoreFolderPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Index.noindex/DataStore",
|
||||
"indexEnableDataStore" : true,
|
||||
"indexPCHPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Index.noindex/PrecompiledHeaders",
|
||||
"pchPath" : "/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Intermediates.noindex/PrecompiledHeaders"
|
||||
},
|
||||
"configurationName" : "Debug",
|
||||
"overrides" : {
|
||||
"commandLine" : {
|
||||
"table" : {
|
||||
|
||||
}
|
||||
},
|
||||
"synthesized" : {
|
||||
"table" : {
|
||||
"ACTION" : "build",
|
||||
"COLOR_DIAGNOSTICS" : "YES",
|
||||
"diagnostic_message_length" : "162",
|
||||
"ENABLE_PREVIEWS" : "NO",
|
||||
"ENABLE_XOJIT_PREVIEWS" : "YES",
|
||||
"ONLY_ACTIVE_ARCH" : "YES",
|
||||
"TOOLCHAINS" : "com.apple.dt.toolchain.Metal.32023.921.5 $(inherited)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schemeCommand" : "launch",
|
||||
"showNonLoggedProgress" : true,
|
||||
"useDryRun" : false,
|
||||
"useImplicitDependencies" : true,
|
||||
"useLegacyBuildLocations" : false,
|
||||
"useParallelTargets" : true
|
||||
}
|
||||
BIN
Binary file not shown.
-1
File diff suppressed because one or more lines are too long
-2
@@ -1,2 +0,0 @@
|
||||
Target dependency graph (1 target)
|
||||
Target 'WorkbenchReplacement' in project 'WorkbenchReplacement' (no dependencies)
|
||||
BIN
Binary file not shown.
@@ -3,3 +3,5 @@ fde3a409a1c7aaa1a5eda9dfaf1056e0
|
||||
1c438df96f25657d77b9e55a3fe47133
|
||||
120e9a8ae12faa2f3ba3b63c6df49ba3
|
||||
a06f417aacd1b83f24bd3cc2cf22ad87
|
||||
7f733ee9c557a22c77228b85d3bb3f5e
|
||||
a06f417aacd1b83f24bd3cc2cf22ad87
|
||||
|
||||
@@ -22,3 +22,5 @@
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Products/Debug/WorkbenchReplacement.app
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Products/Debug/WorkbenchReplacement.app
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Products/Debug/WorkbenchReplacement.app
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Products/Debug/WorkbenchReplacement.app
|
||||
/Volumes/Developer/Applications/WorkbenchReplacement/build/Build/Products/Debug/WorkbenchReplacement.app
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
+1
-1
@@ -19,7 +19,7 @@
|
||||
<dict>
|
||||
<key>cdhash</key>
|
||||
<data>
|
||||
/SGo73prsJFq4QMPB62FM4xJVmQ=
|
||||
CrXwZueWbUElb06KAtY+Fe92gXA=
|
||||
</data>
|
||||
<key>requirement</key>
|
||||
<string>identifier "WorkbenchReplacement.debug" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Mark Gregory (FLBRJ3BYDD)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -6,6 +6,48 @@
|
||||
<integer>13</integer>
|
||||
<key>logs</key>
|
||||
<dict>
|
||||
<key>04704647-E534-492A-ADC4-87C265C050C8</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
<key>documentTypeString</key>
|
||||
<string><nil></string>
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>04704647-E534-492A-ADC4-87C265C050C8.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>E</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>1</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>schemeIdentifier-containerName</key>
|
||||
<string>WorkbenchReplacement project</string>
|
||||
<key>schemeIdentifier-schemeName</key>
|
||||
<string>WorkbenchReplacement</string>
|
||||
<key>schemeIdentifier-sharedScheme</key>
|
||||
<integer>1</integer>
|
||||
<key>signature</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>813879039.75688195</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>813879050.66503203</real>
|
||||
<key>title</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>04704647-E534-492A-ADC4-87C265C050C8</string>
|
||||
</dict>
|
||||
<key>0BE3AE4B-CC13-4C5D-9DA7-73BB03242CE6</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
@@ -48,6 +90,90 @@
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>0BE3AE4B-CC13-4C5D-9DA7-73BB03242CE6</string>
|
||||
</dict>
|
||||
<key>546596EB-C774-4242-A9D1-C86D46C7CAE8</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
<key>documentTypeString</key>
|
||||
<string><nil></string>
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>546596EB-C774-4242-A9D1-C86D46C7CAE8.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>S</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>schemeIdentifier-containerName</key>
|
||||
<string>WorkbenchReplacement project</string>
|
||||
<key>schemeIdentifier-schemeName</key>
|
||||
<string>WorkbenchReplacement</string>
|
||||
<key>schemeIdentifier-sharedScheme</key>
|
||||
<integer>1</integer>
|
||||
<key>signature</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>813879115.19696796</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>813879130.83529198</real>
|
||||
<key>title</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>546596EB-C774-4242-A9D1-C86D46C7CAE8</string>
|
||||
</dict>
|
||||
<key>67C568D7-BB93-4240-AB48-EF7CBFC85D9F</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
<key>documentTypeString</key>
|
||||
<string><nil></string>
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>67C568D7-BB93-4240-AB48-EF7CBFC85D9F.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>S</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>schemeIdentifier-containerName</key>
|
||||
<string>WorkbenchReplacement project</string>
|
||||
<key>schemeIdentifier-schemeName</key>
|
||||
<string>WorkbenchReplacement</string>
|
||||
<key>schemeIdentifier-sharedScheme</key>
|
||||
<integer>1</integer>
|
||||
<key>signature</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>813879245.19600403</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>813879260.71434796</real>
|
||||
<key>title</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>67C568D7-BB93-4240-AB48-EF7CBFC85D9F</string>
|
||||
</dict>
|
||||
<key>A5DCBFE5-D4F5-45BE-8C98-8AC35E432D50</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
@@ -90,7 +216,7 @@
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>A5DCBFE5-D4F5-45BE-8C98-8AC35E432D50</string>
|
||||
</dict>
|
||||
<key>BE675D45-226B-48D5-9BED-8FCC12B530FF</key>
|
||||
<key>D9A8286B-C5F6-4640-8996-6E78F7FFA481</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
@@ -99,17 +225,17 @@
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>BE675D45-226B-48D5-9BED-8FCC12B530FF.xcactivitylog</string>
|
||||
<string>D9A8286B-C5F6-4640-8996-6E78F7FFA481.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>S</string>
|
||||
<string>E</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
@@ -124,13 +250,13 @@
|
||||
<key>signature</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>813878365.00770497</real>
|
||||
<real>813879086.34161401</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>813878379.89619505</real>
|
||||
<real>813879089.726318</real>
|
||||
<key>title</key>
|
||||
<string>Building project WorkbenchReplacement with scheme WorkbenchReplacement and configuration Debug</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>BE675D45-226B-48D5-9BED-8FCC12B530FF</string>
|
||||
<string>D9A8286B-C5F6-4640-8996-6E78F7FFA481</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1792186032.67269: Module build session file for module cache at Path(str: "/Volumes/Developer/Applications/WorkbenchReplacement/build/ModuleCache.noindex")
|
||||
1792186445.60443: Module build session file for module cache at Path(str: "/Volumes/Developer/Applications/WorkbenchReplacement/build/ModuleCache.noindex")
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LastAccessedDate</key>
|
||||
<date>2026-10-16T21:27:12Z</date>
|
||||
<date>2026-10-16T21:34:05Z</date>
|
||||
<key>WorkspacePath</key>
|
||||
<string>/Volumes/Developer/Applications/WorkbenchReplacement/WorkbenchReplacement.xcodeproj</string>
|
||||
</dict>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Phase 17 — SQL Editor Productivity
|
||||
|
||||
- Added persisted query execution history (latest 200 statements), including timestamp, connection, schema, success/failure, and error details. Schema-list refreshes are not recorded.
|
||||
- Added History panel with filtering, reopen in a new tab, and clear history.
|
||||
- Added a persistent saved SQL query library, with save, filter, open, and delete.
|
||||
- Added AppKit SQL keyword completion via NSTextViewDelegate's standard completion interface (typically Esc or Option-Esc depending on macOS key bindings). Completions are keyword-based, not live schema-aware.
|
||||
- Preserved the existing SQL syntax highlighting and query tab handling.
|
||||
|
||||
## Caveats
|
||||
|
||||
History and saved SQL are stored in local UserDefaults and may contain sensitive SQL text; avoid executing statements containing literal secrets if local history retention is a concern. Results remain subject to the existing protocol row cap. This phase has not been built in Xcode or tested against a live server.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Phase 18 — SQL Editor and Result Grid
|
||||
|
||||
Built from the Phase 17 project archive and includes the correction for the Phase 17 `localizedCaseInsensitiveHasPrefix` compilation error.
|
||||
|
||||
## Changes
|
||||
- Execute highlighted SQL independently of the complete editor buffer (Run Selection).
|
||||
- SQL completion includes cached table and view names loaded in the Schemas navigator, alongside SQL keywords. Column-aware suggestions are not yet implemented.
|
||||
- Case-insensitive local filtering of query result rows.
|
||||
- Local result sorting by chosen column, ascending or descending.
|
||||
- CSV export of the currently displayed rows, with RFC-style doubled quotes, UTF-8 BOM and CRLF line endings.
|
||||
- Query elapsed wall-clock time, shown after execution completes (includes connection overhead).
|
||||
|
||||
## Limitations
|
||||
- Result grid filters/sorts operate only on rows returned by the existing query engine, not the full database table.
|
||||
- The CSV writer constructs the file in memory and should not be used for huge result sets.
|
||||
- SQL autocomplete suggestions depend on schemas already loaded; no column metadata is fetched.
|
||||
- No new SQL error underlining was added.
|
||||
- Not compiled on macOS or tested against a MySQL server; run xcodebuild on the Mac.
|
||||
Reference in New Issue
Block a user