From 2ef7b0013029cd2823ee2a7504010b2339b590e0 Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Wed, 2 Sep 2020 18:14:33 -0700 Subject: [PATCH] Improve db file handling --- .../ServiceLayer/AllIdentitiesService.swift | 7 ++++- .../Database/ContentDatabase.swift | 17 ++++++----- .../ServiceLayer/Database/DatabaseError.swift | 7 ----- .../Database/IdentityDatabase.swift | 13 +++------ .../Extensions/FileManager+Extensions.swift | 29 +++++++++++++++++++ 5 files changed, 48 insertions(+), 25 deletions(-) delete mode 100644 ServiceLayer/Sources/ServiceLayer/Database/DatabaseError.swift create mode 100644 ServiceLayer/Sources/ServiceLayer/Extensions/FileManager+Extensions.swift diff --git a/ServiceLayer/Sources/ServiceLayer/AllIdentitiesService.swift b/ServiceLayer/Sources/ServiceLayer/AllIdentitiesService.swift index 65221b2..d4f33ea 100644 --- a/ServiceLayer/Sources/ServiceLayer/AllIdentitiesService.swift +++ b/ServiceLayer/Sources/ServiceLayer/AllIdentitiesService.swift @@ -55,6 +55,7 @@ public extension AllIdentitiesService { networkClient.instanceURL = identity.url return identityDatabase.deleteIdentity(id: identity.id) + .collect() .tryMap { _ in DeletionEndpoint.oauthRevoke( token: try secretsService.item(.accessToken), @@ -62,7 +63,11 @@ public extension AllIdentitiesService { clientSecret: try secretsService.item(.clientSecret)) } .flatMap(networkClient.request) - .tryMap { _ in try secretsService.deleteAllItems() } + .collect() + .tryMap { _ in + try secretsService.deleteAllItems() + try ContentDatabase.delete(forIdentityID: identity.id) + } .ignoreOutput() .eraseToAnyPublisher() } diff --git a/ServiceLayer/Sources/ServiceLayer/Database/ContentDatabase.swift b/ServiceLayer/Sources/ServiceLayer/Database/ContentDatabase.swift index b8fe49b..63bac37 100644 --- a/ServiceLayer/Sources/ServiceLayer/Database/ContentDatabase.swift +++ b/ServiceLayer/Sources/ServiceLayer/Database/ContentDatabase.swift @@ -10,17 +10,10 @@ struct ContentDatabase { private let databaseQueue: DatabaseQueue init(identityID: UUID, environment: AppEnvironment) throws { - guard - let documentsDirectory = NSSearchPathForDirectoriesInDomains( - .documentDirectory, - .userDomainMask, true) - .first - else { throw DatabaseError.documentsDirectoryNotFound } - if environment.inMemoryContent { databaseQueue = DatabaseQueue() } else { - databaseQueue = try DatabaseQueue(path: "\(documentsDirectory)/\(identityID.uuidString).sqlite3") + databaseQueue = try DatabaseQueue(path: try Self.fileURL(identityID: identityID).path) } try Self.migrate(databaseQueue) @@ -28,6 +21,10 @@ struct ContentDatabase { } extension ContentDatabase { + static func delete(forIdentityID identityID: UUID) throws { + try FileManager.default.removeItem(at: try fileURL(identityID: identityID)) + } + func insert(status: Status) -> AnyPublisher { databaseQueue.writePublisher(updates: status.save) .ignoreOutput() @@ -179,6 +176,10 @@ extension ContentDatabase { } private extension ContentDatabase { + static func fileURL(identityID: UUID) throws -> URL { + try FileManager.default.databaseDirectoryURL().appendingPathComponent(identityID.uuidString + ".sqlite") + } + // swiftlint:disable function_body_length static func migrate(_ writer: DatabaseWriter) throws { var migrator = DatabaseMigrator() diff --git a/ServiceLayer/Sources/ServiceLayer/Database/DatabaseError.swift b/ServiceLayer/Sources/ServiceLayer/Database/DatabaseError.swift deleted file mode 100644 index 889bca1..0000000 --- a/ServiceLayer/Sources/ServiceLayer/Database/DatabaseError.swift +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright © 2020 Metabolist. All rights reserved. - -import Foundation - -public enum DatabaseError: Error { - case documentsDirectoryNotFound -} diff --git a/ServiceLayer/Sources/ServiceLayer/Database/IdentityDatabase.swift b/ServiceLayer/Sources/ServiceLayer/Database/IdentityDatabase.swift index 8648ea6..d1f5ff4 100644 --- a/ServiceLayer/Sources/ServiceLayer/Database/IdentityDatabase.swift +++ b/ServiceLayer/Sources/ServiceLayer/Database/IdentityDatabase.swift @@ -13,17 +13,12 @@ struct IdentityDatabase { private let databaseQueue: DatabaseQueue init(environment: AppEnvironment) throws { - guard - let documentsDirectory = NSSearchPathForDirectoriesInDomains( - .documentDirectory, - .userDomainMask, true) - .first - else { throw DatabaseError.documentsDirectoryNotFound } - if environment.inMemoryContent { databaseQueue = DatabaseQueue() } else { - databaseQueue = try DatabaseQueue(path: "\(documentsDirectory)/IdentityDatabase.sqlite3") + let databaseURL = try FileManager.default.databaseDirectoryURL().appendingPathComponent("Identities.sqlite") + + databaseQueue = try DatabaseQueue(path: databaseURL.path) } try Self.migrate(databaseQueue) @@ -51,7 +46,7 @@ extension IdentityDatabase { } func deleteIdentity(id: UUID) -> AnyPublisher { - return databaseQueue.writePublisher(updates: StoredIdentity.filter(Column("id") == id).deleteAll) + databaseQueue.writePublisher(updates: StoredIdentity.filter(Column("id") == id).deleteAll) .ignoreOutput() .eraseToAnyPublisher() } diff --git a/ServiceLayer/Sources/ServiceLayer/Extensions/FileManager+Extensions.swift b/ServiceLayer/Sources/ServiceLayer/Extensions/FileManager+Extensions.swift new file mode 100644 index 0000000..d7168ff --- /dev/null +++ b/ServiceLayer/Sources/ServiceLayer/Extensions/FileManager+Extensions.swift @@ -0,0 +1,29 @@ +// +// File.swift +// +// +// Created by Justin Mazzocchi on 9/2/20. +// + +import Foundation + +extension FileManager { + func databaseDirectoryURL() throws -> URL { + let databaseDirectoryURL = try url(for: .applicationSupportDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: true) + .appendingPathComponent("Database") + var isDirectory: ObjCBool = false + + if !fileExists(atPath: databaseDirectoryURL.path, isDirectory: &isDirectory) { + try createDirectory(at: databaseDirectoryURL, + withIntermediateDirectories: false, + attributes: [.protectionKey: FileProtectionType.complete]) + } else if !isDirectory.boolValue { + throw NSError(domain: NSCocoaErrorDomain, code: NSFileWriteFileExistsError, userInfo: nil) + } + + return databaseDirectoryURL + } +}