Skip to content

Commit d4bb25c

Browse files
authored
Merge branch 'main' into feat/quick-switcher-fuzzy-engine
Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
2 parents 7f20dae + 0d7548c commit d4bb25c

13 files changed

Lines changed: 205 additions & 27 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Quick Switcher scopes: Cmd+1 to Cmd+4 narrow results to All, Tables, Databases, or Queries.
1515
- Option+Return in the Quick Switcher opens the table in a new tab; right-click a result to open its structure, copy the name, or copy the query.
1616
- Tables already open in a tab show an Open badge in the Quick Switcher, rank higher, and Return switches to the existing tab.
17+
- `.psql` and `.pgsql` files now open in the SQL editor like `.sql`: Finder double-click, the open and save panels, and linked SQL folders all accept them. (#1641)
1718

1819
### Changed
1920

@@ -28,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2829
- Exports no longer fail mid-table on servers that enforce a statement time limit; the export session disables the limit and restores it afterwards, the same way mysqldump does. (#1633)
2930
- Quick Switcher no longer shows an empty table list when opened before the schema has finished loading.
3031
- Opening a query from history in the Quick Switcher loads the full query instead of a 100-character preview.
32+
- Refreshing a table now reloads its data even when the previous load is still running; before, the refresh was silently dropped and the grid kept stale rows. (#1637)
3133

3234
### Security
3335

TablePro/Core/Services/Infrastructure/SQLFileService.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ import UniformTypeIdentifiers
1313
enum SQLFileService {
1414
private static let logger = Logger(subsystem: "com.TablePro", category: "SQLFileService")
1515

16+
static let supportedExtensions: Set<String> = ["sql", "psql", "pgsql"]
17+
18+
private static var allowedContentTypes: [UTType] {
19+
let types = Set(supportedExtensions.compactMap { UTType(filenameExtension: $0) })
20+
return types.isEmpty ? [.plainText] : Array(types)
21+
}
22+
1623
/// Reads a SQL file from disk.
1724
static func readFile(url: URL) async throws -> String {
1825
try await Task.detached {
@@ -34,7 +41,7 @@ enum SQLFileService {
3441
@MainActor
3542
static func showOpenPanel() async -> [URL]? {
3643
let panel = NSOpenPanel()
37-
panel.allowedContentTypes = [UTType(filenameExtension: "sql") ?? .plainText]
44+
panel.allowedContentTypes = allowedContentTypes
3845
panel.allowsMultipleSelection = true
3946
panel.message = String(localized: "Select SQL files to open")
4047
let response = await panel.begin()
@@ -46,7 +53,7 @@ enum SQLFileService {
4653
@MainActor
4754
static func showSavePanel(suggestedName: String = "query.sql") async -> URL? {
4855
let panel = NSSavePanel()
49-
panel.allowedContentTypes = [UTType(filenameExtension: "sql") ?? .plainText]
56+
panel.allowedContentTypes = allowedContentTypes
5057
panel.canCreateDirectories = true
5158
panel.nameFieldStringValue = suggestedName
5259
panel.message = String(localized: "Save SQL file")

TablePro/Core/Services/Infrastructure/URLClassifier.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ internal enum URLClassifier {
2828
if ext == "tablepro" {
2929
return .success(.openConnectionShare(url))
3030
}
31-
if ext == "sql" {
31+
if SQLFileService.supportedExtensions.contains(ext) {
3232
return .success(.openSQLFile(url))
3333
}
3434
if PluginManager.shared.allInspectorFileExtensions.contains(ext) {

TablePro/Core/Services/SQL/SQLFolderWatcher.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ internal final class SQLFolderWatcher {
152152
var indexed: [LinkedSQLIndex.IndexedFile] = []
153153

154154
for case let url as URL in enumerator {
155-
guard url.pathExtension.lowercased() == "sql" else { continue }
155+
guard SQLFileService.supportedExtensions.contains(url.pathExtension.lowercased()) else { continue }
156156

157157
let resourceValues = try? url.resourceValues(forKeys: [
158158
.isRegularFileKey, .contentModificationDateKey, .fileSizeKey

TablePro/Info.plist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
<key>CFBundleTypeExtensions</key>
1515
<array>
1616
<string>sql</string>
17+
<string>psql</string>
18+
<string>pgsql</string>
1719
</array>
1820
<key>CFBundleTypeIconSystemGenerated</key>
1921
<true/>
@@ -154,6 +156,8 @@
154156
<key>public.filename-extension</key>
155157
<array>
156158
<string>sql</string>
159+
<string>psql</string>
160+
<string>pgsql</string>
157161
</array>
158162
</dict>
159163
</dict>

TablePro/Views/Main/Child/DataTabGridDelegate.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ final class DataTabGridDelegate: DataGridViewDelegate {
2020
var onAddRow: (() -> Void)?
2121
var onUndoInsert: ((Int) -> Void)?
2222
var onFilterColumn: ((String) -> Void)?
23-
var onRefresh: (() -> Void)?
2423

2524
// MARK: - DataGridViewDelegate
2625

@@ -44,10 +43,6 @@ final class DataTabGridDelegate: DataGridViewDelegate {
4443
onFilterColumn?(columnName)
4544
}
4645

47-
func dataGridRefresh() {
48-
onRefresh?()
49-
}
50-
5146
func dataGridDeleteRows(_ indices: Set<Int>) {
5247
coordinator?.deleteSelectedRows(indices: indices)
5348
}

TablePro/Views/Main/Child/MainEditorContentView.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ struct MainEditorContentView: View {
4444
let onFilterColumn: (String) -> Void
4545
let onApplyFilters: ([TableFilter]) -> Void
4646
let onClearFilters: () -> Void
47-
let onRefresh: () -> Void
4847

4948
// Pagination callbacks
5049
let onFirstPage: () -> Void
@@ -182,7 +181,6 @@ struct MainEditorContentView: View {
182181
dataTabDelegate.onSortStateChanged = onSortStateChanged
183182
dataTabDelegate.onUndoInsert = onUndoInsert
184183
dataTabDelegate.onFilterColumn = onFilterColumn
185-
dataTabDelegate.onRefresh = onRefresh
186184
}
187185

188186
private func refreshDataTabDelegateMutableRefs() {

TablePro/Views/Main/Extensions/MainContentCoordinator+Refresh.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extension MainContentCoordinator {
3333
// Query tabs should not auto-execute on refresh (use Cmd+Enter to execute)
3434
if let (tab, tabIndex) = tabManager.selectedTabAndIndex,
3535
tab.tabType == .table {
36-
currentQueryTask?.cancel()
36+
cancelCurrentQuery()
3737
rebuildTableQuery(at: tabIndex)
3838
runQuery()
3939
}
@@ -42,7 +42,7 @@ extension MainContentCoordinator {
4242
} else {
4343
if let (tab, tabIndex) = tabManager.selectedTabAndIndex,
4444
tab.tabType == .table {
45-
currentQueryTask?.cancel()
45+
cancelCurrentQuery()
4646
rebuildTableQuery(at: tabIndex)
4747
runQuery()
4848
}

TablePro/Views/Main/MainContentCoordinator.swift

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -527,13 +527,24 @@ final class MainContentCoordinator {
527527
}
528528

529529
func refreshTables() async {
530-
guard let driver = services.databaseManager.driver(for: connectionId) else { return }
531530
schemaColumns.removeAll()
532-
await services.schemaService.reload(
533-
connectionId: connectionId,
534-
driver: driver,
535-
connection: connection
536-
)
531+
let schemaService = services.schemaService
532+
let connectionId = connectionId
533+
let connection = connection
534+
do {
535+
try await services.databaseManager.withMetadataDriver(
536+
connectionId: connectionId,
537+
workload: .bulk
538+
) { driver in
539+
await schemaService.reload(
540+
connectionId: connectionId,
541+
driver: driver,
542+
connection: connection
543+
)
544+
}
545+
} catch {
546+
Self.logger.warning("Schema refresh failed: \(error.localizedDescription, privacy: .public)")
547+
}
537548
await reconcilePostSchemaLoad()
538549
}
539550

TablePro/Views/Main/MainContentView.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,6 @@ struct MainContentView: View {
462462
onClearFilters: {
463463
coordinator.clearFiltersAndReload()
464464
},
465-
onRefresh: {
466-
coordinator.runQuery()
467-
},
468465
onFirstPage: {
469466
coordinator.goToFirstPage()
470467
},

0 commit comments

Comments
 (0)