From b2d2f9586efc0b3d60004e4e74938711f3748d34 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Sat, 18 Mar 2023 13:24:37 +0100 Subject: [PATCH] Properly report deleted metadatas in recursive directory delete in FileProviderEnumerator Signed-off-by: Claudio Cambra --- .../NextcloudFilesDatabaseManager.swift | 13 ++++++++-- .../FileProviderEnumerator.swift | 24 ++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager.swift index bdd0a6b73..a36f1b766 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager.swift @@ -361,29 +361,38 @@ class NextcloudFilesDatabaseManager : NSObject { } // Deletes all metadatas related to the info of the directory provided - func deleteDirectoryAndSubdirectoriesMetadata(ocId: String) { + func deleteDirectoryAndSubdirectoriesMetadata(ocId: String) -> [NextcloudItemMetadataTable]? { let database = ncDatabase() guard let directoryMetadata = database.objects(NextcloudItemMetadataTable.self).filter("ocId == %@ AND directory == true", ocId).first else { Logger.ncFilesDatabase.error("Could not find directory metadata for ocId \(ocId, privacy: .public). Not proceeding with deletion") - return + return nil } + var deletedMetadatas: [NextcloudItemMetadataTable] = [] + let directoryUrlPath = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName let results = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, directoryUrlPath) for result in results { deleteItemMetadata(ocId: result.ocId) deleteLocalFileMetadata(ocId: result.ocId) + + deletedMetadatas.append(NextcloudItemMetadataTable(value: result)) } do { try database.write { Logger.ncFilesDatabase.debug("Deleting root directory metadata in recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryMetadata.etag, privacy: .public), serverUrl: \(directoryUrlPath)") + database.delete(results) + + return deletedMetadatas } } catch let error { Logger.ncFilesDatabase.error("Could not delete root directory metadata in recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryMetadata.etag, privacy: .public), serverUrl: \(directoryUrlPath), received error: \(error.localizedDescription, privacy: .public)") } + + return nil } func renameDirectoryAndPropagateToChildren(ocId: String, newServerUrl: String, newFileName: String) -> [NextcloudItemMetadataTable]? { diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift index ec28fb0e8..49b83c079 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift @@ -281,6 +281,13 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { // No matter what happens here we finish enumeration in some way, either from the error // handling below or from the completeChangesObserver FileProviderEnumerator.readServerUrl(serverUrl, ncAccount: ncAccount, ncKit: ncKit, stopAtMatchingEtags: true) { _, newMetadatas, updatedMetadatas, deletedMetadatas, readError in + + // If we get a 404 we might add more deleted metadatas + var currentDeletedMetadatas: [NextcloudItemMetadataTable] = [] + if let notNilDeletedMetadatas = deletedMetadatas { + currentDeletedMetadatas = notNilDeletedMetadatas + } + guard readError == nil else { Logger.enumeration.error("Finishing enumeration of changes for user: \(self.ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash)) with serverUrl: \(self.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with error: \(readError!.localizedDescription, privacy: .public)") @@ -298,7 +305,11 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { let dbManager = NextcloudFilesDatabaseManager.shared if itemMetadata.directory { - dbManager.deleteDirectoryAndSubdirectoriesMetadata(ocId: itemMetadata.ocId) + if let deletedDirectoryMetadatas = dbManager.deleteDirectoryAndSubdirectoriesMetadata(ocId: itemMetadata.ocId) { + currentDeletedMetadatas += deletedDirectoryMetadatas + } else { + Logger.enumeration.error("Something went wrong when recursively deleting directory not found.") + } } else { dbManager.deleteItemMetadata(ocId: itemMetadata.ocId) } @@ -469,14 +480,11 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { if nkReadError.isNotFoundError { Logger.enumeration.info("404 error means item no longer exists. Deleting metadata and reporting as deletion without error") - guard let directoryItemMetadata = dbManager.itemMetadataFromOcId(directoryMetadata.ocId) else { - Logger.enumeration.error("Can't delete directory properly as item metadata not found...") - dispatchGroup.leave() - return + if let deletedMetadatas = dbManager.deleteDirectoryAndSubdirectoriesMetadata(ocId: directoryMetadata.ocId) { + allDeletedMetadatas += deletedMetadatas + } else { + Logger.enumeration.error("An error occurred while trying to delete directory and children not found in recursive scan") } - - dbManager.deleteDirectoryAndSubdirectoriesMetadata(ocId: directoryMetadata.ocId) - allDeletedMetadatas.append(directoryItemMetadata) } else if nkReadError.isNoChangesError { // All is well, just no changed etags Logger.enumeration.info("Error was to say no changed files -- not bad error. No need to check children.") }