mastodon-ios/Mastodon/Persistence/Persistence+SearchHistory.s...

117 lines
3.2 KiB
Swift

//
// Persistence+SearchHistory.swift
// Mastodon
//
// Created by MainasuK on 2022-1-20.
//
import CoreData
import CoreDataStack
import Foundation
import MastodonSDK
import os.log
extension Persistence.SearchHistory {
public struct PersistContext {
public let entity: Entity
public let me: MastodonUser
public let now: Date
public let log = OSLog.api
public init(
entity: Entity,
me: MastodonUser,
now: Date
) {
self.entity = entity
self.me = me
self.now = now
}
public enum Entity: Hashable {
case user(MastodonUser)
case hashtag(Tag)
}
}
public struct PersistResult {
public let searchHistory: SearchHistory
public let isNewInsertion: Bool
public init(
searchHistory: SearchHistory,
isNewInsertion: Bool
) {
self.searchHistory = searchHistory
self.isNewInsertion = isNewInsertion
}
}
public static func createOrMerge(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> PersistResult {
if let old = fetch(in: managedObjectContext, context: context) {
update(searchHistory: old, context: context)
return PersistResult(searchHistory: old, isNewInsertion: false)
} else {
let object = create(in: managedObjectContext, context: context)
return PersistResult(searchHistory: object, isNewInsertion: true)
}
}
}
extension Persistence.SearchHistory {
public static func fetch(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> SearchHistory? {
switch context.entity {
case .user(let user):
return user.findSearchHistory(for: context.me)
case .hashtag(let hashtag):
return hashtag.findSearchHistory(for: context.me)
}
}
@discardableResult
public static func create(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> SearchHistory {
let property = SearchHistory.Property(
identifier: UUID(),
domain: context.me.domain,
userID: context.me.id,
createAt: context.now,
updatedAt: context.now
)
let relationship: SearchHistory.Relationship = {
switch context.entity {
case .user(let user):
return SearchHistory.Relationship(account: user, hashtag: nil, status: nil)
case .hashtag(let hashtag):
return SearchHistory.Relationship(account: nil, hashtag: hashtag, status: nil)
}
}()
let searchHistory = SearchHistory.insert(
into: managedObjectContext,
property: property,
relationship: relationship
)
update(searchHistory: searchHistory, context: context)
return searchHistory
}
private static func update(
searchHistory: SearchHistory,
context: PersistContext
) {
searchHistory.update(updatedAt: context.now)
}
}