Signal-iOS/SignalServiceKit/Contacts/Threads/ThreadRemover.swift
2024-03-27 12:22:52 -05:00

154 lines
6.0 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public protocol ThreadRemover {
func remove(_ thread: TSContactThread, tx: DBWriteTransaction)
func remove(_ thread: TSPrivateStoryThread, tx: DBWriteTransaction)
}
class ThreadRemoverImpl: ThreadRemover {
private let chatColorSettingStore: ChatColorSettingStore
private let databaseStorage: Shims.DatabaseStorage
private let disappearingMessagesConfigurationStore: DisappearingMessagesConfigurationStore
private let interactionRemover: Shims.InteractionRemover
private let sdsThreadRemover: Shims.SDSThreadRemover
private let threadAssociatedDataStore: ThreadAssociatedDataStore
private let threadReadCache: Shims.ThreadReadCache
private let threadReplyInfoStore: ThreadReplyInfoStore
private let threadStore: ThreadStore
private let wallpaperStore: WallpaperStore
init(
chatColorSettingStore: ChatColorSettingStore,
databaseStorage: Shims.DatabaseStorage,
disappearingMessagesConfigurationStore: DisappearingMessagesConfigurationStore,
interactionRemover: Shims.InteractionRemover,
sdsThreadRemover: Shims.SDSThreadRemover,
threadAssociatedDataStore: ThreadAssociatedDataStore,
threadReadCache: Shims.ThreadReadCache,
threadReplyInfoStore: ThreadReplyInfoStore,
threadStore: ThreadStore,
wallpaperStore: WallpaperStore
) {
self.chatColorSettingStore = chatColorSettingStore
self.databaseStorage = databaseStorage
self.disappearingMessagesConfigurationStore = disappearingMessagesConfigurationStore
self.interactionRemover = interactionRemover
self.sdsThreadRemover = sdsThreadRemover
self.threadAssociatedDataStore = threadAssociatedDataStore
self.threadReadCache = threadReadCache
self.threadReplyInfoStore = threadReplyInfoStore
self.threadStore = threadStore
self.wallpaperStore = wallpaperStore
}
func remove(_ thread: TSContactThread, tx: DBWriteTransaction) { removeAny(thread, tx: tx) }
func remove(_ thread: TSPrivateStoryThread, tx: DBWriteTransaction) { removeAny(thread, tx: tx) }
private func removeAny(_ thread: TSThread, tx: DBWriteTransaction) {
chatColorSettingStore.setRawSetting(nil, for: thread.uniqueId, tx: tx)
databaseStorage.updateIdMapping(thread: thread, tx: tx)
interactionRemover.removeAllInteractions(in: thread, tx: tx)
disappearingMessagesConfigurationStore.remove(for: thread, tx: tx)
threadAssociatedDataStore.remove(for: thread.uniqueId, tx: tx)
threadReplyInfoStore.remove(for: thread.uniqueId, tx: tx)
threadStore.removeThread(thread, tx: tx)
threadReadCache.didRemove(thread: thread, tx: tx)
try? wallpaperStore.reset(for: thread, tx: tx)
sdsThreadRemover.didRemove(thread: thread, tx: tx)
}
}
// MARK: -
extension ThreadRemoverImpl {
enum Shims {
typealias InteractionRemover = _ThreadRemoverImpl_InteractionRemoverShim
typealias ThreadReadCache = _ThreadRemoverImpl_ThreadReadCacheShim
typealias DatabaseStorage = _ThreadRemoverImpl_DatabaseStorageShim
typealias SDSThreadRemover = _ThreadRemoverImpl_SDSThreadRemoverShim
}
enum Wrappers {
typealias InteractionRemover = _ThreadRemoverImpl_InteractionRemoverWrapper
typealias ThreadReadCache = _ThreadRemoverImpl_ThreadReadCacheWrapper
typealias DatabaseStorage = _ThreadRemoverImpl_DatabaseStorageWrapper
typealias SDSThreadRemover = _ThreadRemoverImpl_SDSThreadRemoverWrapper
}
}
protocol _ThreadRemoverImpl_InteractionRemoverShim {
func removeAllInteractions(in thread: TSThread, tx: DBWriteTransaction)
}
class _ThreadRemoverImpl_InteractionRemoverWrapper: _ThreadRemoverImpl_InteractionRemoverShim {
func removeAllInteractions(in thread: TSThread, tx: DBWriteTransaction) {
thread.removeAllThreadInteractions(transaction: SDSDB.shimOnlyBridge(tx))
}
}
protocol _ThreadRemoverImpl_ThreadReadCacheShim {
func didRemove(thread: TSThread, tx: DBWriteTransaction)
}
class _ThreadRemoverImpl_ThreadReadCacheWrapper: _ThreadRemoverImpl_ThreadReadCacheShim {
private let threadReadCache: ThreadReadCache
init(_ threadReadCache: ThreadReadCache) {
self.threadReadCache = threadReadCache
}
func didRemove(thread: TSThread, tx: DBWriteTransaction) {
threadReadCache.didRemove(thread: thread, transaction: SDSDB.shimOnlyBridge(tx))
}
}
protocol _ThreadRemoverImpl_DatabaseStorageShim {
func updateIdMapping(thread: TSThread, tx: DBWriteTransaction)
}
class _ThreadRemoverImpl_DatabaseStorageWrapper: _ThreadRemoverImpl_DatabaseStorageShim {
private let databaseStorage: SDSDatabaseStorage
init(_ databaseStorage: SDSDatabaseStorage) {
self.databaseStorage = databaseStorage
}
func updateIdMapping(thread: TSThread, tx: DBWriteTransaction) {
databaseStorage.updateIdMapping(thread: thread, transaction: SDSDB.shimOnlyBridge(tx))
}
}
protocol _ThreadRemoverImpl_SDSThreadRemoverShim {
func didRemove(thread: TSThread, tx: DBWriteTransaction)
}
class _ThreadRemoverImpl_SDSThreadRemoverWrapper: _ThreadRemoverImpl_SDSThreadRemoverShim {
func didRemove(thread: TSThread, tx: DBWriteTransaction) {
thread.clearLastVisibleInteraction(transaction: SDSDB.shimOnlyBridge(tx))
}
}
// MARK: - Unit Tests
#if TESTABLE_BUILD
class ThreadRemover_MockInteractionRemover: ThreadRemoverImpl.Shims.InteractionRemover {
func removeAllInteractions(in thread: TSThread, tx: DBWriteTransaction) {}
}
class ThreadRemover_MockThreadReadCache: ThreadRemoverImpl.Shims.ThreadReadCache {
func didRemove(thread: TSThread, tx: DBWriteTransaction) {}
}
class ThreadRemover_MockDatabaseStorage: ThreadRemoverImpl.Shims.DatabaseStorage {
func updateIdMapping(thread: TSThread, tx: DBWriteTransaction) {}
}
class ThreadRemover_MockSDSThreadRemover: ThreadRemoverImpl.Shims.SDSThreadRemover {
func didRemove(thread: TSThread, tx: DBWriteTransaction) {}
}
#endif