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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix crash when closing window during SSH tunnel connection (use-after-free in libssh2)
- Fix potential deadlock in SSH host key verification prompts (semaphore → async/await)
- Fix data race in ConnectionStorage, GroupStorage, and TagStorage (added @MainActor isolation)
- Add schema versioning to SQLite databases (query history, favorites) for future migrations

### Added

Expand Down
34 changes: 34 additions & 0 deletions TablePro/Core/Storage/QueryHistoryStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,42 @@ final class QueryHistoryStorage {
execute("PRAGMA synchronous=NORMAL;")

createTables()
migrateIfNeeded()
}

// MARK: - Schema Migration

private func migrateIfNeeded() {
let currentVersion = getUserVersion()

// Future migrations go here:
// if currentVersion < 2 {
// execute("ALTER TABLE history ADD COLUMN new_col TEXT;")
// }

let targetVersion: Int32 = 1
if currentVersion < targetVersion {
setUserVersion(targetVersion)
}
}

private func getUserVersion() -> Int32 {
var statement: OpaquePointer?
defer { sqlite3_finalize(statement) }
guard sqlite3_prepare_v2(db, "PRAGMA user_version", -1, &statement, nil) == SQLITE_OK,
sqlite3_step(statement) == SQLITE_ROW
else {
return 0
}
return sqlite3_column_int(statement, 0)
}

private func setUserVersion(_ version: Int32) {
execute("PRAGMA user_version = \(version);")
}

// MARK: - Table Creation

private func createTables() {
// History table
let historyTable = """
Expand Down
34 changes: 34 additions & 0 deletions TablePro/Core/Storage/SQLFavoriteStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,42 @@ internal final class SQLFavoriteStorage {
execute("PRAGMA synchronous=NORMAL;")

createTables()
migrateIfNeeded()
}

// MARK: - Schema Migration

private func migrateIfNeeded() {
let currentVersion = getUserVersion()

// Future migrations go here:
// if currentVersion < 2 {
// execute("ALTER TABLE favorites ADD COLUMN new_col TEXT;")
// }

let targetVersion: Int32 = 1
if currentVersion < targetVersion {
setUserVersion(targetVersion)
}
}

private func getUserVersion() -> Int32 {
var statement: OpaquePointer?
defer { sqlite3_finalize(statement) }
guard sqlite3_prepare_v2(db, "PRAGMA user_version", -1, &statement, nil) == SQLITE_OK,
sqlite3_step(statement) == SQLITE_ROW
else {
return 0
}
return sqlite3_column_int(statement, 0)
}

private func setUserVersion(_ version: Int32) {
execute("PRAGMA user_version = \(version);")
}

// MARK: - Table Creation

private func createTables() {
let favoritesTable = """
CREATE TABLE IF NOT EXISTS favorites (
Expand Down
Loading