Skip to content

Commit afd311e

Browse files
authored
Merge pull request #88 from claucambra/bugfix/pagination-pt4
Further pagination-related fixes
2 parents d7a8b48 + 5884db8 commit afd311e

5 files changed

Lines changed: 54 additions & 7 deletions

File tree

Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ public final class FilesDatabaseManager: Sendable {
452452
parentDirectoryUrl: \(metadata.serverUrl, privacy: .public)
453453
account: \(metadata.account, privacy: .public)
454454
content type: \(metadata.contentType, privacy: .public)
455+
is directory: \(metadata.directory, privacy: .public)
455456
creation date: \(metadata.creationDate, privacy: .public)
456457
date: \(metadata.date, privacy: .public)
457458
lock: \(metadata.lock, privacy: .public)

Sources/NextcloudFileProviderKit/Enumeration/Enumerator+SyncEngine.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,10 @@ extension Enumerator {
274274
if pageIndex == 0 {
275275
guard let firstFile = files.first else { return (nil, .invalidResponseError) }
276276
// Do not ingest metadata for the root container
277-
if !firstFile.fullUrlMatches(dbManager.account.davFilesUrl) {
277+
if !firstFile.fullUrlMatches(dbManager.account.davFilesUrl),
278+
!firstFile.fullUrlMatches(dbManager.account.davFilesUrl + "/."),
279+
!(firstFile.fileName == "." && firstFile.serverUrl == "..")
280+
{
278281
var metadata = firstFile.toItemMetadata()
279282
if metadata.directory,
280283
let existingMetadata = dbManager.itemMetadata(ocId: metadata.ocId)
@@ -388,6 +391,9 @@ extension Enumerator {
388391
at depth \(depth.rawValue, privacy: .public).
389392
username: \(account.username, privacy: .public),
390393
password is empty: \(account.password == "" ? "EMPTY" : "NOT EMPTY"),
394+
pageToken: \(String(data: pageSettings?.page?.rawValue ?? Data(), encoding: .utf8) ?? "NIL", privacy: .public)
395+
pageIndex: \(pageSettings?.index ?? -1, privacy: .public)
396+
pageSize: \(pageSettings?.size ?? -1, privacy: .public)
391397
serverUrl: \(account.serverUrl, privacy: .public)
392398
"""
393399
)
@@ -452,7 +458,7 @@ extension Enumerator {
452458
Self.logger.error(
453459
"""
454460
Received no items from readFileOrFolder of \(serverUrl, privacy: .public),
455-
not much we can do...
461+
not much we can do...
456462
"""
457463
)
458464
return (nil, nil, nil, nil, nextPage, error)
@@ -463,7 +469,9 @@ extension Enumerator {
463469
let isFollowUpPaginatedRequest = (pageSettings?.page != nil && pageSettings?.index ?? 0 > 0)
464470
if !isFollowUpPaginatedRequest {
465471
guard receivedFile.directory ||
466-
receivedFile.fullUrlMatches(dbManager.account.davFilesUrl)
472+
serverUrl == dbManager.account.davFilesUrl ||
473+
receivedFile.fullUrlMatches(dbManager.account.davFilesUrl + "/.") ||
474+
(receivedFile.fileName == "." && receivedFile.serverUrl == "..")
467475
else {
468476
Self.logger.debug(
469477
"""

Sources/NextcloudFileProviderKit/Enumeration/Enumerator.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
214214
Self.logger.debug(
215215
"""
216216
Enumerating page: \(self.pageNum, privacy: .public)
217+
with data: \(String(data: page.rawValue, encoding: .utf8) ?? "", privacy: .public)
217218
for user: \(self.account.ncKitAccount, privacy: .public)
218219
with serverUrl: \(self.serverUrl, privacy: .public)
219220
"""
@@ -291,12 +292,23 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
291292
let metadataRemoteUrl = metadata.serverUrl + "/" + metadata.fileName
292293
nextFoldersServerUrlsToEnumerateWorkingSet.append(metadataRemoteUrl)
293294
}
295+
let nextPageValid = nextPage != nil
296+
let nextPageToken = nextPage?.token ?? "" // For logging
297+
Self.logger.debug(
298+
"""
299+
Current folders awaiting paged enumeration:
300+
\(self.nextFoldersServerUrlsToEnumerateWorkingSet, privacy: .public)
301+
next page is valid: \(nextPageValid, privacy: .public)
302+
next page token: \(nextPageToken, privacy: .public)
303+
"""
304+
)
294305

295306
// If we have finished paged enumeration of the current serverUrl, move to next
296307
// child to scan
297-
if nextPage == nil && !nextFoldersServerUrlsToEnumerateWorkingSet.isEmpty {
308+
if !nextPageValid && !nextFoldersServerUrlsToEnumerateWorkingSet.isEmpty {
298309
let nextServerUrl = nextFoldersServerUrlsToEnumerateWorkingSet.removeFirst()
299310
nextPage = EnumeratorPageResponse(nextServerUrl: nextServerUrl)
311+
Self.logger.info("Next page token set to be \(nextServerUrl, privacy: .public)")
300312
}
301313
}
302314

@@ -305,7 +317,7 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
305317
Finished reading page: \(self.pageNum, privacy: .public)
306318
serverUrl: \(self.serverUrl, privacy: .public)
307319
for user: \(self.account.ncKitAccount, privacy: .public).
308-
Next page token is: \(nextPage?.token ?? "", privacy: .public)
320+
Next page token is: \(nextPage?.token ?? "NIL", privacy: .public)
309321
Processed \(metadatas.count) metadatas
310322
"""
311323
)
@@ -609,6 +621,14 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
609621
Task { @MainActor in
610622
observer.didEnumerate(items)
611623
Self.logger.info("Did enumerate \(items.count) items")
624+
let nextPageNil = nextPage == nil // For logging
625+
let nextPageToken = nextPage?.token ?? "" // For logging
626+
Self.logger.info(
627+
"""
628+
Next page is nil: \(nextPageNil, privacy: .public)
629+
next page token: \(nextPageToken, privacy: .public)
630+
"""
631+
)
612632
if let nextPage, let nextPageData = nextPage.token.data(using: .utf8) {
613633
self.pageNum = nextPage.index
614634
observer.finishEnumerating(upTo: NSFileProviderPage(nextPageData))

Sources/NextcloudFileProviderKit/Enumeration/EnumeratorPageResponse.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,30 @@
77

88
import Alamofire
99
import Foundation
10+
import OSLog
1011

1112
struct EnumeratorPageResponse: Sendable {
1213
let token: String // Required by server to serve the next page of items
1314
let index: Int // Needed to calculate the offset for the next paginated request
1415
let total: Int? // Total item count, provided in the first non-offset paginated response
16+
let logger = Logger(subsystem: Logger.subsystem, category: "enumeratorpageresponse")
1517

1618
init?(nkResponseData: AFDataResponse<Data>?, index: Int) {
1719
guard let headers = nkResponseData?.response?.allHeaderFields as? [String: String] else {
20+
logger.debug("Page response nil as could not get header fields from Alamofire response")
1821
return nil
1922
}
2023

2124
let normalisedHeaders =
2225
Dictionary(uniqueKeysWithValues: headers.map { ($0.key.lowercased(), $0.value) })
2326
guard Bool(normalisedHeaders["x-nc-paginate"]?.lowercased() ?? "false") == true,
2427
let responsePaginateToken = normalisedHeaders["x-nc-paginate-token"]
25-
else { return nil }
28+
else {
29+
logger.debug(
30+
"Page response nil, page headers missing. \(normalisedHeaders, privacy: .public)"
31+
)
32+
return nil
33+
}
2634

2735
self.index = index
2836
token = responsePaginateToken
@@ -31,9 +39,19 @@ struct EnumeratorPageResponse: Sendable {
3139
} else {
3240
total = nil
3341
}
42+
let totalString = total != nil ? String(total ?? -1) : "nil"
43+
logger.debug(
44+
"""
45+
Created enumerator page response with data from PROPFIND reply.
46+
token: \(responsePaginateToken, privacy: .public)
47+
index: \(index, privacy: .public)
48+
total: \(totalString, privacy: .public)
49+
"""
50+
)
3451
}
3552

3653
init(nextServerUrl: String) {
54+
logger.debug("Creating artificial page response with \(nextServerUrl, privacy: .public)")
3755
self.token = nextServerUrl
3856
self.index = -1
3957
self.total = nil

Tests/Interface/MockRemoteItem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class MockRemoteItem: Equatable {
6060
MockRemoteItem(
6161
identifier: NSFileProviderItemIdentifier.rootContainer.rawValue,
6262
versionIdentifier: "root",
63-
name: "",
63+
name: ".",
6464
remotePath: account.davFilesUrl,
6565
directory: true,
6666
account: account.ncKitAccount,

0 commit comments

Comments
 (0)