Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- SQL import dropped statements when the database executed them slower than the file was parsed, so a re-imported export could fail with errors like "relation does not exist". The parser now waits for each statement to be consumed before reading more. (#1264)
- SQL import ignored the database dialect, so PostgreSQL dumps with dollar-quoted function bodies were split at semicolons inside the body. (#1264)
- SQL export emitted `DROP TABLE` for views, materialized views, and foreign tables, so re-importing failed with "is not a table". It now emits `DROP VIEW`, `DROP MATERIALIZED VIEW`, or `DROP FOREIGN TABLE` to match the object. (#1264)
- iOS: connections, groups, and tags no longer silently disappear after a TestFlight or App Store update. Persistence files are now stored with `.completeFileProtectionUntilFirstUserAuthentication` so they stay readable across background sync runs, load failures are no longer swallowed, and the sync engine refuses to overwrite local data when the load was not actually empty.

### Removed
Expand Down
12 changes: 11 additions & 1 deletion Plugins/SQLExportPlugin/SQLExportPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,21 @@ final class SQLExportPlugin: ExportFormatPlugin, SettablePlugin {
guard !dropTargets.isEmpty else { return }
for table in dropTargets {
let tableRef = dataSource.quoteIdentifier(table.name)
try fileHandle.write(contentsOf: "DROP TABLE IF EXISTS \(tableRef) CASCADE;\n".toUTF8Data())
let keyword = dropStatementKeyword(for: table.tableType)
try fileHandle.write(contentsOf: "\(keyword) IF EXISTS \(tableRef) CASCADE;\n".toUTF8Data())
}
try fileHandle.write(contentsOf: "\n".toUTF8Data())
}

private func dropStatementKeyword(for tableType: String) -> String {
switch tableType {
case "view": return "DROP VIEW"
case "materialized view": return "DROP MATERIALIZED VIEW"
case "foreign table": return "DROP FOREIGN TABLE"
default: return "DROP TABLE"
}
}

private func writeDependentTypesAndSequences(
tables: [PluginExportTable],
dataSource: any PluginExportDataSource,
Expand Down
2 changes: 1 addition & 1 deletion TablePro/Core/Plugins/SqlFileImportSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class SqlFileImportSource: PluginImportSource, @unchecked Sendable {

func statements() async throws -> AsyncThrowingStream<(statement: String, lineNumber: Int), Error> {
let fileURL = try await resolveURL()
return parser.parseFile(url: fileURL, encoding: encoding)
return parser.parseFile(url: fileURL, encoding: encoding, dialect: dialect)
}

func cleanup() {
Expand Down
2 changes: 1 addition & 1 deletion TablePro/Core/Services/Export/ExportService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ final class ExportService {
PluginExportTable(
name: table.name,
databaseName: table.databaseName,
tableType: table.type == .view ? "view" : "table",
tableType: table.type.rawValue.lowercased(),
optionValues: table.optionValues
)
}
Expand Down
Loading
Loading