-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFilesDatabaseManager+Directories.swift
More file actions
147 lines (126 loc) · 5.93 KB
/
FilesDatabaseManager+Directories.swift
File metadata and controls
147 lines (126 loc) · 5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
// SPDX-License-Identifier: GPL-2.0-or-later
import FileProvider
import Foundation
import RealmSwift
extension FilesDatabaseManager {
private func fullServerPathUrl(for metadata: any ItemMetadata) -> String {
if metadata.ocId == NSFileProviderItemIdentifier.rootContainer.rawValue {
metadata.serverUrl
} else {
metadata.serverUrl + "/" + metadata.fileName
}
}
public func childItems(directoryMetadata: SendableItemMetadata) -> [SendableItemMetadata] {
let directoryServerUrl = fullServerPathUrl(for: directoryMetadata)
return itemMetadatas
.where({ $0.serverUrl.starts(with: directoryServerUrl) })
.toUnmanagedResults()
}
public func childItemCount(directoryMetadata: SendableItemMetadata) -> Int {
let directoryServerUrl = fullServerPathUrl(for: directoryMetadata)
return itemMetadatas
.where({ $0.serverUrl.starts(with: directoryServerUrl) })
.count
}
public func parentDirectoryMetadataForItem(
_ itemMetadata: SendableItemMetadata
) -> SendableItemMetadata? {
self.itemMetadata(
account: itemMetadata.account, locatedAtRemoteUrl: itemMetadata.serverUrl
)
}
public func directoryMetadata(ocId: String) -> SendableItemMetadata? {
if let metadata = itemMetadatas.where({ $0.ocId == ocId && $0.directory }).first {
return SendableItemMetadata(value: metadata)
}
return nil
}
// Deletes all metadatas related to the info of the directory provided
public func deleteDirectoryAndSubdirectoriesMetadata(
ocId: String
) -> [SendableItemMetadata]? {
guard let directoryMetadata = itemMetadatas
.where({ $0.ocId == ocId && $0.directory })
.first
else {
logger.error("Could not find directory metadata for ocId. Not proceeding with deletion.", [.item: ocId])
return nil
}
let directoryMetadataCopy = SendableItemMetadata(value: directoryMetadata)
let directoryOcId = directoryMetadata.ocId
let directoryUrlPath = directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
let directoryAccount = directoryMetadata.account
let directoryEtag = directoryMetadata.etag
logger.debug("Deleting root directory metadata in recursive delete.", [.eTag: directoryEtag, .item: directoryMetadata.ocId, .url: directoryUrlPath])
let database = ncDatabase()
do {
try database.write { directoryMetadata.deleted = true }
} catch let error {
logger.error("Failure to delete root directory metadata in recursive delete.", [.error: error, .eTag: directoryEtag, .item: directoryOcId, .url: directoryUrlPath])
return nil
}
var deletedMetadatas: [SendableItemMetadata] = [directoryMetadataCopy]
let results = itemMetadatas.where {
$0.account == directoryAccount && $0.serverUrl.starts(with: directoryUrlPath)
}
for result in results {
let inactiveItemMetadata = SendableItemMetadata(value: result)
do {
try database.write { result.deleted = true }
deletedMetadatas.append(inactiveItemMetadata)
} catch let error {
logger.error("Failure to delete directory metadata child in recursive delete", [.error: error, .eTag: directoryEtag, .item: directoryOcId, .url: directoryUrlPath])
}
}
logger.debug("Completed deletions in directory recursive delete.", [.eTag: directoryEtag, .item: directoryOcId, .url: directoryUrlPath])
return deletedMetadatas
}
public func renameDirectoryAndPropagateToChildren(
ocId: String, newServerUrl: String, newFileName: String
) -> [SendableItemMetadata]? {
guard let directoryMetadata = itemMetadatas
.where({ $0.ocId == ocId && $0.directory })
.first
else {
logger.error("Could not find a directory with ocID \(ocId), cannot proceed with recursive renaming.", [.item: ocId])
return nil
}
let oldItemServerUrl = directoryMetadata.serverUrl
let oldItemFilename = directoryMetadata.fileName
let oldDirectoryServerUrl = oldItemServerUrl + "/" + oldItemFilename
let newDirectoryServerUrl = newServerUrl + "/" + newFileName
let childItemResults = itemMetadatas.where {
$0.account == directoryMetadata.account &&
$0.serverUrl.starts(with: oldDirectoryServerUrl)
}
renameItemMetadata(ocId: ocId, newServerUrl: newServerUrl, newFileName: newFileName)
logger.debug("Renamed root renaming directory from \"\(oldDirectoryServerUrl)\" to \"\(newDirectoryServerUrl)\".", [.item: ocId])
do {
let database = ncDatabase()
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.debug(
"""
Moved childItem at: \(oldServerUrl)
to: \(movedServerUrl)
""")
}
}
} catch {
logger.error("Could not rename directory metadata.", [.error: error, .item: ocId, .url: newServerUrl])
return nil
}
return itemMetadatas
.where {
$0.account == directoryMetadata.account &&
$0.serverUrl.starts(with: newDirectoryServerUrl)
}
.toUnmanagedResults()
}
}