-
-
Notifications
You must be signed in to change notification settings - Fork 285
feat: add table export functionality #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
19e3d38
feat: add table export functionality with CSV, JSON, and SQL formats
datlechin d88070a
Update TablePro/Core/Services/ExportService.swift
datlechin 94d73c0
Update TablePro/Core/Services/ExportService.swift
datlechin 9901b82
Update TablePro/Views/Export/ExportCSVOptionsView.swift
datlechin 9d61999
Update TablePro/Core/Services/ExportService.swift
datlechin 85cb44a
fix: address code review feedback
datlechin 376d0c9
refactor: unify sidebar context menus into single function
datlechin fc68f11
fix: address all code review issues
datlechin a457b5e
Update TablePro/Core/Services/ExportService.swift
datlechin baed5e7
Update TablePro/Core/Services/ExportService.swift
datlechin 94eb180
Update TablePro/Core/Services/ExportService.swift
datlechin fe05cfa
Update TablePro/Views/Export/ExportSuccessView.swift
datlechin d1db29e
Update TablePro/Core/Services/ExportService.swift
datlechin 8b65d67
Update TablePro/Core/Services/ExportService.swift
datlechin 764e8fd
wip
datlechin ed798d9
Update TablePro/Core/Services/ExportService.swift
datlechin de48444
Update TablePro/Views/Sidebar/SidebarView.swift
datlechin 80ad0a2
Update TablePro/Views/Export/ExportDialog.swift
datlechin 5e29e6f
wip
datlechin a411d58
Update TablePro/Core/Database/MySQLDriver.swift
datlechin ccb171c
Update TablePro/Views/Export/ExportDialog.swift
datlechin dcd96aa
wip
datlechin dc1518b
Update TablePro/Core/Services/ExportService.swift
datlechin 8683a5a
Update TablePro/Core/Services/ExportService.swift
datlechin dcb444b
Update TablePro/Core/Services/ExportService.swift
datlechin 549bb55
wip
datlechin dcee9e8
Update TablePro/Core/Services/ExportService.swift
datlechin 8e27851
Update TablePro/Views/Export/ExportDialog.swift
datlechin 1bc3152
Update TablePro/Core/Services/ExportService.swift
datlechin dc609eb
Update TablePro/Core/Services/ExportService.swift
datlechin 0af9b4e
Update TablePro/Views/Export/ExportDialog.swift
datlechin 6973621
Update TablePro/Core/Services/ExportService.swift
datlechin dab537b
Update TablePro/Core/Services/ExportService.swift
datlechin c856ceb
wip
datlechin 2f53566
wip
datlechin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| // | ||
| // SQLEscaping.swift | ||
| // TablePro | ||
| // | ||
| // Shared utilities for SQL string escaping to prevent SQL injection. | ||
| // Used across ExportService, SQLStatementGenerator, and other SQL-generating code. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| /// Centralized SQL escaping utilities to prevent SQL injection vulnerabilities | ||
| enum SQLEscaping { | ||
|
|
||
| /// Escape a string value for use in SQL string literals (VALUES, WHERE clauses, etc.) | ||
| /// | ||
| /// Handles the following special characters: | ||
| /// - Backslashes (must be escaped first to avoid double-escaping) | ||
| /// - Single quotes (SQL standard: doubled) | ||
| /// - Control characters: null, backspace, tab, newline, form feed, carriage return | ||
| /// - MySQL EOF marker (\x1A) which can cause parsing issues | ||
| /// | ||
| /// Example: | ||
| /// ```swift | ||
| /// let safe = SQLEscaping.escapeStringLiteral("O'Brien\\test") | ||
| /// // Result: "O''Brien\\\\test" | ||
| /// let sql = "INSERT INTO users (name) VALUES ('\(safe)')" | ||
| /// ``` | ||
| /// | ||
| /// - Parameter str: The raw string to escape | ||
| /// - Returns: The escaped string safe for use in SQL string literals | ||
| static func escapeStringLiteral(_ str: String) -> String { | ||
| var result = str | ||
| // IMPORTANT: Escape backslashes FIRST to avoid double-escaping | ||
| result = result.replacingOccurrences(of: "\\", with: "\\\\") | ||
| // Single quote: SQL standard escaping (double the quote) | ||
| result = result.replacingOccurrences(of: "'", with: "''") | ||
| // Common control characters | ||
| result = result.replacingOccurrences(of: "\n", with: "\\n") | ||
| result = result.replacingOccurrences(of: "\r", with: "\\r") | ||
| result = result.replacingOccurrences(of: "\t", with: "\\t") | ||
| result = result.replacingOccurrences(of: "\0", with: "\\0") | ||
| // Additional control characters that can cause issues | ||
| result = result.replacingOccurrences(of: "\u{08}", with: "\\b") // Backspace | ||
| result = result.replacingOccurrences(of: "\u{0C}", with: "\\f") // Form feed | ||
| result = result.replacingOccurrences(of: "\u{1A}", with: "\\Z") // MySQL EOF marker (Ctrl+Z) | ||
| return result | ||
| } | ||
|
datlechin marked this conversation as resolved.
|
||
|
|
||
| /// Escape wildcards in LIKE patterns while preserving intentional wildcards | ||
| /// | ||
| /// This is useful when building LIKE clauses where the search term should be treated literally. | ||
| /// | ||
| /// - Parameter value: The value to escape | ||
| /// - Returns: The escaped value with %, _, and \ escaped | ||
| static func escapeLikeWildcards(_ value: String) -> String { | ||
| var result = value | ||
| result = result.replacingOccurrences(of: "\\", with: "\\\\") | ||
| result = result.replacingOccurrences(of: "%", with: "\\%") | ||
| result = result.replacingOccurrences(of: "_", with: "\\_") | ||
| return result | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.