separate indexable query for groups
This commit is contained in:
parent
e8ef310cd7
commit
eb07cda055
@ -44,7 +44,7 @@ public class ThreadViewModel: NSObject {
|
||||
|
||||
self.unreadCount = InteractionFinder(threadUniqueId: thread.uniqueId).unreadCount(transaction: transaction)
|
||||
self.hasUnreadMessages = unreadCount > 0
|
||||
self.hasPendingMessageRequest = AnyThreadFinder.hasPendingMessageRequest(thread: thread, transaction: transaction)
|
||||
self.hasPendingMessageRequest = GRDBThreadFinder.hasPendingMessageRequest(thread: thread, transaction: transaction.unwrapGrdbRead)
|
||||
}
|
||||
|
||||
@objc
|
||||
|
||||
@ -406,7 +406,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__block BOOL hasPendingMessageRequest;
|
||||
[self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) {
|
||||
hasPendingMessageRequest = [AnyThreadFinder hasPendingMessageRequestWithThread:thread transaction:transaction];
|
||||
hasPendingMessageRequest = [GRDBThreadFinder hasPendingMessageRequestWithThread:thread
|
||||
transaction:transaction.unwrapGrdbRead];
|
||||
}];
|
||||
|
||||
// If we're creating this thread or we have a pending message request,
|
||||
@ -424,7 +425,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
{
|
||||
OWSAssertDebug(thread);
|
||||
|
||||
BOOL hasPendingMessageRequest = [AnyThreadFinder hasPendingMessageRequestWithThread:thread transaction:transaction];
|
||||
BOOL hasPendingMessageRequest = [GRDBThreadFinder hasPendingMessageRequestWithThread:thread
|
||||
transaction:transaction.unwrapGrdbWrite];
|
||||
|
||||
// If we're creating this thread or we have a pending message request,
|
||||
// any action we trigger should share our profile.
|
||||
|
||||
@ -347,11 +347,6 @@ public class InteractionFinder: NSObject, InteractionFinderAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func possiblyHasIncomingMessages(transaction: GRDBReadTransaction) -> Bool {
|
||||
return grdbAdapter.possiblyHasIncomingMessages(transaction: transaction)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
@objc
|
||||
public func enumerateUnstartedExpiringMessages(transaction: SDSAnyReadTransaction, block: @escaping (TSMessage, UnsafeMutablePointer<ObjCBool>) -> Void) {
|
||||
@ -1040,6 +1035,21 @@ struct GRDBInteractionFinderAdapter: InteractionFinderAdapter {
|
||||
return try! Bool.fetchOne(transaction.database, sql: sql, arguments: arguments) ?? false
|
||||
}
|
||||
|
||||
func hasGroupUpdateInfoMessage(transaction: GRDBReadTransaction) -> Bool {
|
||||
let sql = """
|
||||
SELECT EXISTS(
|
||||
SELECT 1
|
||||
FROM \(InteractionRecord.databaseTableName)
|
||||
WHERE \(interactionColumn: .threadUniqueId) = ?
|
||||
AND \(interactionColumn: .recordType) = \(SDSRecordType.infoMessage.rawValue)
|
||||
AND \(interactionColumn: .messageType) = \(TSInfoMessageType.typeGroupUpdate.rawValue)
|
||||
LIMIT 1
|
||||
)
|
||||
"""
|
||||
let arguments: StatementArguments = [threadUniqueId]
|
||||
return try! Bool.fetchOne(transaction.database, sql: sql, arguments: arguments)!
|
||||
}
|
||||
|
||||
func possiblyHasIncomingMessages(transaction: GRDBReadTransaction) -> Bool {
|
||||
// All of these message types could have been triggered by anyone in
|
||||
// the conversation. So, if one of them exists we have to assume the conversation
|
||||
@ -1067,15 +1077,11 @@ struct GRDBInteractionFinderAdapter: InteractionFinderAdapter {
|
||||
FROM \(InteractionRecord.databaseTableName)
|
||||
WHERE \(interactionColumn: .threadUniqueId) = ?
|
||||
AND \(interactionColumn: .recordType) IN (\(sqlInteractionTypes))
|
||||
OR (
|
||||
\(interactionColumn: .recordType) = \(SDSRecordType.infoMessage.rawValue)
|
||||
AND \(interactionColumn: .messageType) = \(TSInfoMessageType.typeGroupUpdate.rawValue)
|
||||
)
|
||||
LIMIT 1
|
||||
)
|
||||
"""
|
||||
let arguments: StatementArguments = [threadUniqueId]
|
||||
return try! Bool.fetchOne(transaction.database, sql: sql, arguments: arguments) ?? false
|
||||
return try! Bool.fetchOne(transaction.database, sql: sql, arguments: arguments)!
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
@ -60,35 +60,6 @@ public class AnyThreadFinder: NSObject, ThreadFinder {
|
||||
return yapAdapter.sortIndex(thread: thread, transaction: yap)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func hasPendingMessageRequest(thread: TSThread, transaction: ReadTransaction) -> Bool {
|
||||
// If the feature isn't enabled, do nothing.
|
||||
guard RemoteConfig.messageRequests else { return false }
|
||||
|
||||
// If we're creating the thread, don't show the message request view
|
||||
guard thread.shouldThreadBeVisible else { return false }
|
||||
|
||||
// If the thread is already whitelisted, do nothing. The user has already
|
||||
// accepted the request for this thread.
|
||||
guard !SSKEnvironment.shared.profileManager.isThread(
|
||||
inProfileWhitelist: thread,
|
||||
transaction: transaction
|
||||
) else { return false }
|
||||
|
||||
let interactionFinder = InteractionFinder(threadUniqueId: thread.uniqueId)
|
||||
|
||||
let hasSentMessages = interactionFinder.existsOutgoingMessage(transaction: transaction)
|
||||
guard !hasSentMessages || FeatureFlags.phoneNumberPrivacy else { return false }
|
||||
|
||||
// This thread is likely only visible because of system messages like so-and-so
|
||||
// is on signal or sync status. Some of the "possibly" incoming messages might
|
||||
// actually have been triggered by us, but if we sent one of these then the thread
|
||||
// should be in our profile white list and not make it to this check.
|
||||
guard interactionFinder.possiblyHasIncomingMessages(transaction: transaction.unwrapGrdbRead) else { return false }
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
struct YAPDBThreadFinder: ThreadFinder {
|
||||
@ -159,13 +130,14 @@ struct YAPDBThreadFinder: ThreadFinder {
|
||||
}
|
||||
}
|
||||
|
||||
struct GRDBThreadFinder: ThreadFinder {
|
||||
@objc
|
||||
public class GRDBThreadFinder: NSObject, ThreadFinder {
|
||||
|
||||
typealias ReadTransaction = GRDBReadTransaction
|
||||
public typealias ReadTransaction = GRDBReadTransaction
|
||||
|
||||
static let cn = ThreadRecord.columnName
|
||||
|
||||
func visibleThreadCount(isArchived: Bool, transaction: GRDBReadTransaction) throws -> UInt {
|
||||
public func visibleThreadCount(isArchived: Bool, transaction: GRDBReadTransaction) throws -> UInt {
|
||||
let sql = """
|
||||
SELECT COUNT(*)
|
||||
FROM \(ThreadRecord.databaseTableName)
|
||||
@ -182,7 +154,8 @@ struct GRDBThreadFinder: ThreadFinder {
|
||||
return count
|
||||
}
|
||||
|
||||
func enumerateVisibleThreads(isArchived: Bool, transaction: GRDBReadTransaction, block: @escaping (TSThread) -> Void) throws {
|
||||
@objc
|
||||
public func enumerateVisibleThreads(isArchived: Bool, transaction: GRDBReadTransaction, block: @escaping (TSThread) -> Void) throws {
|
||||
let sql = """
|
||||
SELECT *
|
||||
FROM \(ThreadRecord.databaseTableName)
|
||||
@ -197,7 +170,7 @@ struct GRDBThreadFinder: ThreadFinder {
|
||||
}
|
||||
}
|
||||
|
||||
func sortIndex(thread: TSThread, transaction: GRDBReadTransaction) throws -> UInt? {
|
||||
public func sortIndex(thread: TSThread, transaction: GRDBReadTransaction) throws -> UInt? {
|
||||
let sql = """
|
||||
SELECT sortIndex
|
||||
FROM (
|
||||
@ -216,4 +189,38 @@ struct GRDBThreadFinder: ThreadFinder {
|
||||
let arguments: StatementArguments = [grdbId.intValue]
|
||||
return try UInt.fetchOne(transaction.database, sql: sql, arguments: arguments)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func hasPendingMessageRequest(thread: TSThread, transaction: GRDBReadTransaction) -> Bool {
|
||||
// If the feature isn't enabled, do nothing.
|
||||
guard RemoteConfig.messageRequests else { return false }
|
||||
|
||||
// If we're creating the thread, don't show the message request view
|
||||
guard thread.shouldThreadBeVisible else { return false }
|
||||
|
||||
// If the thread is already whitelisted, do nothing. The user has already
|
||||
// accepted the request for this thread.
|
||||
guard !SSKEnvironment.shared.profileManager.isThread(
|
||||
inProfileWhitelist: thread,
|
||||
transaction: transaction.asAnyRead
|
||||
) else { return false }
|
||||
|
||||
let interactionFinder = GRDBInteractionFinderAdapter(threadUniqueId: thread.uniqueId)
|
||||
|
||||
let hasSentMessages = interactionFinder.existsOutgoingMessage(transaction: transaction)
|
||||
guard !hasSentMessages || FeatureFlags.phoneNumberPrivacy else { return false }
|
||||
|
||||
if thread.isGroupThread(),
|
||||
interactionFinder.hasGroupUpdateInfoMessage(transaction: transaction) {
|
||||
return true
|
||||
}
|
||||
|
||||
// This thread is likely only visible because of system messages like so-and-so
|
||||
// is on signal or sync status. Some of the "possibly" incoming messages might
|
||||
// actually have been triggered by us, but if we sent one of these then the thread
|
||||
// should be in our profile white list and not make it to this check.
|
||||
guard interactionFinder.possiblyHasIncomingMessages(transaction: transaction) else { return false }
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user