Skip to content
Merged
13 changes: 12 additions & 1 deletion TablePro/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ struct ContentView: View {
showAllTablesMetadata()
},
pendingTruncates: sessionPendingTruncatesBinding,
pendingDeletes: sessionPendingDeletesBinding
pendingDeletes: sessionPendingDeletesBinding,
tableOperationOptions: sessionTableOperationOptionsBinding,
databaseType: currentSession?.connection.type ?? .sqlite
)
}
.navigationSplitViewColumnWidth(min: 200, ideal: 250, max: 350)
Expand All @@ -169,6 +171,7 @@ struct ContentView: View {
selectedTables: sessionSelectedTablesBinding,
pendingTruncates: sessionPendingTruncatesBinding,
pendingDeletes: sessionPendingDeletesBinding,
tableOperationOptions: sessionTableOperationOptionsBinding,
isInspectorPresented: $isInspectorPresented
)
.id(currentSession!.id)
Expand Down Expand Up @@ -249,6 +252,14 @@ struct ContentView: View {
)
}

private var sessionTableOperationOptionsBinding: Binding<[String: TableOperationOptions]> {
createSessionBinding(
get: { $0.tableOperationOptions },
set: { $0.tableOperationOptions = $1 },
defaultValue: [:]
)
}

// MARK: - Actions

private func connectToDatabase(_ connection: DatabaseConnection) {
Expand Down
1 change: 1 addition & 0 deletions TablePro/Models/ConnectionSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct ConnectionSession: Identifiable {
var selectedTabId: UUID?
var pendingTruncates: Set<String> = []
var pendingDeletes: Set<String> = []
var tableOperationOptions: [String: TableOperationOptions] = [:]

// Metadata
let connectedAt: Date
Expand Down
7 changes: 5 additions & 2 deletions TablePro/Models/DatabaseConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,13 @@ enum DatabaseType: String, CaseIterable, Identifiable, Codable {
}
}

/// Quote an identifier (table or column name) for this database type
/// Quote an identifier (table or column name) for this database type.
/// Escapes embedded quote characters to prevent SQL injection.
func quoteIdentifier(_ name: String) -> String {
let q = identifierQuote
return "\(q)\(name)\(q)"
// Escape embedded quotes by doubling them (SQL standard)
let escaped = name.replacingOccurrences(of: q, with: q + q)
return "\(q)\(escaped)\(q)"
}
}

Expand Down
21 changes: 21 additions & 0 deletions TablePro/Models/TableOperationOptions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// TableOperationOptions.swift
// TablePro
//
// Model for table delete/truncate operation options.
// Supports foreign key constraint handling and cascade operations.
//

import Foundation

/// Options for table delete/truncate operations
struct TableOperationOptions: Codable, Equatable {
var ignoreForeignKeys: Bool = false
var cascade: Bool = false
}

/// Type of table operation
enum TableOperationType: String, Codable {
case truncate
case drop
}
Loading