зеркало из https://github.com/nextcloud/desktop.git
Remove redundant directory metadata tables in File Provider
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
This commit is contained in:
Родитель
2e70c82663
Коммит
872186248a
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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 RealmSwift
|
||||
|
||||
class NextcloudDirectoryMetadataTable: Object {
|
||||
func isInSameRemoteState(_ comparingMetadata: NextcloudDirectoryMetadataTable) -> Bool {
|
||||
return comparingMetadata.etag == self.etag &&
|
||||
comparingMetadata.e2eEncrypted == self.e2eEncrypted &&
|
||||
comparingMetadata.favorite == self.favorite &&
|
||||
comparingMetadata.permissions == self.permissions
|
||||
}
|
||||
|
||||
@Persisted(primaryKey: true) var ocId: String
|
||||
@Persisted var account = ""
|
||||
@Persisted var colorFolder: String?
|
||||
@Persisted var e2eEncrypted: Bool = false
|
||||
@Persisted var etag = ""
|
||||
@Persisted var favorite: Bool = false
|
||||
@Persisted var fileId = ""
|
||||
@Persisted var offline: Bool = false
|
||||
@Persisted var permissions = ""
|
||||
@Persisted var richWorkspace: String?
|
||||
@Persisted var serverUrl = ""
|
||||
@Persisted var parentDirectoryServerUrl = ""
|
||||
}
|
|
@ -54,7 +54,7 @@ class NextcloudFilesDatabaseManager : NSObject {
|
|||
let config = Realm.Configuration(
|
||||
fileURL: self.databasePath,
|
||||
schemaVersion: self.schemaVersion,
|
||||
objectTypes: [NextcloudItemMetadataTable.self, NextcloudDirectoryMetadataTable.self, NextcloudLocalFileMetadataTable.self]
|
||||
objectTypes: [NextcloudItemMetadataTable.self, NextcloudLocalFileMetadataTable.self]
|
||||
)
|
||||
|
||||
Realm.Configuration.defaultConfiguration = config
|
||||
|
@ -290,163 +290,60 @@ class NextcloudFilesDatabaseManager : NSObject {
|
|||
return nil
|
||||
}
|
||||
|
||||
func directoryMetadata(account: String, serverUrl: String) -> NextcloudDirectoryMetadataTable? {
|
||||
if let metadata = ncDatabase().objects(NextcloudDirectoryMetadataTable.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first {
|
||||
return NextcloudDirectoryMetadataTable(value: metadata)
|
||||
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 directoryMetadata(ocId: String) -> NextcloudDirectoryMetadataTable? {
|
||||
if let metadata = ncDatabase().objects(NextcloudDirectoryMetadataTable.self).filter("ocId == %@", ocId).first {
|
||||
return NextcloudDirectoryMetadataTable(value: metadata)
|
||||
}
|
||||
|
||||
return nil
|
||||
func childDirectoriesForDirectory(_ directoryMetadata: NextcloudItemMetadataTable) -> [NextcloudItemMetadataTable] {
|
||||
let directoryServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
|
||||
let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("serverUrl BEGINSWITH %@ AND ocId != %@ AND directory == true", directoryServerUrl, directoryMetadata.account)
|
||||
return sortedItemMetadatas(metadatas)
|
||||
}
|
||||
|
||||
private func sortedDirectoryMetadatas(_ metadatas: Results<NextcloudDirectoryMetadataTable>) -> [NextcloudDirectoryMetadataTable] {
|
||||
let sortedMetadatas = metadatas.sorted(byKeyPath: "serverUrl", ascending: true)
|
||||
return Array(sortedMetadatas.map { NextcloudDirectoryMetadataTable(value: $0) })
|
||||
}
|
||||
|
||||
func childDirectoriesForDirectory(_ directoryMetadata: NextcloudDirectoryMetadataTable) -> [NextcloudDirectoryMetadataTable] {
|
||||
let metadatas = ncDatabase().objects(NextcloudDirectoryMetadataTable.self).filter("serverUrl BEGINSWITH %@ AND ocId != %@", directoryMetadata.serverUrl, directoryMetadata.account)
|
||||
return sortedDirectoryMetadatas(metadatas)
|
||||
}
|
||||
|
||||
func parentDirectoryMetadataForItem(_ itemMetadata: NextcloudItemMetadataTable) -> NextcloudDirectoryMetadataTable? {
|
||||
func parentDirectoryMetadataForItem(_ itemMetadata: NextcloudItemMetadataTable) -> NextcloudItemMetadataTable? {
|
||||
return directoryMetadata(account: itemMetadata.account, serverUrl: itemMetadata.serverUrl)
|
||||
}
|
||||
|
||||
func directoryMetadatas(account: String) -> [NextcloudDirectoryMetadataTable] {
|
||||
let metadatas = ncDatabase().objects(NextcloudDirectoryMetadataTable.self).filter("account == %@", account)
|
||||
return sortedDirectoryMetadatas(metadatas)
|
||||
}
|
||||
|
||||
func directoryMetadatas(account: String, parentDirectoryServerUrl: String) -> [NextcloudDirectoryMetadataTable] {
|
||||
let metadatas = ncDatabase().objects(NextcloudDirectoryMetadataTable.self).filter("account == %@ AND parentDirectoryServerUrl == %@", account, parentDirectoryServerUrl)
|
||||
return sortedDirectoryMetadatas(metadatas)
|
||||
}
|
||||
|
||||
private func processDirectoryMetadatasToDelete(databaseToWriteTo: Realm,
|
||||
existingDirectoryMetadatas: Results<NextcloudDirectoryMetadataTable>,
|
||||
updatedDirectoryMetadatas: [NextcloudDirectoryMetadataTable]) {
|
||||
|
||||
for existingMetadata in existingDirectoryMetadatas {
|
||||
guard !updatedDirectoryMetadatas.contains(where: { $0.ocId == existingMetadata.ocId }),
|
||||
let metadataToDelete = directoryMetadata(ocId: existingMetadata.ocId) else { continue }
|
||||
|
||||
Logger.ncFilesDatabase.debug("Deleting directory metadata during update. ocID: \(existingMetadata.ocId, privacy: .public), etag: \(existingMetadata.etag, privacy: .public), serverUrl: \(existingMetadata.serverUrl)")
|
||||
|
||||
self.deleteDirectoryAndSubdirectoriesMetadata(ocId: metadataToDelete.ocId)
|
||||
}
|
||||
}
|
||||
|
||||
private func processDirectoryMetadatasToUpdate(databaseToWriteTo: Realm,
|
||||
existingDirectoryMetadatas: Results<NextcloudDirectoryMetadataTable>,
|
||||
updatedDirectoryMetadatas: [NextcloudDirectoryMetadataTable]) {
|
||||
|
||||
assert(databaseToWriteTo.isInWriteTransaction)
|
||||
|
||||
for updatedMetadata in updatedDirectoryMetadatas {
|
||||
if let existingMetadata = existingDirectoryMetadatas.first(where: { $0.ocId == updatedMetadata.ocId }) {
|
||||
|
||||
if !existingMetadata.isInSameRemoteState(updatedMetadata) {
|
||||
|
||||
databaseToWriteTo.add(NextcloudDirectoryMetadataTable(value: updatedMetadata), update: .all)
|
||||
Logger.ncFilesDatabase.debug("Updated existing directory metadata. ocID: \(updatedMetadata.ocId, privacy: .public), etag: \(updatedMetadata.etag, privacy: .public), serverUrl: \(updatedMetadata.serverUrl)")
|
||||
}
|
||||
// Don't update under other circumstances in which the metadata already exists
|
||||
|
||||
} else { // This is a new metadata
|
||||
databaseToWriteTo.add(NextcloudDirectoryMetadataTable(value: updatedMetadata), update: .all)
|
||||
Logger.ncFilesDatabase.debug("Created new directory metadata during update. ocID: \(updatedMetadata.ocId, privacy: .public), etag: \(updatedMetadata.etag, privacy: .public), serverUrl: \(updatedMetadata.serverUrl)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateDirectoryMetadatas(account: String, parentDirectoryServerUrl: String, updatedDirectoryMetadatas: [NextcloudDirectoryMetadataTable]) {
|
||||
let database = ncDatabase()
|
||||
|
||||
let existingDirectoryMetadatas = ncDatabase().objects(NextcloudDirectoryMetadataTable.self).filter("account == %@ AND parentDirectoryServerUrl == %@", account, parentDirectoryServerUrl)
|
||||
|
||||
// Actual db writing handled internally
|
||||
processDirectoryMetadatasToDelete(databaseToWriteTo: database,
|
||||
existingDirectoryMetadatas: existingDirectoryMetadatas,
|
||||
updatedDirectoryMetadatas: updatedDirectoryMetadatas)
|
||||
|
||||
do {
|
||||
try database.write {
|
||||
|
||||
processDirectoryMetadatasToUpdate(databaseToWriteTo: database,
|
||||
existingDirectoryMetadatas: existingDirectoryMetadatas,
|
||||
updatedDirectoryMetadatas: updatedDirectoryMetadatas)
|
||||
}
|
||||
} catch let error {
|
||||
Logger.ncFilesDatabase.error("Could not update directory metadatas, received error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
func directoryMetadataFromItemMetadata(directoryItemMetadata: NextcloudItemMetadataTable, recordEtag: Bool = false) -> NextcloudDirectoryMetadataTable {
|
||||
var newDirectoryMetadata = NextcloudDirectoryMetadataTable()
|
||||
let directoryOcId = directoryItemMetadata.ocId
|
||||
|
||||
if let existingDirectoryMetadata = directoryMetadata(ocId: directoryOcId) {
|
||||
newDirectoryMetadata = existingDirectoryMetadata
|
||||
func directoryMetadata(ocId: String) -> NextcloudItemMetadataTable? {
|
||||
if let metadata = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("ocId == %@ AND directory == true", ocId).first {
|
||||
return NextcloudItemMetadataTable(value: metadata)
|
||||
}
|
||||
|
||||
if recordEtag {
|
||||
newDirectoryMetadata.etag = directoryItemMetadata.etag
|
||||
}
|
||||
|
||||
newDirectoryMetadata.ocId = directoryOcId
|
||||
newDirectoryMetadata.fileId = directoryItemMetadata.fileId
|
||||
newDirectoryMetadata.parentDirectoryServerUrl = directoryItemMetadata.serverUrl
|
||||
newDirectoryMetadata.serverUrl = directoryItemMetadata.serverUrl + "/" + directoryItemMetadata.fileNameView
|
||||
newDirectoryMetadata.account = directoryItemMetadata.account
|
||||
newDirectoryMetadata.e2eEncrypted = directoryItemMetadata.e2eEncrypted
|
||||
newDirectoryMetadata.favorite = directoryItemMetadata.favorite
|
||||
newDirectoryMetadata.permissions = directoryItemMetadata.permissions
|
||||
|
||||
return newDirectoryMetadata
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateDirectoryMetadatasFromItemMetadatas(account: String, parentDirectoryServerUrl: String, updatedDirectoryItemMetadatas: [NextcloudItemMetadataTable], recordEtag: Bool = false) {
|
||||
|
||||
var updatedDirMetadatas: [NextcloudDirectoryMetadataTable] = []
|
||||
|
||||
for directoryItemMetadata in updatedDirectoryItemMetadatas {
|
||||
let newDirectoryMetadata = directoryMetadataFromItemMetadata(directoryItemMetadata: directoryItemMetadata, recordEtag: recordEtag)
|
||||
updatedDirMetadatas.append(newDirectoryMetadata)
|
||||
}
|
||||
|
||||
updateDirectoryMetadatas(account: account, parentDirectoryServerUrl: parentDirectoryServerUrl, updatedDirectoryMetadatas: updatedDirMetadatas)
|
||||
func directoryMetadatas(account: String) -> [NextcloudItemMetadataTable] {
|
||||
let metadatas = ncDatabase().objects(NextcloudItemMetadataTable.self).filter("account == %@ AND directory == true", account)
|
||||
return sortedItemMetadatas(metadatas)
|
||||
}
|
||||
|
||||
func addDirectoryMetadata(_ metadata: NextcloudDirectoryMetadataTable) {
|
||||
let database = ncDatabase()
|
||||
|
||||
do {
|
||||
try database.write {
|
||||
database.add(metadata, update: .all)
|
||||
Logger.ncFilesDatabase.debug("Added new directory metadata. ocId: \(metadata.ocId, privacy: .public), etag: \(metadata.etag, privacy: .public), serverUrl: \(metadata.serverUrl)")
|
||||
}
|
||||
} catch let error {
|
||||
Logger.ncFilesDatabase.error("Could not add new directory metadata. ocId: \(metadata.ocId, privacy: .public), etag: \(metadata.etag, privacy: .public), serverUrl: \(metadata.serverUrl), received error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
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) {
|
||||
let database = ncDatabase()
|
||||
guard let directoryMetadata = database.objects(NextcloudDirectoryMetadataTable.self).filter("ocId == %@", ocId).first else {
|
||||
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
|
||||
}
|
||||
|
||||
let results = database.objects(NextcloudDirectoryMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, directoryMetadata.serverUrl)
|
||||
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)
|
||||
|
@ -455,11 +352,11 @@ class NextcloudFilesDatabaseManager : NSObject {
|
|||
|
||||
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: \(directoryMetadata.serverUrl)")
|
||||
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)
|
||||
}
|
||||
} 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: \(directoryMetadata.serverUrl), received error: \(error.localizedDescription, privacy: .public)")
|
||||
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)")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,25 +365,19 @@ class NextcloudFilesDatabaseManager : NSObject {
|
|||
let database = ncDatabase()
|
||||
|
||||
do {
|
||||
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
|
||||
}
|
||||
|
||||
let oldServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
|
||||
|
||||
let childItemResults = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryMetadata.account, oldServerUrl)
|
||||
|
||||
renameItemMetadata(ocId: ocId, newServerUrl: newServerUrl, newFileName: newFileName)
|
||||
Logger.ncFilesDatabase.debug("Renamed root renaming directory")
|
||||
|
||||
try database.write {
|
||||
guard let directoryTableResult = database.objects(NextcloudDirectoryMetadataTable.self).filter("ocId == %@", ocId).first,
|
||||
let directoryItemResult = database.objects(NextcloudItemMetadataTable.self).filter("ocId == %@", ocId).first else {
|
||||
Logger.ncFilesDatabase.error("Could not find a directory with ocID \(ocId, privacy: .public), cannot proceed with recursive renaming")
|
||||
return
|
||||
}
|
||||
|
||||
let oldServerUrl = directoryTableResult.serverUrl
|
||||
|
||||
let childItemResults = database.objects(NextcloudItemMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryTableResult.account, oldServerUrl)
|
||||
let childDirectoryResults = database.objects(NextcloudDirectoryMetadataTable.self).filter("account == %@ AND serverUrl BEGINSWITH %@", directoryTableResult.account, oldServerUrl)
|
||||
|
||||
directoryTableResult.serverUrl = newServerUrl
|
||||
database.add(directoryTableResult, update: .all)
|
||||
directoryItemResult.fileName = newFileName
|
||||
directoryItemResult.fileNameView = newFileName
|
||||
database.add(directoryItemResult, update: .all)
|
||||
Logger.ncFilesDatabase.debug("Renamed root renaming directory at \(oldServerUrl) to \(newServerUrl)")
|
||||
|
||||
for childItem in childItemResults {
|
||||
let oldServerUrl = childItem.serverUrl
|
||||
let movedServerUrl = oldServerUrl.replacingOccurrences(of: oldServerUrl, with: newServerUrl)
|
||||
|
@ -494,17 +385,6 @@ class NextcloudFilesDatabaseManager : NSObject {
|
|||
database.add(childItem, update: .all)
|
||||
Logger.ncFilesDatabase.debug("Moved childItem at \(oldServerUrl) to \(movedServerUrl)")
|
||||
}
|
||||
|
||||
for childDirectory in childDirectoryResults {
|
||||
let oldServerUrl = childDirectory.serverUrl
|
||||
let oldParentServerUrl = childDirectory.parentDirectoryServerUrl
|
||||
let movedServerUrl = oldServerUrl.replacingOccurrences(of: oldServerUrl, with: newServerUrl)
|
||||
let movedParentServerUrl = oldServerUrl.replacingOccurrences(of: oldParentServerUrl, with: newServerUrl)
|
||||
childDirectory.serverUrl = movedServerUrl
|
||||
childDirectory.parentDirectoryServerUrl = movedParentServerUrl
|
||||
database.add(childDirectory, update: .all)
|
||||
Logger.ncFilesDatabase.debug("Moved childDirectory 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)")
|
||||
|
|
|
@ -113,8 +113,10 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
dispatchGroup.enter() // Add to outer counter
|
||||
|
||||
dispatchQueue.async {
|
||||
let directoryServerUrl = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
|
||||
|
||||
guard serverError == nil else {
|
||||
Logger.enumeration.info("Skipping enumeration of directory for working set: \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) as we have an error.")
|
||||
Logger.enumeration.info("Skipping enumeration of directory for working set: \(directoryServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) as we have an error.")
|
||||
dispatchGroup.leave()
|
||||
return;
|
||||
}
|
||||
|
@ -122,9 +124,9 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
let currentNetworkTaskDispatchGroup = DispatchGroup() // To make this serial queue wait until this task is done
|
||||
currentNetworkTaskDispatchGroup.enter()
|
||||
|
||||
FileProviderEnumerator.readServerUrl(directoryMetadata.serverUrl, ncAccount: self.ncAccount, ncKit: self.ncKit) { metadatas, _, _, _, readError in
|
||||
FileProviderEnumerator.readServerUrl(directoryServerUrl, ncAccount: self.ncAccount, ncKit: self.ncKit) { metadatas, _, _, _, readError in
|
||||
guard readError == nil else {
|
||||
Logger.enumeration.error("Finishing enumeration of working set directory \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with error \(readError!.localizedDescription, privacy: .public)")
|
||||
Logger.enumeration.error("Finishing enumeration of working set directory \(directoryServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with error \(readError!.localizedDescription, privacy: .public)")
|
||||
|
||||
let nkError = NKError(error: readError!)
|
||||
if nkError.isUnauthenticatedError || nkError.isCouldntConnectError {
|
||||
|
@ -140,7 +142,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
if let metadatas = metadatas {
|
||||
allMetadatas += metadatas
|
||||
} else {
|
||||
allMetadatas += dbManager.itemMetadatas(account: self.ncAccount.ncKitAccount, serverUrl: directoryMetadata.serverUrl)
|
||||
allMetadatas += dbManager.itemMetadatas(account: self.ncAccount.ncKitAccount, serverUrl: directoryServerUrl)
|
||||
}
|
||||
|
||||
currentNetworkTaskDispatchGroup.leave()
|
||||
|
@ -419,9 +421,8 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
|
||||
private static func fullRecursiveScan(ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool, completionHandler: @escaping(_ newMetadatas: [NextcloudItemMetadataTable], _ updatedMetadatas: [NextcloudItemMetadataTable], _ deletedMetadatas: [NextcloudItemMetadataTable]) -> Void) {
|
||||
|
||||
let rootContainerDirectoryMetadata = NextcloudDirectoryMetadataTable()
|
||||
rootContainerDirectoryMetadata.serverUrl = ncAccount.davFilesUrl
|
||||
rootContainerDirectoryMetadata.account = ncAccount.ncKitAccount
|
||||
let rootContainerDirectoryMetadata = NextcloudItemMetadataTable()
|
||||
rootContainerDirectoryMetadata.directory = true
|
||||
rootContainerDirectoryMetadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
|
||||
|
||||
// Create a serial dispatch queue
|
||||
|
@ -436,7 +437,9 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
}
|
||||
}
|
||||
|
||||
private static func scanRecursively(_ directoryMetadata: NextcloudDirectoryMetadataTable, ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool) -> (metadatas: [NextcloudItemMetadataTable], newMetadatas: [NextcloudItemMetadataTable], updatedMetadatas: [NextcloudItemMetadataTable], deletedMetadatas: [NextcloudItemMetadataTable]) {
|
||||
private static func scanRecursively(_ directoryMetadata: NextcloudItemMetadataTable, ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool) -> (metadatas: [NextcloudItemMetadataTable], newMetadatas: [NextcloudItemMetadataTable], updatedMetadatas: [NextcloudItemMetadataTable], deletedMetadatas: [NextcloudItemMetadataTable]) {
|
||||
|
||||
assert(directoryMetadata.directory, "Can only recursively scan a directory.")
|
||||
|
||||
var allMetadatas: [NextcloudItemMetadataTable] = []
|
||||
var allNewMetadatas: [NextcloudItemMetadataTable] = []
|
||||
|
@ -448,8 +451,12 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
|
||||
dispatchGroup.enter()
|
||||
|
||||
Logger.enumeration.debug("About to read: \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
FileProviderEnumerator.readServerUrl(directoryMetadata.serverUrl, ncAccount: ncAccount, ncKit: ncKit, stopAtMatchingEtags: scanChangesOnly) { metadatas, newMetadatas, updatedMetadatas, deletedMetadatas, readError in
|
||||
let itemServerUrl = directoryMetadata.ocId == NSFileProviderItemIdentifier.rootContainer.rawValue ?
|
||||
ncAccount.davFilesUrl : directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
|
||||
|
||||
Logger.enumeration.debug("About to read: \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
|
||||
FileProviderEnumerator.readServerUrl(itemServerUrl, ncAccount: ncAccount, ncKit: ncKit, stopAtMatchingEtags: scanChangesOnly) { metadatas, newMetadatas, updatedMetadatas, deletedMetadatas, readError in
|
||||
|
||||
if readError != nil {
|
||||
let nkReadError = NKError(error: readError!)
|
||||
|
@ -457,7 +464,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
// Is the error is that we have found matching etags on this item, then ignore it
|
||||
// if we are doing a full rescan
|
||||
guard nkReadError.isNoChangesError && scanChangesOnly else {
|
||||
Logger.enumeration.error("Finishing enumeration of changes at \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with \(readError!.localizedDescription, privacy: .public)")
|
||||
Logger.enumeration.error("Finishing enumeration of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with \(readError!.localizedDescription, privacy: .public)")
|
||||
|
||||
if nkReadError.isNotFoundError {
|
||||
Logger.enumeration.info("404 error means item no longer exists. Deleting metadata and reporting as deletion without error")
|
||||
|
@ -479,30 +486,30 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
}
|
||||
}
|
||||
|
||||
Logger.enumeration.info("Finished reading serverUrl: \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
Logger.enumeration.info("Finished reading serverUrl: \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
|
||||
if let metadatas = metadatas {
|
||||
allMetadatas += metadatas
|
||||
} else {
|
||||
Logger.enumeration.warning("WARNING: Nil metadatas received for reading of changes at \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
Logger.enumeration.warning("WARNING: Nil metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
}
|
||||
|
||||
if let newMetadatas = newMetadatas {
|
||||
allNewMetadatas += newMetadatas
|
||||
} else {
|
||||
Logger.enumeration.warning("WARNING: Nil new metadatas received for reading of changes at \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
Logger.enumeration.warning("WARNING: Nil new metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
}
|
||||
|
||||
if let updatedMetadatas = updatedMetadatas {
|
||||
allUpdatedMetadatas += updatedMetadatas
|
||||
} else {
|
||||
Logger.enumeration.warning("WARNING: Nil updated metadatas received for reading of changes at \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
Logger.enumeration.warning("WARNING: Nil updated metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
}
|
||||
|
||||
if let deletedMetadatas = deletedMetadatas {
|
||||
allDeletedMetadatas += deletedMetadatas
|
||||
} else {
|
||||
Logger.enumeration.warning("WARNING: Nil deleted metadatas received for reading of changes at \(directoryMetadata.serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
Logger.enumeration.warning("WARNING: Nil deleted metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
}
|
||||
|
||||
dispatchGroup.leave()
|
||||
|
@ -510,7 +517,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
|
||||
dispatchGroup.wait()
|
||||
|
||||
var updatedDirectories: [NextcloudDirectoryMetadataTable] = []
|
||||
var updatedDirectories: [NextcloudItemMetadataTable] = []
|
||||
for updatedMetadata in allUpdatedMetadatas {
|
||||
if updatedMetadata.directory {
|
||||
guard let directoryMetadata = dbManager.directoryMetadata(ocId: updatedMetadata.ocId) else {
|
||||
|
@ -600,18 +607,9 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
// We have now scanned this directory's contents, so update with etag in order to not check again if not needed
|
||||
// unless it's the root container
|
||||
if serverUrl != ncAccount.davFilesUrl {
|
||||
let directoryItemMetadata = dbManager.directoryMetadataFromItemMetadata(directoryItemMetadata: directoryMetadata, recordEtag: true)
|
||||
dbManager.addDirectoryMetadata(directoryItemMetadata)
|
||||
dbManager.addItemMetadata(directoryMetadata)
|
||||
}
|
||||
|
||||
// STORE ETAG-LESS DIRECTORY METADATA FOR CHILD DIRECTORIES
|
||||
// Since we haven't scanned the contents of the child directories, don't record their itemMetadata etags in the directory tables
|
||||
// This will delete database records for directories that we did not get from the readFileOrFolder (indicating they were deleted)
|
||||
// as well as deleting the records for all the children contained by the directories.
|
||||
// TODO: Find a way to detect if files have been moved rather than deleted and change the metadata server urls, move the materialised files
|
||||
dbManager.updateDirectoryMetadatasFromItemMetadatas(account: ncKitAccount, parentDirectoryServerUrl: serverUrl, updatedDirectoryItemMetadatas: childDirectoriesMetadata)
|
||||
// TODO: Notify working set changed if new folders found
|
||||
|
||||
dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrl, updatedMetadatas: metadatas) { newMetadatas, updatedMetadatas, deletedMetadatas in
|
||||
completionHandler(metadatas, newMetadatas, updatedMetadatas, deletedMetadatas, nil)
|
||||
}
|
||||
|
|
|
@ -232,28 +232,22 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
return Progress()
|
||||
}
|
||||
|
||||
var parentItemMetadata: NextcloudDirectoryMetadataTable?
|
||||
var parentItemServerUrl: String
|
||||
|
||||
if parentItemIdentifier == .rootContainer {
|
||||
let rootMetadata = NextcloudDirectoryMetadataTable()
|
||||
|
||||
rootMetadata.account = ncAccount.ncKitAccount
|
||||
rootMetadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
|
||||
rootMetadata.serverUrl = ncAccount.davFilesUrl
|
||||
|
||||
parentItemMetadata = rootMetadata
|
||||
parentItemServerUrl = ncAccount.davFilesUrl
|
||||
} else {
|
||||
parentItemMetadata = dbManager.directoryMetadata(ocId: parentItemIdentifier.rawValue)
|
||||
}
|
||||
guard let parentItemMetadata = dbManager.directoryMetadata(ocId: parentItemIdentifier.rawValue) else {
|
||||
Logger.fileProviderExtension.error("Not creating item: \(itemTemplate.itemIdentifier.rawValue, privacy: .public), could not find metadata for parentItemIdentifier \(parentItemIdentifier.rawValue, privacy: .public)")
|
||||
completionHandler(itemTemplate, NSFileProviderItemFields(), false, NSFileProviderError(.noSuchItem))
|
||||
return Progress()
|
||||
}
|
||||
|
||||
guard let parentItemMetadata = parentItemMetadata else {
|
||||
Logger.fileProviderExtension.error("Not creating item: \(itemTemplate.itemIdentifier.rawValue, privacy: .public), could not find metadata for parentItemIdentifier \(parentItemIdentifier.rawValue, privacy: .public)")
|
||||
completionHandler(itemTemplate, NSFileProviderItemFields(), false, NSFileProviderError(.noSuchItem))
|
||||
return Progress()
|
||||
parentItemServerUrl = parentItemMetadata.serverUrl + "/" + parentItemMetadata.fileName
|
||||
}
|
||||
|
||||
let fileNameLocalPath = url?.path ?? ""
|
||||
let newServerUrlFileName = parentItemMetadata.serverUrl + "/" + itemTemplate.filename
|
||||
let newServerUrlFileName = parentItemServerUrl + "/" + itemTemplate.filename
|
||||
|
||||
Logger.fileProviderExtension.debug("About to upload item with identifier: \(itemTemplate.itemIdentifier.rawValue, privacy: .public) of type: \(itemTemplate.contentType?.identifier ?? "UNKNOWN") (is folder: \(itemTemplateIsFolder ? "yes" : "no") and filename: \(itemTemplate.filename) to server url: \(newServerUrlFileName, privacy: OSLogPrivacy.auto(mask: .hash)) with contents located at: \(fileNameLocalPath, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
|
||||
|
@ -275,8 +269,6 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
DispatchQueue.global().async {
|
||||
dbManager.convertNKFilesFromDirectoryReadToItemMetadatas(files, account: account) { directoryMetadata, childDirectoriesMetadata, metadatas in
|
||||
|
||||
let newDirectoryMetadata = dbManager.directoryMetadataFromItemMetadata(directoryItemMetadata: directoryMetadata)
|
||||
dbManager.addDirectoryMetadata(newDirectoryMetadata)
|
||||
dbManager.addItemMetadata(directoryMetadata)
|
||||
|
||||
let fpItem = FileProviderItem(metadata: directoryMetadata, parentItemIdentifier: parentItemIdentifier, ncKit: self.ncKit)
|
||||
|
@ -323,7 +315,7 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
newMetadata.size = size
|
||||
newMetadata.contentType = itemTemplate.contentType?.preferredMIMEType ?? ""
|
||||
newMetadata.directory = itemTemplateIsFolder
|
||||
newMetadata.serverUrl = parentItemMetadata.serverUrl
|
||||
newMetadata.serverUrl = parentItemServerUrl
|
||||
newMetadata.session = ""
|
||||
newMetadata.sessionError = ""
|
||||
newMetadata.sessionTaskIdentifier = 0
|
||||
|
@ -362,28 +354,22 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
Logger.fileProviderExtension.warning("Modification for item: \(item.itemIdentifier.rawValue, privacy: .public) may already exist")
|
||||
}
|
||||
|
||||
var parentItemMetadata: NextcloudDirectoryMetadataTable?
|
||||
var parentItemServerUrl: String
|
||||
|
||||
if parentItemIdentifier == .rootContainer {
|
||||
let rootMetadata = NextcloudDirectoryMetadataTable()
|
||||
|
||||
rootMetadata.account = ncAccount.ncKitAccount
|
||||
rootMetadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
|
||||
rootMetadata.serverUrl = ncAccount.davFilesUrl
|
||||
|
||||
parentItemMetadata = rootMetadata
|
||||
parentItemServerUrl = ncAccount.davFilesUrl
|
||||
} else {
|
||||
parentItemMetadata = dbManager.directoryMetadata(ocId: parentItemIdentifier.rawValue)
|
||||
}
|
||||
guard let parentItemMetadata = dbManager.directoryMetadata(ocId: parentItemIdentifier.rawValue) else {
|
||||
Logger.fileProviderExtension.error("Not modifying item: \(item.itemIdentifier.rawValue, privacy: .public), could not find metadata for parentItemIdentifier \(parentItemIdentifier.rawValue, privacy: .public)")
|
||||
completionHandler(item, [], false, NSFileProviderError(.noSuchItem))
|
||||
return Progress()
|
||||
}
|
||||
|
||||
guard let parentItemMetadata = parentItemMetadata else {
|
||||
Logger.fileProviderExtension.error("Not modifying item: \(item.itemIdentifier.rawValue, privacy: .public), could not find metadata for parentItemIdentifier \(parentItemIdentifier.rawValue, privacy: .public)")
|
||||
completionHandler(item, [], false, NSFileProviderError(.noSuchItem))
|
||||
return Progress()
|
||||
parentItemServerUrl = parentItemMetadata.serverUrl + "/" + parentItemMetadata.fileName
|
||||
}
|
||||
|
||||
let fileNameLocalPath = newContents?.path ?? ""
|
||||
let newServerUrlFileName = parentItemMetadata.serverUrl + "/" + item.filename
|
||||
let newServerUrlFileName = parentItemServerUrl + "/" + item.filename
|
||||
|
||||
Logger.fileProviderExtension.debug("About to upload modified item with identifier: \(item.itemIdentifier.rawValue, privacy: .public) of type: \(item.contentType?.identifier ?? "UNKNOWN") (is folder: \(itemTemplateIsFolder ? "yes" : "no") and filename: \(item.filename, privacy: OSLogPrivacy.auto(mask: .hash)) to server url: \(newServerUrlFileName, privacy: OSLogPrivacy.auto(mask: .hash)) with contents located at: \(fileNameLocalPath, privacy: OSLogPrivacy.auto(mask: .hash))")
|
||||
|
||||
|
@ -427,7 +413,7 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
if itemTemplateIsFolder {
|
||||
dbManager.renameDirectoryAndPropagateToChildren(ocId: ocId, newServerUrl: newServerUrlFileName, newFileName: item.filename)
|
||||
} else {
|
||||
dbManager.renameItemMetadata(ocId: ocId, newServerUrl: parentItemMetadata.serverUrl, newFileName: item.filename)
|
||||
dbManager.renameItemMetadata(ocId: ocId, newServerUrl: parentItemServerUrl, newFileName: item.filename)
|
||||
}
|
||||
|
||||
guard let newMetadata = dbManager.itemMetadataFromOcId(ocId) else {
|
||||
|
@ -519,7 +505,7 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
newMetadata.size = size
|
||||
newMetadata.contentType = item.contentType?.preferredMIMEType ?? ""
|
||||
newMetadata.directory = itemTemplateIsFolder
|
||||
newMetadata.serverUrl = parentItemMetadata.serverUrl
|
||||
newMetadata.serverUrl = parentItemServerUrl
|
||||
newMetadata.session = ""
|
||||
newMetadata.sessionError = ""
|
||||
newMetadata.sessionTaskIdentifier = 0
|
||||
|
@ -631,6 +617,15 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension, NKComm
|
|||
materialisedEnumerator.enumerateItems(for: materialisedObserver, startingAt: startingPage)
|
||||
}
|
||||
|
||||
func signalEnumerator(completionHandler: @escaping(_ error: Error?) -> Void) {
|
||||
guard let fpManager = NSFileProviderManager(for: self.domain) else {
|
||||
Logger.fileProviderExtension.error("Could not get file provider manager for domain, could not signal enumerator. This might lead to future conflicts.")
|
||||
return
|
||||
}
|
||||
|
||||
fpManager.signalEnumerator(for: .workingSet, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
// MARK: Nextcloud desktop client communication
|
||||
func sendFileProviderDomainIdentifier() {
|
||||
let command = "FILE_PROVIDER_DOMAIN_IDENTIFIER_REQUEST_REPLY"
|
||||
|
|
|
@ -16,7 +16,7 @@ import Foundation
|
|||
import FileProvider
|
||||
|
||||
class NextcloudAccount: NSObject {
|
||||
let webDavFilesUrlSuffix: String = "/remote.php/dav/files/"
|
||||
private let webDavFilesUrlSuffix: String = "/remote.php/dav/files/"
|
||||
let username, password, ncKitAccount, serverUrl, davFilesUrl: String
|
||||
|
||||
init(user: String, serverUrl: String, password: String) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
5307A6EB2965DB8D001E0C6A /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 5307A6EA2965DB8D001E0C6A /* RealmSwift */; };
|
||||
5307A6F229675346001E0C6A /* NextcloudFilesDatabaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5307A6F129675346001E0C6A /* NextcloudFilesDatabaseManager.swift */; };
|
||||
5318AD9129BF42FB00CBB71C /* NextcloudItemMetadataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5318AD9029BF42FB00CBB71C /* NextcloudItemMetadataTable.swift */; };
|
||||
5318AD9329BF432B00CBB71C /* NextcloudDirectoryMetadataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5318AD9229BF432B00CBB71C /* NextcloudDirectoryMetadataTable.swift */; };
|
||||
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 */; };
|
||||
|
@ -137,7 +136,6 @@
|
|||
/* Begin PBXFileReference section */
|
||||
5307A6F129675346001E0C6A /* NextcloudFilesDatabaseManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudFilesDatabaseManager.swift; sourceTree = "<group>"; };
|
||||
5318AD9029BF42FB00CBB71C /* NextcloudItemMetadataTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudItemMetadataTable.swift; sourceTree = "<group>"; };
|
||||
5318AD9229BF432B00CBB71C /* NextcloudDirectoryMetadataTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudDirectoryMetadataTable.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
|
@ -219,7 +217,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
5307A6F129675346001E0C6A /* NextcloudFilesDatabaseManager.swift */,
|
||||
5318AD9229BF432B00CBB71C /* NextcloudDirectoryMetadataTable.swift */,
|
||||
5318AD9029BF42FB00CBB71C /* NextcloudItemMetadataTable.swift */,
|
||||
5318AD9429BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift */,
|
||||
);
|
||||
|
@ -563,7 +560,6 @@
|
|||
5352E85B29B7BFE6002CE85C /* Progress+Extensions.swift in Sources */,
|
||||
536EFC36295E3C1100F4CB13 /* NextcloudAccount.swift in Sources */,
|
||||
538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */,
|
||||
5318AD9329BF432B00CBB71C /* NextcloudDirectoryMetadataTable.swift in Sources */,
|
||||
536EFBF7295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift in Sources */,
|
||||
5318AD9929BF58D000CBB71C /* NKError+Extensions.swift in Sources */,
|
||||
5318AD9529BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift in Sources */,
|
||||
|
|
Загрузка…
Ссылка в новой задаче