// // MastodonCachePersistentStore.swift // Tusker // // Created by Shadowfacts on 4/11/20. // Copyright © 2020 Shadowfacts. All rights reserved. // import Foundation import CoreData import Pachyderm class MastodonCachePersistentStore: NSPersistentContainer { private(set) lazy var backgroundContext = newBackgroundContext() init(for controller: MastodonController) { let url = Bundle.main.url(forResource: "Tusker", withExtension: "momd")! let model = NSManagedObjectModel(contentsOf: url)! super.init(name: "\(controller.accountInfo!.id)_cache", managedObjectModel: model) loadPersistentStores { (description, error) in if let error = error { fatalError("Unable to load persistent store: \(error)") } } } func status(for id: String, in context: NSManagedObjectContext? = nil) -> StatusMO? { let context = context ?? viewContext let request: NSFetchRequest = StatusMO.fetchRequest() request.predicate = NSPredicate(format: "id = %@", id) request.fetchLimit = 1 if let result = try? context.fetch(request), let status = result.first { return status } else { return nil } } private func upsert(status: Status) { if let statusMO = self.status(for: status.id, in: self.backgroundContext) { statusMO.updateFrom(apiStatus: status, container: self) } else { _ = StatusMO(apiStatus: status, container: self, context: self.backgroundContext) } } func addOrUpdate(status: Status, save: Bool = true) { backgroundContext.perform { self.upsert(status: status) if save, self.backgroundContext.hasChanges { try! self.backgroundContext.save() } } } func addAll(statuses: [Status], completion: (() -> Void)? = nil) { backgroundContext.perform { statuses.forEach(self.upsert(status:)) if self.backgroundContext.hasChanges { try! self.backgroundContext.save() } completion?() } } func account(for id: String, in context: NSManagedObjectContext? = nil) -> AccountMO? { let context = context ?? viewContext let request: NSFetchRequest = AccountMO.fetchRequest() request.predicate = NSPredicate(format: "id = %@", id) request.fetchLimit = 1 if let result = try? context.fetch(request), let account = result.first { return account } else { return nil } } private func upsert(account: Account) { if let accountMO = self.account(for: account.id, in: self.backgroundContext) { accountMO.updateFrom(apiAccount: account, container: self) } else { _ = AccountMO(apiAccount: account, container: self, context: self.backgroundContext) } } func addOrUpdate(account: Account, save: Bool = true) { backgroundContext.perform { self.upsert(account: account) if save, self.backgroundContext.hasChanges { try! self.backgroundContext.save() } } } func addAll(accounts: [Account], completion: (() -> Void)? = nil) { backgroundContext.perform { accounts.forEach(self.upsert(account:)) if self.backgroundContext.hasChanges { try! self.backgroundContext.save() } completion?() } } }