|
|
|
@ -14,137 +14,9 @@
|
|
|
|
|
#import "TSStorageManager.h"
|
|
|
|
|
#import "TextSecureKitEnv.h"
|
|
|
|
|
#import "Threading.h"
|
|
|
|
|
#import <YapDatabase/YapDatabaseView.h>
|
|
|
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
|
|
|
|
|
//#pragma mark - Finder
|
|
|
|
|
|
|
|
|
|
NSString *const OWSOutgoingMessageFinderExtensionName = @"OWSOutgoingMessageFinderExtensionName";
|
|
|
|
|
|
|
|
|
|
@interface OWSOutgoingMessageFinder : NSObject
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
@interface OWSOutgoingMessageFinder ()
|
|
|
|
|
|
|
|
|
|
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
@implementation OWSOutgoingMessageFinder
|
|
|
|
|
|
|
|
|
|
- (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection
|
|
|
|
|
{
|
|
|
|
|
OWSSingletonAssert();
|
|
|
|
|
|
|
|
|
|
self = [super init];
|
|
|
|
|
if (!self) {
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dbConnection = dbConnection;
|
|
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSArray<TSOutgoingMessage *> *)outgoingMessagesWithTimestamp:(uint64_t)timestamp
|
|
|
|
|
transaction:(YapDatabaseReadTransaction *)transaction
|
|
|
|
|
{
|
|
|
|
|
OWSAssert(transaction);
|
|
|
|
|
NSMutableArray<TSOutgoingMessage *> *result = [NSMutableArray new];
|
|
|
|
|
YapDatabaseViewTransaction *viewTransaction = [transaction ext:OWSOutgoingMessageFinderExtensionName];
|
|
|
|
|
OWSAssert(viewTransaction);
|
|
|
|
|
[viewTransaction
|
|
|
|
|
enumerateKeysAndObjectsInGroup:[OWSOutgoingMessageFinder groupForTimestamp:timestamp]
|
|
|
|
|
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
|
|
|
|
OWSAssert([object isKindOfClass:[TSOutgoingMessage class]]);
|
|
|
|
|
TSOutgoingMessage *message = (TSOutgoingMessage *)object;
|
|
|
|
|
OWSAssert(message.timestamp == timestamp);
|
|
|
|
|
[result addObject:object];
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
return [result copy];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ (NSString *)groupForTimestamp:(uint64_t)timestamp
|
|
|
|
|
{
|
|
|
|
|
return [NSString stringWithFormat:@"%llu", timestamp];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ (YapDatabaseView *)databaseExtension
|
|
|
|
|
{
|
|
|
|
|
YapDatabaseViewSorting *sorting =
|
|
|
|
|
[YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction,
|
|
|
|
|
NSString *group,
|
|
|
|
|
NSString *collection1,
|
|
|
|
|
NSString *key1,
|
|
|
|
|
id object1,
|
|
|
|
|
NSString *collection2,
|
|
|
|
|
NSString *key2,
|
|
|
|
|
id object2) {
|
|
|
|
|
// The ordering doesn't matter as long as its consistent.
|
|
|
|
|
return [key1 compare:key2];
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
YapDatabaseViewGrouping *grouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(
|
|
|
|
|
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
|
|
|
|
if (![object isKindOfClass:[TSOutgoingMessage class]]) {
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSOutgoingMessage *message = (TSOutgoingMessage *)object;
|
|
|
|
|
|
|
|
|
|
// Arbitrary string - all in the same group. We're only using the view for sorting.
|
|
|
|
|
return [OWSOutgoingMessageFinder groupForTimestamp:message.timestamp];
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
YapDatabaseViewOptions *options = [YapDatabaseViewOptions new];
|
|
|
|
|
options.allowedCollections =
|
|
|
|
|
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSOutgoingMessage collection]]];
|
|
|
|
|
|
|
|
|
|
return [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ (void)asyncRegisterDatabaseExtension:(YapDatabase *)database
|
|
|
|
|
{
|
|
|
|
|
YapDatabaseView *existingView = [database registeredExtension:OWSOutgoingMessageFinderExtensionName];
|
|
|
|
|
if (existingView) {
|
|
|
|
|
OWSFail(@"%@ was already initialized.", OWSOutgoingMessageFinderExtensionName);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
[database
|
|
|
|
|
asyncRegisterExtension:[self databaseExtension]
|
|
|
|
|
withName:OWSOutgoingMessageFinderExtensionName
|
|
|
|
|
completionBlock:^(BOOL ready) {
|
|
|
|
|
OWSCAssert(ready);
|
|
|
|
|
|
|
|
|
|
DDLogInfo(
|
|
|
|
|
@"%@ asyncRegisterExtension: %@ -> %d", self.tag, OWSOutgoingMessageFinderExtensionName, ready);
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - Logging
|
|
|
|
|
|
|
|
|
|
+ (NSString *)tag
|
|
|
|
|
{
|
|
|
|
|
return [NSString stringWithFormat:@"[%@]", self.class];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSString *)tag
|
|
|
|
|
{
|
|
|
|
|
return self.class.tag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
NSString *const OWSReadReceiptManagerCollection = @"OWSReadReceiptManagerCollection";
|
|
|
|
|
NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsEnabled";
|
|
|
|
|
NSString *const OWSRecipientReadReceiptCollection = @"OWSRecipientReadReceiptCollection";
|
|
|
|
@ -155,8 +27,6 @@ NSString *const OWSRecipientReadReceiptCollection = @"OWSRecipientReadReceiptCol
|
|
|
|
|
|
|
|
|
|
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
|
|
|
|
|
|
|
|
|
|
@property (nonatomic, readonly) OWSOutgoingMessageFinder *outgoingMessageFinder;
|
|
|
|
|
|
|
|
|
|
// A map of "thread unique id"-to-"read receipt" for read receipts that
|
|
|
|
|
// we will send to our linked devices.
|
|
|
|
|
//
|
|
|
|
@ -211,8 +81,6 @@ NSString *const OWSRecipientReadReceiptCollection = @"OWSRecipientReadReceiptCol
|
|
|
|
|
_messageSender = messageSender;
|
|
|
|
|
_dbConnection = storageManager.newDatabaseConnection;
|
|
|
|
|
|
|
|
|
|
_outgoingMessageFinder = [[OWSOutgoingMessageFinder alloc] initWithDBConnection:self.dbConnection];
|
|
|
|
|
|
|
|
|
|
_toLinkedDevicesReadReceiptMap = [NSMutableDictionary new];
|
|
|
|
|
_toSenderReadReceiptMap = [NSMutableDictionary new];
|
|
|
|
|
|
|
|
|
@ -443,8 +311,10 @@ NSString *const OWSRecipientReadReceiptCollection = @"OWSRecipientReadReceiptCol
|
|
|
|
|
for (int i = 0; i < timestamps.count; i++) {
|
|
|
|
|
UInt64 timestamp = [timestamps uint64AtIndex:i];
|
|
|
|
|
|
|
|
|
|
NSArray<TSOutgoingMessage *> *messages =
|
|
|
|
|
[self.outgoingMessageFinder outgoingMessagesWithTimestamp:timestamp transaction:transaction];
|
|
|
|
|
NSArray<TSOutgoingMessage *> *messages
|
|
|
|
|
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:timestamp
|
|
|
|
|
ofClass:[TSOutgoingMessage class]
|
|
|
|
|
withTransaction:transaction];
|
|
|
|
|
OWSAssert(messages.count <= 1);
|
|
|
|
|
if (messages.count > 0) {
|
|
|
|
|
// TODO: We might also need to "mark as read by recipient" any older messages
|
|
|
|
@ -518,13 +388,6 @@ NSString *const OWSRecipientReadReceiptCollection = @"OWSRecipientReadReceiptCol
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - Database Extension
|
|
|
|
|
|
|
|
|
|
+ (void)asyncRegisterDatabaseExtension:(YapDatabase *)database
|
|
|
|
|
{
|
|
|
|
|
[OWSOutgoingMessageFinder asyncRegisterDatabaseExtension:database];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - Logging
|
|
|
|
|
|
|
|
|
|
+ (NSString *)tag
|
|
|
|
|