Skip to content

Commit

Permalink
fix: Use uid instead of id to differentiate files
Browse files Browse the repository at this point in the history
Signed-off-by: Philippe Weidmann <[email protected]>
  • Loading branch information
PhilippeWeidmann committed Jan 29, 2024
1 parent 135665c commit 469cc3d
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class InMemoryFileListViewModel: FileListViewModel {
func removeFiles(_ files: [ProxyFile]) {
try? realm.write {
for file in files {
if let file = realm.object(ofType: File.self, forPrimaryKey: file.id), !file.isInvalidated {
if let file = realm.object(ofType: File.self, forPrimaryKey: file.uid), !file.isInvalidated {
realm.delete(file)
}
}
Expand Down
4 changes: 2 additions & 2 deletions kDrive/UI/Controller/Files/RootMenuViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ class RootMenuViewController: CustomLargeTitleCollectionViewController, SelectSw

configureDataSource()

let rootChildren = driveFileManager.getRealm()
.object(ofType: File.self, forPrimaryKey: DriveFileManager.constants.rootID)?.children
let rootFileUid = File.uid(driveId: driveFileManager.drive.id, fileId: DriveFileManager.constants.rootID)
let rootChildren = driveFileManager.getRealm().object(ofType: File.self, forPrimaryKey: rootFileUid)?.children
rootChildrenObservationToken = rootChildren?.observe { [weak self] changes in
guard let self else { return }
switch changes {
Expand Down
2 changes: 1 addition & 1 deletion kDrive/UI/Controller/Menu/Trash/TrashListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ class MultipleSelectionTrashViewModel: MultipleSelectionFileListViewModel {
guard let realm = try? Realm(configuration: realmConfiguration) else { return }
try? realm.write {
for file in deletedFiles {
if let file = realm.object(ofType: File.self, forPrimaryKey: file.id), !file.isInvalidated {
if let file = realm.object(ofType: File.self, forPrimaryKey: file.uid), !file.isInvalidated {
realm.delete(file)
}
}
Expand Down
6 changes: 5 additions & 1 deletion kDriveCore/Data/Api/Endpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ public protocol AbstractFile {
}

public struct ProxyFile: AbstractFile, Sendable {
public var uid: String {
File.uid(driveId: driveId, fileId: id)
}

public var driveId: Int
public var id: Int
public var isRoot: Bool {
Expand All @@ -130,7 +134,7 @@ public struct ProxyFile: AbstractFile, Sendable {
}

func resolve(using realm: Realm) throws -> File {
guard let file = realm.object(ofType: File.self, forPrimaryKey: id), !file.isInvalidated else {
guard let file = realm.object(ofType: File.self, forPrimaryKey: uid), !file.isInvalidated else {
throw DriveError.errorWithUserInfo(.fileNotFound, info: [.fileId: ErrorUserInfo(intValue: id)])
}
return file
Expand Down
10 changes: 6 additions & 4 deletions kDriveCore/Data/Cache/DriveFileManager+Listing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,22 @@ public extension DriveFileManager {
!alreadyHandledActionIds.contains(fileAction.fileId) else { continue }
alreadyHandledActionIds.insert(fileAction.fileId)

let fileUid = File.uid(driveId: directory.driveId, fileId: fileAction.fileId)

switch fileAction.action {
case .fileDelete, .fileTrash:
removeFileInDatabase(fileId: fileAction.fileId, cascade: true, withTransaction: false, using: realm)
removeFileInDatabase(fileUid: fileUid, cascade: true, withTransaction: false, using: realm)

case .fileMoveOut:
guard let movedOutFile: File = realm.getObject(id: fileAction.fileId),
guard let movedOutFile: File = realm.getObject(id: fileUid),
let oldParent = movedOutFile.parent else { continue }

oldParent.children.remove(movedOutFile)
case .fileMoveIn, .fileRestore, .fileCreate:
keepCacheAttributesForFile(newFile: actionFile, keepProperties: [.standard, .extras], using: realm)
realm.add(actionFile, update: .modified)

if let existingFile: File = realm.getObject(id: fileAction.fileId),
if let existingFile: File = realm.getObject(id: fileUid),
let oldParent = existingFile.parent {
oldParent.children.remove(existingFile)
}
Expand All @@ -100,7 +102,7 @@ public extension DriveFileManager {
.fileColorUpdate, .fileColorDelete,
.fileCategorize, .fileUncategorize:

if let oldFile: File = realm.getObject(id: fileAction.fileId),
if let oldFile: File = realm.getObject(id: fileUid),
oldFile.name != actionFile.name {
try? renameCachedFile(updatedFile: actionFile, oldFile: oldFile)
}
Expand Down
47 changes: 24 additions & 23 deletions kDriveCore/Data/Cache/DriveFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ public final class DriveFileManager {
let realm = realm ?? getRealm()
realm.refresh()

guard let file = realm.object(ofType: File.self, forPrimaryKey: id), !file.isInvalidated else {
let uid = File.uid(driveId: drive.id, fileId: id)
guard let file = realm.object(ofType: File.self, forPrimaryKey: uid), !file.isInvalidated else {
return nil
}
return freeze ? file.freeze() : file
Expand Down Expand Up @@ -736,7 +737,7 @@ public final class DriveFileManager {
token?.cancel()
if error != nil && error != .taskRescheduled {
// Mark it as not available offline
self.updateFileProperty(fileId: safeFile.id) { file in
self.updateFileProperty(fileUid: safeFile.uid) { file in
file.isAvailableOffline = false
}
}
Expand All @@ -762,14 +763,14 @@ public final class DriveFileManager {
}

public func setFileShareLink(file: ProxyFile, shareLink: ShareLink?) {
updateFileProperty(fileId: file.id) { file in
updateFileProperty(fileUid: file.uid) { file in
file.sharelink = shareLink
file.capabilities.canBecomeSharelink = shareLink == nil
}
}

public func setFileDropBox(file: ProxyFile, dropBox: DropBox?) {
updateFileProperty(fileId: file.id) { file in
updateFileProperty(fileUid: file.uid) { file in
file.dropbox = dropBox
file.capabilities.canBecomeDropbox = dropBox == nil
}
Expand Down Expand Up @@ -882,7 +883,7 @@ public final class DriveFileManager {
let timestamp = try TimeInterval(timestamp ?? file.resolve(using: realm).responseAt)
var page = 1
var moreComing = true
var pagedActions = [Int: FileActivityType]()
var pagedActions = [String: FileActivityType]()
var pagedActivities = ActivitiesResult()
var responseAt = 0
while moreComing {
Expand Down Expand Up @@ -916,7 +917,7 @@ public final class DriveFileManager {
// swiftlint:disable:next cyclomatic_complexity
private func apply(activities: [FileActivity],
to file: File,
pagedActions: inout [Int: FileActivityType],
pagedActions: inout [String: FileActivityType],
timestamp: Int,
using realm: Realm? = nil) -> ActivitiesResult {
var insertedFiles = [File]()
Expand All @@ -926,14 +927,14 @@ public final class DriveFileManager {
realm.refresh()
realm.beginWrite()
for activity in activities {
let fileId = activity.fileId
let fileId = File.uid(driveId: file.driveId, fileId: activity.fileId)
if pagedActions[fileId] == nil {
switch activity.action {
case .fileDelete, .fileTrash:
if let file = realm.object(ofType: File.self, forPrimaryKey: fileId), !file.isInvalidated {
deletedFiles.append(file.freeze())
}
removeFileInDatabase(fileId: fileId, cascade: true, withTransaction: false, using: realm)
removeFileInDatabase(fileUid: fileId, cascade: true, withTransaction: false, using: realm)
if let file = activity.file {
deletedFiles.append(file)
}
Expand Down Expand Up @@ -980,7 +981,7 @@ public final class DriveFileManager {
.fileColorDelete:
if let newFile = activity.file {
if newFile.isTrashed {
removeFileInDatabase(fileId: fileId, cascade: true, withTransaction: false, using: realm)
removeFileInDatabase(fileUid: fileId, cascade: true, withTransaction: false, using: realm)
deletedFiles.append(newFile)
pagedActions[fileId] = .fileDelete
} else {
Expand Down Expand Up @@ -1080,7 +1081,7 @@ public final class DriveFileManager {
let categoryId = category.id
let response = try await apiFetcher.add(category: category, to: file)
if response.result {
updateFileProperty(fileId: file.id) { file in
updateFileProperty(fileUid: file.uid) { file in
let newCategory = FileCategory(categoryId: categoryId, userId: self.drive.userId)
file.categories.append(newCategory)
}
Expand All @@ -1091,7 +1092,7 @@ public final class DriveFileManager {
let categoryId = category.id
let response = try await apiFetcher.add(drive: drive, category: category, to: files)
for fileResponse in response where fileResponse.result {
updateFileProperty(fileId: fileResponse.id) { file in
updateFileProperty(fileUid: File.uid(driveId: drive.id, fileId: fileResponse.id)) { file in
let newCategory = FileCategory(categoryId: categoryId, userId: self.drive.userId)
file.categories.append(newCategory)
}
Expand All @@ -1102,7 +1103,7 @@ public final class DriveFileManager {
let categoryId = category.id
let response = try await apiFetcher.remove(category: category, from: file)
if response {
updateFileProperty(fileId: file.id) { file in
updateFileProperty(fileUid: file.uid) { file in
if let index = file.categories.firstIndex(where: { $0.categoryId == categoryId }) {
file.categories.remove(at: index)
}
Expand All @@ -1114,7 +1115,7 @@ public final class DriveFileManager {
let categoryId = category.id
let response = try await apiFetcher.remove(drive: drive, category: category, from: files)
for fileResponse in response where fileResponse.result {
updateFileProperty(fileId: fileResponse.id) { file in
updateFileProperty(fileUid: File.uid(driveId: drive.id, fileId: fileResponse.id)) { file in
if let index = file.categories.firstIndex(where: { $0.categoryId == categoryId }) {
file.categories.remove(at: index)
}
Expand Down Expand Up @@ -1185,7 +1186,7 @@ public final class DriveFileManager {
response = try await apiFetcher.unfavorite(file: file)
}
if response {
updateFileProperty(fileId: file.id) { file in
updateFileProperty(fileUid: file.uid) { file in
file.isFavorite = favorite
}
}
Expand All @@ -1196,7 +1197,7 @@ public final class DriveFileManager {
backgroundQueue.async { [self] in
let localRealm = getRealm()
let savedFile = try? file.resolve(using: localRealm).freeze()
removeFileInDatabase(fileId: file.id, cascade: true, withTransaction: true, using: localRealm)
removeFileInDatabase(fileUid: file.uid, cascade: true, withTransaction: true, using: localRealm)
if let file = savedFile {
savedFile?.signalChanges(userId: drive.userId)
notifyObserversWith(file: file)
Expand Down Expand Up @@ -1414,18 +1415,18 @@ public final class DriveFileManager {
return Array(children.freeze())
}

func removeFileInDatabase(fileId: Int, cascade: Bool, withTransaction: Bool, using realm: Realm? = nil) {
func removeFileInDatabase(fileUid: String, cascade: Bool, withTransaction: Bool, using realm: Realm? = nil) {
let realm = realm ?? getRealm()
realm.refresh()

if let file = realm.object(ofType: File.self, forPrimaryKey: fileId), !file.isInvalidated {
if let file = realm.object(ofType: File.self, forPrimaryKey: fileUid), !file.isInvalidated {
if fileManager.fileExists(atPath: file.localContainerUrl.path) {
try? fileManager.removeItem(at: file.localContainerUrl) // Check that it was correctly removed?
}

if cascade {
for child in file.children.freeze() where !child.isInvalidated {
removeFileInDatabase(fileId: child.id, cascade: cascade, withTransaction: withTransaction, using: realm)
removeFileInDatabase(fileUid: child.uid, cascade: cascade, withTransaction: withTransaction, using: realm)
}
}
if withTransaction {
Expand Down Expand Up @@ -1460,11 +1461,11 @@ public final class DriveFileManager {
}
}

private func updateFileProperty(fileId: Int, using realm: Realm? = nil, _ block: (File) -> Void) {
private func updateFileProperty(fileUid: String, using realm: Realm? = nil, _ block: (File) -> Void) {
let realm = realm ?? getRealm()
realm.refresh()

if let file = realm.object(ofType: File.self, forPrimaryKey: fileId), !file.isInvalidated {
if let file = realm.object(ofType: File.self, forPrimaryKey: fileUid), !file.isInvalidated {
try? realm.write {
block(file)
}
Expand Down Expand Up @@ -1523,7 +1524,7 @@ public final class DriveFileManager {
let realm = realm ?? getRealm()
realm.refresh()

guard let savedChild = realm.object(ofType: File.self, forPrimaryKey: newFile.id),
guard let savedChild = realm.object(ofType: File.self, forPrimaryKey: newFile.uid),
!savedChild.isInvalidated else { return }
newFile.isAvailableOffline = savedChild.isAvailableOffline
newFile.versionCode = savedChild.versionCode
Expand Down Expand Up @@ -1577,10 +1578,10 @@ public final class DriveFileManager {
}

public func updateColor(directory: File, color: String) async throws -> Bool {
let fileId = directory.id
let fileUid = directory.uid
let result = try await apiFetcher.updateColor(directory: directory.proxify(), color: color)
if result {
updateFileProperty(fileId: fileId) { file in
updateFileProperty(fileUid: fileUid) { file in
file.color = color
}
}
Expand Down
14 changes: 11 additions & 3 deletions kDriveCore/Data/Models/File.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ public final class File: Object, Codable {

@LazyInjectService var accountManager: AccountManageable

@Persisted(primaryKey: true) public var id = UUID().uuidString.hashValue
@Persisted(primaryKey: true) public var uid = UUID().uuidString
@Persisted public var id: Int
@Persisted public var parentId: Int
/// Drive identifier
@Persisted public var driveId: Int
Expand Down Expand Up @@ -730,13 +731,20 @@ public final class File: Object, Codable {
return ProxyFile(driveId: driveId, id: id)
}

public static func uid(driveId: Int, fileId: Int) -> String {
"\(fileId)\(driveId)"
}

public convenience init(from decoder: Decoder) throws {
self.init()

let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
let id = try container.decode(Int.self, forKey: .id)
self.id = id
parentId = try container.decode(Int.self, forKey: .parentId)
driveId = try container.decode(Int.self, forKey: .driveId)
let driveId = try container.decode(Int.self, forKey: .driveId)
self.driveId = driveId
uid = File.uid(driveId: driveId, fileId: id)
let decodedName = try container.decode(String.self, forKey: .name)
name = decodedName
sortedName = try container.decodeIfPresent(String.self, forKey: .sortedName) ?? decodedName
Expand Down

0 comments on commit 469cc3d

Please sign in to comment.