Path: blob/main/SignalServiceKit/Contacts/NicknameRecord/NicknameManager.swift
1 views
//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import GRDB
public protocol NicknameManager {
func fetchNickname(for recipient: SignalRecipient, tx: DBReadTransaction) -> NicknameRecord?
func createOrUpdate(
nicknameRecord: NicknameRecord,
updateStorageServiceFor recipientUniqueId: RecipientUniqueId?,
tx: DBWriteTransaction,
)
func deleteNickname(
recipientRowID: Int64,
updateStorageServiceFor recipientUniqueId: RecipientUniqueId?,
tx: DBWriteTransaction,
)
}
public struct NicknameManagerImpl: NicknameManager {
private let nicknameRecordStore: any NicknameRecordStore
private let searchableNameIndexer: any SearchableNameIndexer
private let storageServiceManager: any StorageServiceManager
public init(
nicknameRecordStore: any NicknameRecordStore,
searchableNameIndexer: any SearchableNameIndexer,
storageServiceManager: any StorageServiceManager,
) {
self.nicknameRecordStore = nicknameRecordStore
self.searchableNameIndexer = searchableNameIndexer
self.storageServiceManager = storageServiceManager
}
private func notifyContactChanges(tx: DBWriteTransaction) {
tx.addSyncCompletion {
NotificationCenter.default.postOnMainThread(name: .OWSContactsManagerSignalAccountsDidChange, object: nil)
}
}
// MARK: Read
public func fetchNickname(
for recipient: SignalRecipient,
tx: DBReadTransaction,
) -> NicknameRecord? {
return nicknameRecordStore.fetch(recipientRowID: recipient.id, tx: tx)
}
// MARK: Write
public func createOrUpdate(
nicknameRecord: NicknameRecord,
updateStorageServiceFor recipientUniqueId: RecipientUniqueId?,
tx: DBWriteTransaction,
) {
if
self.nicknameRecordStore.nicknameExists(
recipientRowID: nicknameRecord.recipientRowID,
tx: tx,
)
{
self.update(nicknameRecord, tx: tx)
} else {
self.insert(nicknameRecord, tx: tx)
}
if let recipientUniqueId {
self.storageServiceManager.recordPendingUpdates(updatedRecipientUniqueIds: [recipientUniqueId])
}
}
private func insert(_ nicknameRecord: NicknameRecord, tx: DBWriteTransaction) {
self.nicknameRecordStore.insert(nicknameRecord, tx: tx)
self.searchableNameIndexer.insert(nicknameRecord, tx: tx)
self.notifyContactChanges(tx: tx)
}
private func update(_ nicknameRecord: NicknameRecord, tx: DBWriteTransaction) {
self.nicknameRecordStore.update(nicknameRecord, tx: tx)
self.searchableNameIndexer.update(nicknameRecord, tx: tx)
self.notifyContactChanges(tx: tx)
}
public func deleteNickname(
recipientRowID: Int64,
updateStorageServiceFor recipientUniqueId: RecipientUniqueId?,
tx: DBWriteTransaction,
) {
guard
let nicknameRecord = self.nicknameRecordStore.fetch(
recipientRowID: recipientRowID,
tx: tx,
) else { return }
self.delete(nicknameRecord, tx: tx)
if let recipientUniqueId {
self.storageServiceManager.recordPendingUpdates(updatedRecipientUniqueIds: [recipientUniqueId])
}
}
private func delete(_ nicknameRecord: NicknameRecord, tx: DBWriteTransaction) {
self.searchableNameIndexer.delete(nicknameRecord, tx: tx)
self.nicknameRecordStore.delete(nicknameRecord, tx: tx)
self.notifyContactChanges(tx: tx)
}
}