|
196 | 196 | } |
197 | 197 | } |
198 | 198 |
|
| 199 | + /* |
| 200 | + * Old schema creates record and synchronizes to iCloud. |
| 201 | + * Schema is migrated to add a "NOT NULL" column. |
| 202 | + * New sync engine is launched. |
| 203 | + => Sync starts without emitting an error. |
| 204 | + */ |
| 205 | + @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 206 | + @Test func addColumn_OldRecordsSyncToNewSchema() async throws { |
| 207 | + let remindersList = RemindersList(id: 1, title: "Personal") |
| 208 | + try await userDatabase.userWrite { db in |
| 209 | + try db.seed { |
| 210 | + remindersList |
| 211 | + } |
| 212 | + } |
| 213 | + try await syncEngine.processPendingRecordZoneChanges(scope: .private) |
| 214 | + |
| 215 | + syncEngine.stop() |
| 216 | + |
| 217 | + try await userDatabase.userWrite { db in |
| 218 | + try #sql( |
| 219 | + """ |
| 220 | + ALTER TABLE "remindersLists" |
| 221 | + ADD COLUMN "position" INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 0 |
| 222 | + """ |
| 223 | + ) |
| 224 | + .execute(db) |
| 225 | + } |
| 226 | + |
| 227 | + // NB: Sync engine should start without emitting issue. |
| 228 | + _ = try await SyncEngine( |
| 229 | + container: syncEngine.container, |
| 230 | + userDatabase: syncEngine.userDatabase, |
| 231 | + tables: syncEngine.tables |
| 232 | + .filter { $0.base != Reminder.self && $0.base != RemindersList.self } |
| 233 | + + [ |
| 234 | + SynchronizedTable(for: ReminderWithPosition.self), |
| 235 | + SynchronizedTable(for: RemindersListWithPosition.self), |
| 236 | + ], |
| 237 | + privateTables: syncEngine.privateTables |
| 238 | + ) |
| 239 | + } |
| 240 | + |
199 | 241 | /* |
200 | 242 | * Test run from perspective of old device with old schema. |
201 | 243 | * Old schema saves record in cloud database. |
|
0 commit comments