@@ -234,7 +234,7 @@ public final class FilesDatabaseManager: Sendable {
234234
235235 for existingMetadata in existingMetadatas {
236236 guard !updatedMetadatas. contains ( where: { $0. ocId == existingMetadata. ocId } ) ,
237- let metadataToDelete = itemMetadatas. where ( { $0. ocId == existingMetadata. ocId } ) . first
237+ var metadataToDelete = itemMetadatas. where ( { $0. ocId == existingMetadata. ocId } ) . first
238238 else { continue }
239239
240240 deletedMetadatas. append ( metadataToDelete)
@@ -245,6 +245,7 @@ public final class FilesDatabaseManager: Sendable {
245245 ocID: \( existingMetadata. ocId, privacy: . public)
246246 etag: \( existingMetadata. etag, privacy: . public)
247247 fileName: \( existingMetadata. fileName, privacy: . public) "
248+ syncTime: \( existingMetadata. syncTime, privacy: . public)
248249 """
249250 )
250251 }
@@ -282,6 +283,7 @@ public final class FilesDatabaseManager: Sendable {
282283 if keepExistingDownloadState {
283284 updatedMetadata. downloaded = existingMetadata. downloaded
284285 }
286+ updatedMetadata. visitedDirectory = existingMetadata. visitedDirectory
285287
286288 returningUpdatedMetadatas. append ( updatedMetadata)
287289
@@ -291,6 +293,7 @@ public final class FilesDatabaseManager: Sendable {
291293 ocID: \( updatedMetadata. ocId, privacy: . public)
292294 etag: \( updatedMetadata. etag, privacy: . public)
293295 fileName: \( updatedMetadata. fileName, privacy: . public)
296+ syncTime: \( updatedMetadata. syncTime, privacy: . public)
294297 """
295298 )
296299 } else {
@@ -300,6 +303,7 @@ public final class FilesDatabaseManager: Sendable {
300303 ocID: \( updatedMetadata. ocId, privacy: . public)
301304 etag: \( updatedMetadata. etag, privacy: . public)
302305 fileName: \( updatedMetadata. fileName, privacy: . public)
306+ syncTime: \( updatedMetadata. syncTime, privacy: . public)
303307 """
304308 )
305309 }
@@ -313,6 +317,23 @@ public final class FilesDatabaseManager: Sendable {
313317 ocID: \( updatedMetadata. ocId, privacy: . public)
314318 etag: \( updatedMetadata. etag, privacy: . public)
315319 fileName: \( updatedMetadata. fileName, privacy: . public)
320+ parentDirectoryUrl: \( updatedMetadata. serverUrl, privacy: . public)
321+ account: \( updatedMetadata. account, privacy: . public)
322+ content type: \( updatedMetadata. contentType, privacy: . public)
323+ is directory: \( updatedMetadata. directory, privacy: . public)
324+ creation date: \( updatedMetadata. creationDate, privacy: . public)
325+ date: \( updatedMetadata. date, privacy: . public)
326+ lock: \( updatedMetadata. lock, privacy: . public)
327+ lockTimeOut: \( updatedMetadata. lockTimeOut? . description ?? " " , privacy: . public)
328+ lockOwner: \( updatedMetadata. lockOwner ?? " " , privacy: . public)
329+ permissions: \( updatedMetadata. permissions, privacy: . public)
330+ size: \( updatedMetadata. size, privacy: . public)
331+ trashbinFileName: \( updatedMetadata. trashbinFileName, privacy: . public)
332+ downloaded: \( updatedMetadata. downloaded, privacy: . public)
333+ uploaded: \( updatedMetadata. uploaded, privacy: . public)
334+ visitedDirectory: \( updatedMetadata. visitedDirectory, privacy: . public)
335+ deleted: \( updatedMetadata. deleted, privacy: . public)
336+ syncTime: \( updatedMetadata. syncTime, privacy: . public)
316337 """
317338 )
318339 }
@@ -368,12 +389,14 @@ public final class FilesDatabaseManager: Sendable {
368389 readTargetMetadata = nil
369390 }
370391
371- // NOTE: These metadatas are managed -- be careful!
372392 let metadatasToDelete = processItemMetadatasToDelete (
373393 existingMetadatas: existingMetadatas,
374394 updatedMetadatas: updatedChildMetadatas
375- )
376- let metadatasToDeleteCopy = metadatasToDelete. map { SendableItemMetadata ( value: $0) }
395+ ) . map {
396+ var metadata = SendableItemMetadata ( value: $0)
397+ metadata. deleted = true
398+ return metadata
399+ }
377400
378401 let metadatasToChange = processItemMetadatasToUpdate (
379402 existingMetadatas: existingMetadatas,
@@ -396,32 +419,34 @@ public final class FilesDatabaseManager: Sendable {
396419 }
397420
398421 if var readTargetMetadata {
422+ if readTargetMetadata. directory {
423+ readTargetMetadata. visitedDirectory = true
424+ }
425+
399426 if let existing = itemMetadata ( ocId: readTargetMetadata. ocId) {
400427 if existing. status == Status . normal. rawValue,
401428 !existing. isInSameDatabaseStoreableRemoteState ( readTargetMetadata)
402429 {
403- Self . logger. info ( " Depth 1 read target changed: \( readTargetMetadata. ocId) " )
430+ Self . logger. info ( " Depth 1 read target changed: \( readTargetMetadata. ocId, privacy : . public ) " )
404431 if keepExistingDownloadState {
405432 readTargetMetadata. downloaded = existing. downloaded
406433 }
407- if readTargetMetadata. directory {
408- readTargetMetadata. visitedDirectory = true
409- }
410434 metadatasToUpdate. insert ( readTargetMetadata, at: 0 )
411435 }
412436 } else {
413- Self . logger. info ( " Depth 1 read target is new: \( readTargetMetadata. ocId) " )
437+ Self . logger. info ( " Depth 1 read target is new: \( readTargetMetadata. ocId, privacy : . public ) " )
414438 metadatasToCreate. insert ( readTargetMetadata, at: 0 )
415439 }
416440 }
417441
418442 try database. write {
419- database. delete ( metadatasToDelete)
443+ // Do not delete the metadatas that have been deleted
444+ database. add ( metadatasToDelete. map { RealmItemMetadata ( value: $0) } , update: . modified)
420445 database. add ( metadatasToUpdate. map { RealmItemMetadata ( value: $0) } , update: . modified)
421446 database. add ( metadatasToCreate. map { RealmItemMetadata ( value: $0) } , update: . all)
422447 }
423448
424- return ( metadatasToCreate, metadatasToUpdate, metadatasToDeleteCopy )
449+ return ( metadatasToCreate, metadatasToUpdate, metadatasToDelete )
425450 } catch {
426451 Self . logger. error (
427452 """
@@ -467,6 +492,7 @@ public final class FilesDatabaseManager: Sendable {
467492 ocID: \( metadata. ocId, privacy: . public)
468493 etag: \( metadata. etag, privacy: . public)
469494 fileName: \( metadata. fileName, privacy: . public)
495+ syncTime: \( metadata. syncTime, privacy: . public)
470496 """
471497 )
472498 }
@@ -513,6 +539,8 @@ public final class FilesDatabaseManager: Sendable {
513539 downloaded: \( metadata. downloaded, privacy: . public)
514540 uploaded: \( metadata. uploaded, privacy: . public)
515541 visitedDirectory: \( metadata. visitedDirectory, privacy: . public)
542+ deleted: \( metadata. deleted, privacy: . public)
543+ syncTime: \( metadata. syncTime, privacy: . public)
516544 """
517545 )
518546 }
@@ -523,6 +551,7 @@ public final class FilesDatabaseManager: Sendable {
523551 ocID: \( metadata. ocId, privacy: . public)
524552 etag: \( metadata. etag, privacy: . public)
525553 fileName: \( metadata. fileName, privacy: . public)
554+ syncTime: \( metadata. syncTime, privacy: . public)
526555 received error: \( error. localizedDescription, privacy: . public)
527556 """
528557 )
@@ -535,7 +564,7 @@ public final class FilesDatabaseManager: Sendable {
535564 let database = ncDatabase ( )
536565 try database. write {
537566 Self . logger. debug ( " Deleting item metadata. \( ocId, privacy: . public) " )
538- database . delete ( results)
567+ results. forEach { $0 . deleted = true }
539568 }
540569 return true
541570 } catch {
@@ -614,6 +643,7 @@ public final class FilesDatabaseManager: Sendable {
614643 fileName: \( metadata. fileName, privacy: . public) ,
615644 serverUrl: \( metadata. serverUrl, privacy: . public) ,
616645 account: \( metadata. account, privacy: . public) ,
646+ syncTime: \( metadata. syncTime, privacy: . public)
617647 """
618648 )
619649 return nil
@@ -652,12 +682,68 @@ public final class FilesDatabaseManager: Sendable {
652682 return NSFileProviderItemIdentifier ( parentMetadata. ocId)
653683 }
654684
655- public func materialisedItemMetadatas ( account: String ) -> [ SendableItemMetadata ] {
685+ private func managedMaterialisedItemMetadatas ( account: String ) -> Results < RealmItemMetadata > {
656686 itemMetadatas
657687 . where {
658688 $0. account == account &&
659689 ( ( $0. directory && $0. visitedDirectory) || ( !$0. directory && $0. downloaded) )
660690 }
661- . toUnmanagedResults ( )
691+ }
692+
693+ public func materialisedItemMetadatas( account: String ) -> [ SendableItemMetadata ] {
694+ managedMaterialisedItemMetadatas ( account: account) . toUnmanagedResults ( )
695+ }
696+
697+ public func pendingWorkingSetChanges(
698+ account: Account , since date: Date
699+ ) -> ( updated: [ SendableItemMetadata ] , deleted: [ SendableItemMetadata ] ) {
700+ let accId = account. ncKitAccount
701+ let pending = managedMaterialisedItemMetadatas ( account: accId) . where { $0. syncTime > date }
702+ var updated = pending. where { !$0. deleted } . toUnmanagedResults ( )
703+ var deleted = pending. where { $0. deleted } . toUnmanagedResults ( )
704+
705+ var handledUpdateOcIds = Set ( updated. map ( \. ocId) )
706+ updated
707+ . map {
708+ var serverUrl = $0. serverUrl + " / " + $0. fileName
709+ if serverUrl. last == " / " { serverUrl. removeLast ( ) }
710+ return serverUrl
711+ }
712+ . forEach { serverUrl in
713+ Self . logger. debug ( " Checking (updated) \( serverUrl, privacy: . public) " )
714+ itemMetadatas
715+ . where { $0. serverUrl == serverUrl && $0. syncTime > date }
716+ . forEach { metadata in
717+ Self . logger. debug ( " Checking item: \( metadata. fileName, privacy: . public) " )
718+ guard !handledUpdateOcIds. contains ( metadata. ocId) else { return }
719+ handledUpdateOcIds. insert ( metadata. ocId)
720+ let sendableMetadata = SendableItemMetadata ( value: metadata)
721+ if metadata. deleted {
722+ deleted. append ( sendableMetadata)
723+ } else {
724+ updated. append ( sendableMetadata)
725+ }
726+ Self . logger. debug ( " Appended item: \( metadata. fileName, privacy: . public) " )
727+ }
728+ }
729+
730+ var handledDeleteOcIds = Set ( deleted. map ( \. ocId) )
731+ deleted
732+ . map {
733+ var serverUrl = $0. serverUrl + " / " + $0. fileName
734+ if serverUrl. last == " / " { serverUrl. removeLast ( ) }
735+ return serverUrl
736+ }
737+ . forEach { serverUrl in
738+ Self . logger. debug ( " Checking (deletion) \( serverUrl, privacy: . public) " )
739+ itemMetadatas
740+ . where { $0. serverUrl. starts ( with: serverUrl) && $0. syncTime > date }
741+ . forEach { metadata in
742+ guard !handledDeleteOcIds. contains ( metadata. ocId) else { return }
743+ deleted. append ( SendableItemMetadata ( value: metadata) )
744+ }
745+ }
746+
747+ return ( updated, deleted)
662748 }
663749}
0 commit comments