mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.9 KiB
Matlab
145 lines
4.9 KiB
Matlab
4 years ago
|
//
|
||
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||
|
//
|
||
|
|
||
|
#import "OWSIncomingMessageFinder.h"
|
||
|
#import "OWSPrimaryStorage.h"
|
||
|
#import "TSIncomingMessage.h"
|
||
|
#import <YapDatabase/YapDatabase.h>
|
||
|
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
|
||
|
|
||
|
NS_ASSUME_NONNULL_BEGIN
|
||
|
|
||
|
NSString *const OWSIncomingMessageFinderExtensionName = @"OWSIncomingMessageFinderExtensionName";
|
||
|
|
||
|
NSString *const OWSIncomingMessageFinderColumnTimestamp = @"OWSIncomingMessageFinderColumnTimestamp";
|
||
|
NSString *const OWSIncomingMessageFinderColumnSourceId = @"OWSIncomingMessageFinderColumnSourceId";
|
||
|
NSString *const OWSIncomingMessageFinderColumnSourceDeviceId = @"OWSIncomingMessageFinderColumnSourceDeviceId";
|
||
|
|
||
|
@interface OWSIncomingMessageFinder ()
|
||
|
|
||
|
@property (nonatomic, readonly) OWSPrimaryStorage *primaryStorage;
|
||
|
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
|
||
|
|
||
|
@end
|
||
|
|
||
|
@implementation OWSIncomingMessageFinder
|
||
|
|
||
|
@synthesize dbConnection = _dbConnection;
|
||
|
|
||
|
#pragma mark - init
|
||
|
|
||
|
- (instancetype)init
|
||
|
{
|
||
|
return [self initWithPrimaryStorage:[OWSPrimaryStorage sharedManager]];
|
||
|
}
|
||
|
|
||
|
- (instancetype)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage
|
||
|
{
|
||
|
self = [super init];
|
||
|
if (!self) {
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
_primaryStorage = primaryStorage;
|
||
|
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
#pragma mark - properties
|
||
|
|
||
|
- (YapDatabaseConnection *)dbConnection
|
||
|
{
|
||
|
@synchronized(self) {
|
||
|
if (!_dbConnection) {
|
||
|
_dbConnection = [self.primaryStorage newDatabaseConnection];
|
||
|
}
|
||
|
}
|
||
|
return _dbConnection;
|
||
|
}
|
||
|
|
||
|
#pragma mark - YAP integration
|
||
|
|
||
|
+ (YapDatabaseSecondaryIndex *)indexExtension
|
||
|
{
|
||
|
YapDatabaseSecondaryIndexSetup *setup = [YapDatabaseSecondaryIndexSetup new];
|
||
|
|
||
|
[setup addColumn:OWSIncomingMessageFinderColumnTimestamp withType:YapDatabaseSecondaryIndexTypeInteger];
|
||
|
[setup addColumn:OWSIncomingMessageFinderColumnSourceId withType:YapDatabaseSecondaryIndexTypeText];
|
||
|
[setup addColumn:OWSIncomingMessageFinderColumnSourceDeviceId withType:YapDatabaseSecondaryIndexTypeInteger];
|
||
|
|
||
|
YapDatabaseSecondaryIndexWithObjectBlock block = ^(YapDatabaseReadTransaction *transaction,
|
||
|
NSMutableDictionary *dict,
|
||
|
NSString *collection,
|
||
|
NSString *key,
|
||
|
id object) {
|
||
|
if ([object isKindOfClass:[TSIncomingMessage class]]) {
|
||
|
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)object;
|
||
|
|
||
|
// On new messages authorId should be set on all incoming messages, but there was a time when authorId was
|
||
|
// only set on incoming group messages.
|
||
|
NSObject *authorIdOrNull = incomingMessage.authorId ? incomingMessage.authorId : [NSNull null];
|
||
|
[dict setObject:@(incomingMessage.timestamp) forKey:OWSIncomingMessageFinderColumnTimestamp];
|
||
|
[dict setObject:authorIdOrNull forKey:OWSIncomingMessageFinderColumnSourceId];
|
||
|
[dict setObject:@(incomingMessage.sourceDeviceId) forKey:OWSIncomingMessageFinderColumnSourceDeviceId];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
YapDatabaseSecondaryIndexHandler *handler = [YapDatabaseSecondaryIndexHandler withObjectBlock:block];
|
||
|
|
||
|
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler versionTag:nil];
|
||
|
}
|
||
|
|
||
|
+ (NSString *)databaseExtensionName
|
||
|
{
|
||
|
return OWSIncomingMessageFinderExtensionName;
|
||
|
}
|
||
|
|
||
|
+ (void)asyncRegisterExtensionWithPrimaryStorage:(OWSStorage *)storage
|
||
|
{
|
||
|
[storage asyncRegisterExtension:self.indexExtension withName:OWSIncomingMessageFinderExtensionName];
|
||
|
}
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
// We should not normally hit this, as we should have prefer registering async, but it is useful for testing.
|
||
|
- (void)registerExtension
|
||
|
{
|
||
|
[self.primaryStorage registerExtension:self.class.indexExtension withName:OWSIncomingMessageFinderExtensionName];
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#pragma mark - instance methods
|
||
|
|
||
|
- (BOOL)existsMessageWithTimestamp:(uint64_t)timestamp
|
||
|
sourceId:(NSString *)sourceId
|
||
|
sourceDeviceId:(uint32_t)sourceDeviceId
|
||
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||
|
{
|
||
|
#ifdef DEBUG
|
||
|
if (![self.primaryStorage registeredExtension:OWSIncomingMessageFinderExtensionName]) {
|
||
|
|
||
|
// we should be initializing this at startup rather than have an unexpectedly slow lazy setup at random.
|
||
|
[self registerExtension];
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
NSString *queryFormat = [NSString stringWithFormat:@"WHERE %@ = ? AND %@ = ? AND %@ = ?",
|
||
|
OWSIncomingMessageFinderColumnTimestamp,
|
||
|
OWSIncomingMessageFinderColumnSourceId,
|
||
|
OWSIncomingMessageFinderColumnSourceDeviceId];
|
||
|
// YapDatabaseQuery params must be objects
|
||
|
YapDatabaseQuery *query = [YapDatabaseQuery queryWithFormat:queryFormat, @(timestamp), sourceId, @(sourceDeviceId)];
|
||
|
|
||
|
NSUInteger count;
|
||
|
BOOL success = [[transaction ext:OWSIncomingMessageFinderExtensionName] getNumberOfRows:&count matchingQuery:query];
|
||
|
if (!success) {
|
||
|
return NO;
|
||
|
}
|
||
|
|
||
|
return count > 0;
|
||
|
}
|
||
|
|
||
|
@end
|
||
|
|
||
|
NS_ASSUME_NONNULL_END
|