Skip to content

Commit 0b1e7e8

Browse files
committed
fix(file-provider): Clean up change delivery items after change session completed
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
1 parent 9e6e9aa commit 0b1e7e8

2 files changed

Lines changed: 60 additions & 9 deletions

File tree

shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager+ChangeDelivery.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ extension FilesDatabaseManager {
112112
.map { ($0.sequence, $0.metadataData, $0.deleted) }
113113
}
114114

115-
/// Advance an active session to its next continuation anchor, or mark it complete.
115+
/// Advance an active session to its next continuation anchor, or remove it after the final batch.
116116
func advanceChangeDeliverySession(
117117
sessionId: String,
118118
nextSequence: Int,
@@ -125,15 +125,22 @@ extension FilesDatabaseManager {
125125
}
126126

127127
try? database.write {
128-
session.nextSequence = nextSequence
129-
session.completed = completed
130-
if let nextAnchorKey {
131-
session.currentAnchorKey = nextAnchorKey
132-
}
128+
if completed {
129+
database.objects(RealmChangeDeliveryItem.self)
130+
.filter("sessionId == %@", sessionId)
131+
.forEach { database.delete($0) }
132+
database.delete(session)
133+
} else {
134+
session.nextSequence = nextSequence
135+
session.completed = false
136+
if let nextAnchorKey {
137+
session.currentAnchorKey = nextAnchorKey
138+
}
133139

134-
database.objects(RealmChangeDeliveryItem.self)
135-
.filter("sessionId == %@ AND sequence < %@", sessionId, nextSequence)
136-
.forEach { database.delete($0) }
140+
database.objects(RealmChangeDeliveryItem.self)
141+
.filter("sessionId == %@ AND sequence < %@", sessionId, nextSequence)
142+
.forEach { database.delete($0) }
143+
}
137144
}
138145
}
139146

shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/FilesDatabaseManagerTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,50 @@ final class FilesDatabaseManagerTests: NextcloudFileProviderKitTestCase {
2525
XCTAssertNotNil(Self.dbManager, "FilesDatabaseManager should be initialized")
2626
}
2727

28+
func testCompletedChangeDeliverySessionRemovesPersistedState() {
29+
let sessionId = "completed-change-delivery-\(name)"
30+
let metadata = SendableItemMetadata(
31+
ocId: "change-delivery-item-\(name)",
32+
fileName: "item.txt",
33+
account: Self.account
34+
)
35+
36+
XCTAssertTrue(
37+
Self.dbManager.createChangeDeliverySession(
38+
sessionId: sessionId,
39+
anchorKey: "initial-anchor-\(name)",
40+
finalAnchorRawValue: Data("final-anchor".utf8),
41+
updated: [metadata],
42+
deleted: [],
43+
incomplete: false
44+
)
45+
)
46+
47+
let database = Self.dbManager.ncDatabase()
48+
XCTAssertNotNil(database.object(ofType: RealmChangeDeliverySession.self, forPrimaryKey: sessionId))
49+
XCTAssertEqual(
50+
database.objects(RealmChangeDeliveryItem.self)
51+
.where { $0.sessionId == sessionId }
52+
.count,
53+
1
54+
)
55+
56+
Self.dbManager.advanceChangeDeliverySession(
57+
sessionId: sessionId,
58+
nextSequence: 1,
59+
nextAnchorKey: nil,
60+
completed: true
61+
)
62+
63+
let cleanedDatabase = Self.dbManager.ncDatabase()
64+
XCTAssertNil(cleanedDatabase.object(ofType: RealmChangeDeliverySession.self, forPrimaryKey: sessionId))
65+
XCTAssertTrue(
66+
cleanedDatabase.objects(RealmChangeDeliveryItem.self)
67+
.where { $0.sessionId == sessionId }
68+
.isEmpty
69+
)
70+
}
71+
2872
func testSchema203MigrationBackfillsCanonicalPathKeys() throws {
2973
let databaseDirectory = makeDatabaseDirectory()
3074
let domainIdentifier = NSFileProviderDomainIdentifier("migration-test")

0 commit comments

Comments
 (0)