Skip to content
Open
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
60 changes: 46 additions & 14 deletions Sources/SQLiteData/CloudKit/Internal/MockSyncEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@
package final class MockSyncEngineState: CKSyncEngineStateProtocol {
package let changeTag = LockIsolated(0)
package let _pendingRecordZoneChanges = LockIsolated<
OrderedSet<CKSyncEngine.PendingRecordZoneChange>
>([]
OrderedDictionary<CKRecord.ID, CKSyncEngine.PendingRecordZoneChange>
>([:]
)
package let _pendingDatabaseChanges = LockIsolated<
OrderedSet<CKSyncEngine.PendingDatabaseChange>
>([])
OrderedDictionary<CKRecordZone.ID, CKSyncEngine.PendingDatabaseChange>
>([:])
private let fileID: StaticString
private let filePath: StaticString
private let line: UInt
Expand All @@ -160,11 +160,11 @@
}

package var pendingRecordZoneChanges: [CKSyncEngine.PendingRecordZoneChange] {
_pendingRecordZoneChanges.withValue { Array($0) }
_pendingRecordZoneChanges.withValue { Array($0.values) }
}

package var pendingDatabaseChanges: [CKSyncEngine.PendingDatabaseChange] {
_pendingDatabaseChanges.withValue { Array($0) }
_pendingDatabaseChanges.withValue { Array($0.values) }
}

package func removePendingChanges() {
Expand All @@ -173,26 +173,58 @@
}

package func add(pendingRecordZoneChanges: [CKSyncEngine.PendingRecordZoneChange]) {
self._pendingRecordZoneChanges.withValue {
$0.append(contentsOf: pendingRecordZoneChanges)
self._pendingRecordZoneChanges.withValue { dict in
for change in pendingRecordZoneChanges {
switch change {
case .saveRecord(let id), .deleteRecord(let id):
dict.updateValue(change, forKey: id)
@unknown default:
fatalError("Unsupported pendingRecordZoneChange: \(change)")
}
}
}
}

package func remove(pendingRecordZoneChanges: [CKSyncEngine.PendingRecordZoneChange]) {
self._pendingRecordZoneChanges.withValue {
$0.subtract(pendingRecordZoneChanges)
self._pendingRecordZoneChanges.withValue { dict in
for change in pendingRecordZoneChanges {
switch change {
case .saveRecord(let id), .deleteRecord(let id):
if dict[id] == change { dict.removeValue(forKey: id) }
@unknown default:
fatalError("Unsupported pendingRecordZoneChange: \(change)")
}
}
}
}

package func add(pendingDatabaseChanges: [CKSyncEngine.PendingDatabaseChange]) {
self._pendingDatabaseChanges.withValue {
$0.append(contentsOf: pendingDatabaseChanges)
self._pendingDatabaseChanges.withValue { dict in
for change in pendingDatabaseChanges {
switch change {
case .saveZone(let zone):
dict.updateValue(change, forKey: zone.zoneID)
case .deleteZone(let zoneID):
dict.updateValue(change, forKey: zoneID)
@unknown default:
fatalError("Unsupported pendingDatabaseChange: \(change)")
}
}
}
}

package func remove(pendingDatabaseChanges: [CKSyncEngine.PendingDatabaseChange]) {
self._pendingDatabaseChanges.withValue {
$0.subtract(pendingDatabaseChanges)
self._pendingDatabaseChanges.withValue { dict in
for change in pendingDatabaseChanges {
switch change {
case .saveZone(let zone):
if dict[zone.zoneID] == change { dict.removeValue(forKey: zone.zoneID) }
case .deleteZone(let zoneID):
if dict[zoneID] == change { dict.removeValue(forKey: zoneID) }
@unknown default:
fatalError("Unsupported pendingDatabaseChange: \(change)")
}
}
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions Sources/SQLiteData/CloudKit/Internal/Triggers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
defaultZone: defaultZone,
privateTables: privateTables
)
SyncMetadata
.where {
$0.recordPrimaryKey.eq(#sql("\(new.primaryKey)"))
&& $0.recordType.eq(tableName)
&& $0._isDeleted
}
.update {
$0._isDeleted = false
$0.userModificationTime = $currentTime()
}
}
)
}
Expand Down Expand Up @@ -242,6 +252,7 @@
afterZoneUpdateTrigger(),
afterUpdateTrigger(for: syncEngine),
afterSoftDeleteTrigger(for: syncEngine),
afterUndeleteTrigger(for: syncEngine),
]
}

Expand Down Expand Up @@ -348,6 +359,29 @@
}
)
}

fileprivate static func afterUndeleteTrigger(
for syncEngine: SyncEngine
) -> TemporaryTrigger<Self> {
createTemporaryTrigger(
"\(String.sqliteDataCloudKitSchemaName)_after_undelete_on_sqlitedata_icloud_metadata",
ifNotExists: true,
after: .update(of: \._isDeleted) { _, new in
Values(
syncEngine.$didUpdate(
recordName: new.recordName,
zoneName: new.zoneName,
ownerName: new.ownerName,
oldZoneName: new.zoneName,
oldOwnerName: new.ownerName,
descendantRecordNames: #bind(nil)
)
)
} when: { old, new in
old._isDeleted && !new._isDeleted && !SyncEngine.$isSynchronizing
}
)
}
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
Expand Down
Loading