Skip to content

Commit 5581705

Browse files
committed
Fix for schema migration involving 'NOT NULL' columns.
1 parent 8af16d5 commit 5581705

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

Sources/SQLiteData/CloudKit/SyncEngine.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,11 +2005,11 @@
20052005
if data == nil {
20062006
reportIssue("Asset data not found on disk")
20072007
}
2008-
return "\(quote: columnName) = \(data?.queryFragment ?? "NULL")"
2008+
return "\(quote: columnName) = \(data?.queryFragment ?? #""excluded".\#(quote: columnName)"#)"
20092009
} else {
20102010
return """
20112011
\(quote: columnName) = \
2012-
\(record.encryptedValues[columnName]?.queryFragment ?? "NULL")
2012+
\(record.encryptedValues[columnName]?.queryFragment ?? #""excluded".\#(quote: columnName)"#)
20132013
"""
20142014
}
20152015
}

Tests/SQLiteDataTests/CloudKitTests/SchemaChangeTests.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,42 @@
106106
}
107107
}
108108

109+
@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
110+
@Test func addColumn_OldRecordsSyncToNewSchema() async throws {
111+
let remindersList = RemindersList(id: 1, title: "Personal")
112+
try await userDatabase.userWrite { db in
113+
try db.seed {
114+
remindersList
115+
}
116+
}
117+
try await syncEngine.processPendingRecordZoneChanges(scope: .private)
118+
119+
syncEngine.stop()
120+
121+
try await userDatabase.userWrite { db in
122+
try #sql(
123+
"""
124+
ALTER TABLE "remindersLists"
125+
ADD COLUMN "position" INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 0
126+
"""
127+
)
128+
.execute(db)
129+
}
130+
131+
let relaunchedSyncEngine = try await SyncEngine(
132+
container: syncEngine.container,
133+
userDatabase: syncEngine.userDatabase,
134+
tables: syncEngine.tables
135+
.filter { $0.base != Reminder.self && $0.base != RemindersList.self }
136+
+ [
137+
SynchronizedTable(for: ReminderWithPosition.self),
138+
SynchronizedTable(for: RemindersListWithPosition.self),
139+
],
140+
privateTables: syncEngine.privateTables
141+
)
142+
defer { _ = relaunchedSyncEngine }
143+
}
144+
109145
@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
110146
@Test func addAssetToRemindersList() async throws {
111147
let personalList = RemindersList(id: 1, title: "Personal")

0 commit comments

Comments
 (0)