Split directory item metadata handling in database to new NextcloudFilesDatabaseManag...
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Tue, 4 Apr 2023 08:24:17 +0000 (16:24 +0800)
committerClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 12 May 2023 08:02:39 +0000 (16:02 +0800)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager+Directories.swift [new file with mode: 0644]
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager.swift
shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj

diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager+Directories.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Database/NextcloudFilesDatabaseManager+Directories.swift
new file mode 100644 (file)
index 0000000..386791e
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2023 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+import Foundation
+import OSLog
+
+extension NextcloudFilesDatabaseManager {
+    func directoryMetadata(account: String, serverUrl: String) -> NextcloudItemMetadataTable? {
+        // We want to split by "/" (e.g. cloud.nc.com/files/a/b) but we need to be mindful of "https://c.nc.com"
+        let problematicSeparator = "://"
+        let placeholderSeparator = "__TEMP_REPLACE__"
+        let serverUrlWithoutPrefix = serverUrl.replacingOccurrences(of: problematicSeparator, with: placeholderSeparator)
+        var splitServerUrl = serverUrlWithoutPrefix.split(separator: "/")
+        let directoryItemFileName = String(splitServerUrl.removeLast())
+        let directoryItemServerUrl = splitServerUrl.joined(separator: "/").replacingOccurrences(of: placeholderSeparator, with: problematicSeparator)
+
+        if let metadata = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND directory == true", account, directoryItemServerUrl, directoryItemFileName).first {
+            return NextcloudItemMetadataTable(value: metadata)
+        }
+
+        return nil
+    }
+
+    func childItemsForDirectory(_ directoryMetadata: NextcloudItemMetadataTable) -> [NextcloudItemMetadataTable] {
+        let directoryServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
+        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("serverUrl BEGINSWITH %@", directoryServerUrl)
+        return sortedItemMetadatas(metadatas)
+    }
+
+    func childDirectoriesForDirectory(_ directoryMetadata: NextcloudItemMetadataTable) -> [NextcloudItemMetadataTable] {
+        let directoryServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
+        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("serverUrl BEGINSWITH %@ AND directory == true", directoryServerUrl)
+        return sortedItemMetadatas(metadatas)
+    }
+
+    func parentDirectoryMetadataForItem(_ itemMetadata: NextcloudItemMetadataTable) -> NextcloudItemMetadataTable? {
+        return directoryMetadata(account: itemMetadata.account, serverUrl: itemMetadata.serverUrl)
+    }
+
+    func directoryMetadata(ocId: String) -> NextcloudItemMetadataTable? {
+        if let metadata = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("ocId == %@ AND directory == true", ocId).first {
+            return NextcloudItemMetadataTable(value: metadata)
+        }
+
+        return nil
+    }
+
+    func directoryMetadatas(account: String) -> [NextcloudItemMetadataTable] {
+        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND directory == true", account)
+        return sortedItemMetadatas(metadatas)
+    }
+
+    func directoryMetadatas(account: String, parentDirectoryServerUrl: String) -> [NextcloudItemMetadataTable] {
+        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND parentDirectoryServerUrl == %@ AND directory == true", account, parentDirectoryServerUrl)
+        return sortedItemMetadatas(metadatas)
+    }
+
+    // Deletes all metadatas related to the info of the directory provided
+    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 nil
+        }
+
+        let directoryMetadataCopy = NextcloudItemMetadataTable(value: directoryMetadata)
+        let directoryUrlPath = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
+        let directoryAccount = directoryMetadata.account
+        let directoryEtag = directoryMetadata.etag
+
+        Logger.ncFilesDatabase.debug("Deleting root directory metadata in recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryEtag, privacy: .public), serverUrl: \(directoryUrlPath, privacy: .public)")
+
+        guard deleteItemMetadata(ocId: directoryMetadata.ocId) else {
+            Logger.ncFilesDatabase.debug("Failure to delete root directory metadata in recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryEtag, privacy: .public), serverUrl: \(directoryUrlPath, privacy: .public)")
+            return nil
+        }
+
+        var deletedMetadatas: [NextcloudItemMetadataTable] = [directoryMetadataCopy]
+
+        let results = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryAccount, directoryUrlPath)
+
+        for result in results {
+            let successfulItemMetadataDelete = deleteItemMetadata(ocId: result.ocId)
+            if (successfulItemMetadataDelete) {
+                deletedMetadatas.append(NextcloudItemMetadataTable(value: result))
+            }
+
+            if localFileMetadataFromOcId(result.ocId) != nil {
+                deleteLocalFileMetadata(ocId: result.ocId)
+            }
+        }
+
+        Logger.ncFilesDatabase.debug("Completed deletions in directory recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryEtag, privacy: .public), serverUrl: \(directoryUrlPath, privacy: .public)")
+
+        return deletedMetadatas
+    }
+
+    func renameDirectoryAndPropagateToChildren(ocId: String, newServerUrl: String, newFileName: 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 a directory with ocID \(ocId, privacy: .public), cannot proceed with recursive renaming")
+            return nil
+        }
+
+        let oldItemServerUrl = directoryMetadata.serverUrl
+        let oldDirectoryServerUrl = oldItemServerUrl + "/" + directoryMetadata.fileName
+        let newDirectoryServerUrl = newServerUrl + "/" + newFileName
+        let childItemResults = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, oldDirectoryServerUrl)
+
+        renameItemMetadata(ocId: ocId, newServerUrl: newServerUrl, newFileName: newFileName)
+        Logger.ncFilesDatabase.debug("Renamed root renaming directory")
+
+        do {
+            try database.write {
+                for childItem in childItemResults {
+                    let oldServerUrl = childItem.serverUrl
+                    let movedServerUrl = oldServerUrl.replacingOccurrences(of: oldDirectoryServerUrl, with: newDirectoryServerUrl)
+                    childItem.serverUrl = movedServerUrl
+                    database.add(childItem, update: .all)
+                    Logger.ncFilesDatabase.debug("Moved childItem at \(oldServerUrl) to \(movedServerUrl)")
+                }
+            }
+        } catch let error {
+            Logger.ncFilesDatabase.error("Could not rename directory metadata with ocId: \(ocId, privacy: .public) to new serverUrl: \(newServerUrl), received error: \(error.localizedDescription, privacy: .public)")
+
+            return nil
+        }
+
+        let updatedChildItemResults = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, newDirectoryServerUrl)
+        return sortedItemMetadatas(updatedChildItemResults)
+    }
+}
index 7f18fcc744077325bbfddb0f5b3811a054e3f70a..0541ff819114b51f995c73b94981eb53d6d2f97e 100644 (file)
@@ -69,7 +69,7 @@ class NextcloudFilesDatabaseManager : NSObject {
         super.init()
     }
 
-    private func ncDatabase() -> Realm {
+    func ncDatabase() -> Realm {
         let realm = try! Realm()
         realm.refresh()
         return realm
@@ -89,7 +89,7 @@ class NextcloudFilesDatabaseManager : NSObject {
         return nil
     }
 
-    private func sortedItemMetadatas(_ metadatas: Results<NextcloudItemMetadataTable>) -> [NextcloudItemMetadataTable] {
+    func sortedItemMetadatas(_ metadatas: Results<NextcloudItemMetadataTable>) -> [NextcloudItemMetadataTable] {
         let sortedMetadatas = metadatas.sorted(byKeyPath: "fileName", ascending: true)
         return Array(sortedMetadatas.map { NextcloudItemMetadataTable(value: $0) })
     }
@@ -324,132 +324,6 @@ class NextcloudFilesDatabaseManager : NSObject {
         return nil
     }
 
-    func directoryMetadata(account: String, serverUrl: String) -> NextcloudItemMetadataTable? {
-        // We want to split by "/" (e.g. cloud.nc.com/files/a/b) but we need to be mindful of "https://c.nc.com"
-        let problematicSeparator = "://"
-        let placeholderSeparator = "__TEMP_REPLACE__"
-        let serverUrlWithoutPrefix = serverUrl.replacingOccurrences(of: problematicSeparator, with: placeholderSeparator)
-        var splitServerUrl = serverUrlWithoutPrefix.split(separator: "/")
-        let directoryItemFileName = String(splitServerUrl.removeLast())
-        let directoryItemServerUrl = splitServerUrl.joined(separator: "/").replacingOccurrences(of: placeholderSeparator, with: problematicSeparator)
-
-        if let metadata = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND directory == true", account, directoryItemServerUrl, directoryItemFileName).first {
-            return NextcloudItemMetadataTable(value: metadata)
-        }
-
-        return nil
-    }
-
-    func childItemsForDirectory(_ directoryMetadata: NextcloudItemMetadataTable) -> [NextcloudItemMetadataTable] {
-        let directoryServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
-        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("serverUrl BEGINSWITH %@", directoryServerUrl)
-        return sortedItemMetadatas(metadatas)
-    }
-
-    func childDirectoriesForDirectory(_ directoryMetadata: NextcloudItemMetadataTable) -> [NextcloudItemMetadataTable] {
-        let directoryServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
-        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("serverUrl BEGINSWITH %@ AND directory == true", directoryServerUrl)
-        return sortedItemMetadatas(metadatas)
-    }
-
-    func parentDirectoryMetadataForItem(_ itemMetadata: NextcloudItemMetadataTable) -> NextcloudItemMetadataTable? {
-        return directoryMetadata(account: itemMetadata.account, serverUrl: itemMetadata.serverUrl)
-    }
-
-    func directoryMetadata(ocId: String) -> NextcloudItemMetadataTable? {
-        if let metadata = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("ocId == %@ AND directory == true", ocId).first {
-            return NextcloudItemMetadataTable(value: metadata)
-        }
-
-        return nil
-    }
-
-    func directoryMetadatas(account: String) -> [NextcloudItemMetadataTable] {
-        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND directory == true", account)
-        return sortedItemMetadatas(metadatas)
-    }
-
-    func directoryMetadatas(account: String, parentDirectoryServerUrl: String) -> [NextcloudItemMetadataTable] {
-        let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND parentDirectoryServerUrl == %@ AND directory == true", account, parentDirectoryServerUrl)
-        return sortedItemMetadatas(metadatas)
-    }
-
-    // Deletes all metadatas related to the info of the directory provided
-    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 nil
-        }
-
-        let directoryMetadataCopy = NextcloudItemMetadataTable(value: directoryMetadata)
-        let directoryUrlPath = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
-        let directoryAccount = directoryMetadata.account
-        let directoryEtag = directoryMetadata.etag
-
-        Logger.ncFilesDatabase.debug("Deleting root directory metadata in recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryEtag, privacy: .public), serverUrl: \(directoryUrlPath, privacy: .public)")
-
-        guard deleteItemMetadata(ocId: directoryMetadata.ocId) else {
-            Logger.ncFilesDatabase.debug("Failure to delete root directory metadata in recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryEtag, privacy: .public), serverUrl: \(directoryUrlPath, privacy: .public)")
-            return nil
-        }
-
-        var deletedMetadatas: [NextcloudItemMetadataTable] = [directoryMetadataCopy]
-
-        let results = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryAccount, directoryUrlPath)
-
-        for result in results {
-            let successfulItemMetadataDelete = deleteItemMetadata(ocId: result.ocId)
-            if (successfulItemMetadataDelete) {
-                deletedMetadatas.append(NextcloudItemMetadataTable(value: result))
-            }
-
-            if localFileMetadataFromOcId(result.ocId) != nil {
-                deleteLocalFileMetadata(ocId: result.ocId)
-            }
-        }
-
-        Logger.ncFilesDatabase.debug("Completed deletions in directory recursive delete. ocID: \(directoryMetadata.ocId, privacy: .public), etag: \(directoryEtag, privacy: .public), serverUrl: \(directoryUrlPath, privacy: .public)")
-
-        return deletedMetadatas
-    }
-
-    func renameDirectoryAndPropagateToChildren(ocId: String, newServerUrl: String, newFileName: 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 a directory with ocID \(ocId, privacy: .public), cannot proceed with recursive renaming")
-            return nil
-        }
-
-        let oldItemServerUrl = directoryMetadata.serverUrl
-        let oldDirectoryServerUrl = oldItemServerUrl + "/" + directoryMetadata.fileName
-        let newDirectoryServerUrl = newServerUrl + "/" + newFileName
-        let childItemResults = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, oldDirectoryServerUrl)
-
-        renameItemMetadata(ocId: ocId, newServerUrl: newServerUrl, newFileName: newFileName)
-        Logger.ncFilesDatabase.debug("Renamed root renaming directory")
-
-        do {
-            try database.write {
-                for childItem in childItemResults {
-                    let oldServerUrl = childItem.serverUrl
-                    let movedServerUrl = oldServerUrl.replacingOccurrences(of: oldDirectoryServerUrl, with: newDirectoryServerUrl)
-                    childItem.serverUrl = movedServerUrl
-                    database.add(childItem, update: .all)
-                    Logger.ncFilesDatabase.debug("Moved childItem at \(oldServerUrl) to \(movedServerUrl)")
-                }
-            }
-        } catch let error {
-            Logger.ncFilesDatabase.error("Could not rename directory metadata with ocId: \(ocId, privacy: .public) to new serverUrl: \(newServerUrl), received error: \(error.localizedDescription, privacy: .public)")
-
-            return nil
-        }
-
-        let updatedChildItemResults = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, newDirectoryServerUrl)
-        return sortedItemMetadatas(updatedChildItemResults)
-    }
 
     func localFileMetadataFromOcId(_ ocId: String) -> NextcloudLocalFileMetadataTable? {
         if let metadata = ncDatabase().objects(NextcloudLocalFileMetadataTable.self).filter("ocId == %@", ocId).first {
index 590657ccabdfa93b8b09d34a16ecb01b764f266d..4c4d2f10193aba1a99d2592910d054dba6085917 100644 (file)
@@ -15,6 +15,7 @@
                5318AD9529BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5318AD9429BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift */; };
                5318AD9729BF493600CBB71C /* FileProviderMaterialisedEnumerationObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5318AD9629BF493600CBB71C /* FileProviderMaterialisedEnumerationObserver.swift */; };
                5318AD9929BF58D000CBB71C /* NKError+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5318AD9829BF58D000CBB71C /* NKError+Extensions.swift */; };
+               5352B36629DC14970011CE03 /* NextcloudFilesDatabaseManager+Directories.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5352B36529DC14970011CE03 /* NextcloudFilesDatabaseManager+Directories.swift */; };
                5352E85B29B7BFE6002CE85C /* Progress+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5352E85A29B7BFE6002CE85C /* Progress+Extensions.swift */; };
                535AE30E29C0A2CC0042A9BA /* Logger+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535AE30D29C0A2CC0042A9BA /* Logger+Extensions.swift */; };
                536EFBF7295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536EFBF6295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift */; };
                5318AD9429BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudLocalFileMetadataTable.swift; sourceTree = "<group>"; };
                5318AD9629BF493600CBB71C /* FileProviderMaterialisedEnumerationObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderMaterialisedEnumerationObserver.swift; sourceTree = "<group>"; };
                5318AD9829BF58D000CBB71C /* NKError+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NKError+Extensions.swift"; sourceTree = "<group>"; };
+               5352B36529DC14970011CE03 /* NextcloudFilesDatabaseManager+Directories.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NextcloudFilesDatabaseManager+Directories.swift"; sourceTree = "<group>"; };
                5352E85A29B7BFE6002CE85C /* Progress+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Progress+Extensions.swift"; sourceTree = "<group>"; };
                535AE30D29C0A2CC0042A9BA /* Logger+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Logger+Extensions.swift"; sourceTree = "<group>"; };
                536EFBF6295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderSocketLineProcessor.swift; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                5307A6F129675346001E0C6A /* NextcloudFilesDatabaseManager.swift */,
+                               5352B36529DC14970011CE03 /* NextcloudFilesDatabaseManager+Directories.swift */,
                                5318AD9029BF42FB00CBB71C /* NextcloudItemMetadataTable.swift */,
                                53ED472729C88E7000795DB1 /* NextcloudItemMetadataTable+NKFile.swift */,
                                5318AD9429BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift */,
                                53D056312970594F00988392 /* LocalFilesUtils.swift in Sources */,
                                538E396F27F4765000FA63D5 /* FileProviderItem.swift in Sources */,
                                5318AD9129BF42FB00CBB71C /* NextcloudItemMetadataTable.swift in Sources */,
+                               5352B36629DC14970011CE03 /* NextcloudFilesDatabaseManager+Directories.swift in Sources */,
                                5318AD9729BF493600CBB71C /* FileProviderMaterialisedEnumerationObserver.swift in Sources */,
                                538E397127F4765000FA63D5 /* FileProviderEnumerator.swift in Sources */,
                        );