Retain changes from session database branch.

pull/1/head
Matthew Chen 7 years ago
parent 76a295aaa5
commit 15b8e58324

@ -295,11 +295,11 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModified:) selector:@selector(yapDatabaseModified:)
name:YapDatabaseModifiedNotification name:YapDatabaseModifiedNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModifiedExternally:) selector:@selector(yapDatabaseModifiedExternally:)
name:YapDatabaseModifiedExternallyNotification name:YapDatabaseModifiedExternallyNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:) selector:@selector(applicationWillEnterForeground:)
name:OWSApplicationWillEnterForegroundNotification name:OWSApplicationWillEnterForegroundNotification

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
import Foundation import Foundation
@ -82,7 +82,7 @@ class MessageDetailViewController: OWSViewController, UIScrollViewDelegate {
NotificationCenter.default.addObserver(self, NotificationCenter.default.addObserver(self,
selector: #selector(yapDatabaseModified), selector: #selector(yapDatabaseModified),
name: NSNotification.Name.YapDatabaseModified, name: NSNotification.Name.YapDatabaseModified,
object: nil) object: TSStorageManager.shared().dbNotificationObject)
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSLinkedDevicesTableViewController.h" #import "OWSLinkedDevicesTableViewController.h"
@ -65,11 +65,11 @@ int const OWSLinkedDevicesTableViewControllerSectionAddDevice = 1;
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModified:) selector:@selector(yapDatabaseModified:)
name:YapDatabaseModifiedNotification name:YapDatabaseModifiedNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModifiedExternally:) selector:@selector(yapDatabaseModifiedExternally:)
name:YapDatabaseModifiedExternallyNotification name:YapDatabaseModifiedExternallyNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
self.refreshControl = [UIRefreshControl new]; self.refreshControl = [UIRefreshControl new];
[self.refreshControl addTarget:self action:@selector(refreshDevices) forControlEvents:UIControlEventValueChanged]; [self.refreshControl addTarget:self action:@selector(refreshDevices) forControlEvents:UIControlEventValueChanged];

@ -100,16 +100,18 @@ NS_ASSUME_NONNULL_BEGIN
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModified:) selector:@selector(yapDatabaseModified:)
name:YapDatabaseModifiedNotification name:YapDatabaseModifiedNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModifiedExternally:) selector:@selector(yapDatabaseModifiedExternally:)
name:YapDatabaseModifiedExternallyNotification name:YapDatabaseModifiedExternallyNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
} else { } else {
[[NSNotificationCenter defaultCenter] removeObserver:self name:YapDatabaseModifiedNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self
name:YapDatabaseModifiedNotification
object:TSStorageManager.sharedManager.dbNotificationObject];
[[NSNotificationCenter defaultCenter] removeObserver:self [[NSNotificationCenter defaultCenter] removeObserver:self
name:YapDatabaseModifiedExternallyNotification name:YapDatabaseModifiedExternallyNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
} }
} }

@ -1,11 +1,11 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope; @class OWSSignalServiceProtosEnvelope;
@class TSStorageManager; @class OWSStorage;
// This class is used to write incoming (decrypted, unprocessed) // This class is used to write incoming (decrypted, unprocessed)
// messages to a durable queue and then process them in batches, // messages to a durable queue and then process them in batches,
@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSBatchMessageProcessor : NSObject @interface OWSBatchMessageProcessor : NSObject
+ (instancetype)sharedInstance; + (instancetype)sharedInstance;
+ (void)syncRegisterDatabaseExtension:(TSStorageManager *)storageManager; + (void)syncRegisterDatabaseExtension:(OWSStorage *)storage;
- (void)enqueueEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData; - (void)enqueueEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData;
- (void)handleAnyUnprocessedEnvelopesAsync; - (void)handleAnyUnprocessedEnvelopesAsync;

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSBatchMessageProcessor.h" #import "OWSBatchMessageProcessor.h"
@ -200,15 +200,15 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
} }
+ (void)syncRegisterDatabaseExtension:(TSStorageManager *)storageManager + (void)syncRegisterDatabaseExtension:(OWSStorage *)storage
{ {
YapDatabaseView *existingView = [storageManager registeredExtension:OWSMessageContentJobFinderExtensionName]; YapDatabaseView *existingView = [storage registeredExtension:OWSMessageContentJobFinderExtensionName];
if (existingView) { if (existingView) {
OWSFail(@"%@ was already initialized.", OWSMessageContentJobFinderExtensionName); OWSFail(@"%@ was already initialized.", OWSMessageContentJobFinderExtensionName);
// already initialized // already initialized
return; return;
} }
[storageManager registerExtension:[self databaseExtension] withName:OWSMessageContentJobFinderExtensionName]; [storage registerExtension:[self databaseExtension] withName:OWSMessageContentJobFinderExtensionName];
} }
#pragma mark Logging #pragma mark Logging
@ -443,9 +443,9 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
#pragma mark - class methods #pragma mark - class methods
+ (void)syncRegisterDatabaseExtension:(TSStorageManager *)storageManager + (void)syncRegisterDatabaseExtension:(OWSStorage *)storage
{ {
[OWSMessageContentJobFinder syncRegisterDatabaseExtension:storageManager]; [OWSMessageContentJobFinder syncRegisterDatabaseExtension:storage];
} }
#pragma mark - instance methods #pragma mark - instance methods

@ -1,11 +1,12 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class TSStorageManager; @class OWSStorage;
@class TSMessage; @class TSMessage;
@class TSStorageManager;
@class TSThread; @class TSThread;
@class YapDatabaseReadTransaction; @class YapDatabaseReadTransaction;
@ -27,12 +28,12 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
* Database extensions required for class to work. * Database extensions required for class to work.
*/ */
+ (void)asyncRegisterDatabaseExtensions:(TSStorageManager *)storageManager; + (void)asyncRegisterDatabaseExtensions:(OWSStorage *)storage;
/** /**
* Only use the sync version for testing, generally we'll want to register extensions async * Only use the sync version for testing, generally we'll want to register extensions async
*/ */
+ (void)blockingRegisterDatabaseExtensions:(TSStorageManager *)storageManager; + (void)blockingRegisterDatabaseExtensions:(OWSStorage *)storage;
@end @end

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSDisappearingMessagesFinder.h" #import "OWSDisappearingMessagesFinder.h"
@ -189,23 +189,22 @@ static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_mess
} }
// Useful for tests, don't use in app startup path because it's slow. // Useful for tests, don't use in app startup path because it's slow.
+ (void)blockingRegisterDatabaseExtensions:(TSStorageManager *)storageManager + (void)blockingRegisterDatabaseExtensions:(OWSStorage *)storage
{ {
[storageManager registerExtension:[self indexDatabaseExtension] [storage registerExtension:[self indexDatabaseExtension] withName:OWSDisappearingMessageFinderExpiresAtIndex];
withName:OWSDisappearingMessageFinderExpiresAtIndex];
} }
+ (void)asyncRegisterDatabaseExtensions:(TSStorageManager *)storageManager + (void)asyncRegisterDatabaseExtensions:(OWSStorage *)storage
{ {
[storageManager asyncRegisterExtension:[self indexDatabaseExtension] [storage asyncRegisterExtension:[self indexDatabaseExtension]
withName:OWSDisappearingMessageFinderExpiresAtIndex withName:OWSDisappearingMessageFinderExpiresAtIndex
completionBlock:^(BOOL ready) { completionBlock:^(BOOL ready) {
if (ready) { if (ready) {
DDLogDebug(@"%@ completed registering extension async.", self.logTag); DDLogDebug(@"%@ completed registering extension async.", self.logTag);
} else { } else {
DDLogError(@"%@ failed registering extension async.", self.logTag); DDLogError(@"%@ failed registering extension async.", self.logTag);
} }
}]; }];
} }
@end @end

@ -1,9 +1,10 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSStorage;
@class TSStorageManager; @class TSStorageManager;
@interface OWSFailedAttachmentDownloadsJob : NSObject @interface OWSFailedAttachmentDownloadsJob : NSObject
@ -16,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
* Database extensions required for class to work. * Database extensions required for class to work.
*/ */
+ (void)asyncRegisterDatabaseExtensionsWithStorageManager:(TSStorageManager *)storageManager; + (void)asyncRegisterDatabaseExtensionsWithStorageManager:(OWSStorage *)storage;
/** /**
* Only use the sync version for testing, generally we'll want to register extensions async * Only use the sync version for testing, generally we'll want to register extensions async

@ -124,17 +124,17 @@ static NSString *const OWSFailedAttachmentDownloadsJobAttachmentStateIndex = @"i
withName:OWSFailedAttachmentDownloadsJobAttachmentStateIndex]; withName:OWSFailedAttachmentDownloadsJobAttachmentStateIndex];
} }
+ (void)asyncRegisterDatabaseExtensionsWithStorageManager:(TSStorageManager *)storageManager + (void)asyncRegisterDatabaseExtensionsWithStorageManager:(OWSStorage *)storage
{ {
[storageManager asyncRegisterExtension:[self indexDatabaseExtension] [storage asyncRegisterExtension:[self indexDatabaseExtension]
withName:OWSFailedAttachmentDownloadsJobAttachmentStateIndex withName:OWSFailedAttachmentDownloadsJobAttachmentStateIndex
completionBlock:^(BOOL ready) { completionBlock:^(BOOL ready) {
if (ready) { if (ready) {
DDLogDebug(@"%@ completed registering extension async.", self.logTag); DDLogDebug(@"%@ completed registering extension async.", self.logTag);
} else { } else {
DDLogError(@"%@ failed registering extension async.", self.logTag); DDLogError(@"%@ failed registering extension async.", self.logTag);
} }
}]; }];
} }
@end @end

@ -1,9 +1,10 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSStorage;
@class TSStorageManager; @class TSStorageManager;
@interface OWSFailedMessagesJob : NSObject @interface OWSFailedMessagesJob : NSObject
@ -16,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
* Database extensions required for class to work. * Database extensions required for class to work.
*/ */
+ (void)asyncRegisterDatabaseExtensionsWithStorageManager:(TSStorageManager *)storageManager; + (void)asyncRegisterDatabaseExtensionsWithStorageManager:(OWSStorage *)storage;
/** /**
* Only use the sync version for testing, generally we'll want to register extensions async * Only use the sync version for testing, generally we'll want to register extensions async

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSFailedMessagesJob.h" #import "OWSFailedMessagesJob.h"
@ -134,17 +134,17 @@ static NSString *const OWSFailedMessagesJobMessageStateIndex = @"index_outoing_m
withName:OWSFailedMessagesJobMessageStateIndex]; withName:OWSFailedMessagesJobMessageStateIndex];
} }
+ (void)asyncRegisterDatabaseExtensionsWithStorageManager:(TSStorageManager *)storageManager + (void)asyncRegisterDatabaseExtensionsWithStorageManager:(OWSStorage *)storage
{ {
[storageManager asyncRegisterExtension:[self indexDatabaseExtension] [storage asyncRegisterExtension:[self indexDatabaseExtension]
withName:OWSFailedMessagesJobMessageStateIndex withName:OWSFailedMessagesJobMessageStateIndex
completionBlock:^(BOOL ready) { completionBlock:^(BOOL ready) {
if (ready) { if (ready) {
DDLogDebug(@"%@ completed registering extension async.", self.logTag); DDLogDebug(@"%@ completed registering extension async.", self.logTag);
} else { } else {
DDLogError(@"%@ failed registering extension async.", self.logTag); DDLogError(@"%@ failed registering extension async.", self.logTag);
} }
}]; }];
} }
@end @end

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSRecipientIdentity.h" #import "OWSRecipientIdentity.h"
@ -18,6 +18,7 @@ extern const NSUInteger kIdentityKeyLength;
@class OWSRecipientIdentity; @class OWSRecipientIdentity;
@class OWSSignalServiceProtosVerified; @class OWSSignalServiceProtosVerified;
@class OWSStorage;
// This class can be safely accessed and used from any thread. // This class can be safely accessed and used from any thread.
@interface OWSIdentityManager : NSObject <IdentityKeyStore> @interface OWSIdentityManager : NSObject <IdentityKeyStore>

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSMessageManager.h" #import "OWSMessageManager.h"
@ -126,11 +126,11 @@ NS_ASSUME_NONNULL_BEGIN
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModified:) selector:@selector(yapDatabaseModified:)
name:YapDatabaseModifiedNotification name:YapDatabaseModifiedNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModified:) selector:@selector(yapDatabaseModified:)
name:YapDatabaseModifiedExternallyNotification name:YapDatabaseModifiedExternallyNotification
object:nil]; object:TSStorageManager.sharedManager.dbNotificationObject];
} }
- (void)yapDatabaseModified:(NSNotification *)notification - (void)yapDatabaseModified:(NSNotification *)notification

@ -1,11 +1,11 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope; @class OWSSignalServiceProtosEnvelope;
@class TSStorageManager; @class OWSStorage;
// This class is used to write incoming (encrypted, unprocessed) // This class is used to write incoming (encrypted, unprocessed)
// messages to a durable queue and then decrypt them in the order // messages to a durable queue and then decrypt them in the order
@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSMessageReceiver : NSObject @interface OWSMessageReceiver : NSObject
+ (instancetype)sharedInstance; + (instancetype)sharedInstance;
+ (void)syncRegisterDatabaseExtension:(TSStorageManager *)storageManager; + (void)syncRegisterDatabaseExtension:(OWSStorage *)storage;
- (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope; - (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope;
- (void)handleAnyUnprocessedEnvelopesAsync; - (void)handleAnyUnprocessedEnvelopesAsync;

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSMessageReceiver.h" #import "OWSMessageReceiver.h"
@ -190,17 +190,17 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
}); });
} }
+ (void)syncRegisterDatabaseExtension:(TSStorageManager *)storageManager + (void)syncRegisterDatabaseExtension:(OWSStorage *)storage
{ {
[self registerLegacyClasses]; [self registerLegacyClasses];
YapDatabaseView *existingView = [storageManager registeredExtension:OWSMessageDecryptJobFinderExtensionName]; YapDatabaseView *existingView = [storage registeredExtension:OWSMessageDecryptJobFinderExtensionName];
if (existingView) { if (existingView) {
OWSFail(@"%@ was already initialized.", OWSMessageDecryptJobFinderExtensionName); OWSFail(@"%@ was already initialized.", OWSMessageDecryptJobFinderExtensionName);
// already initialized // already initialized
return; return;
} }
[storageManager registerExtension:[self databaseExtension] withName:OWSMessageDecryptJobFinderExtensionName]; [storage registerExtension:[self databaseExtension] withName:OWSMessageDecryptJobFinderExtensionName];
} }
@end @end
@ -422,9 +422,9 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
#pragma mark - class methods #pragma mark - class methods
+ (void)syncRegisterDatabaseExtension:(TSStorageManager *)storageManager + (void)syncRegisterDatabaseExtension:(OWSStorage *)storage
{ {
[OWSMessageDecryptJobFinder syncRegisterDatabaseExtension:storageManager]; [OWSMessageDecryptJobFinder syncRegisterDatabaseExtension:storage];
} }
#pragma mark - instance methods #pragma mark - instance methods

@ -1,9 +1,10 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSStorage;
@class TSStorageManager; @class TSStorageManager;
@class YapDatabaseReadTransaction; @class YapDatabaseReadTransaction;
@ -14,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
* Must be called before using this finder. * Must be called before using this finder.
*/ */
+ (void)asyncRegisterExtensionWithStorageManager:(TSStorageManager *)storageManager; + (void)asyncRegisterExtensionWithStorageManager:(OWSStorage *)storage;
/** /**
* Detects existance of a duplicate incoming message. * Detects existance of a duplicate incoming message.

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSIncomingMessageFinder.h" #import "OWSIncomingMessageFinder.h"
@ -92,14 +92,14 @@ NSString *const OWSIncomingMessageFinderColumnSourceDeviceId = @"OWSIncomingMess
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler]; return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];
} }
+ (void)asyncRegisterExtensionWithStorageManager:(TSStorageManager *)storageManager + (void)asyncRegisterExtensionWithStorageManager:(OWSStorage *)storage
{ {
DDLogInfo(@"%@ registering async.", self.logTag); DDLogInfo(@"%@ registering async.", self.logTag);
[storageManager asyncRegisterExtension:self.indexExtension [storage asyncRegisterExtension:self.indexExtension
withName:OWSIncomingMessageFinderExtensionName withName:OWSIncomingMessageFinderExtensionName
completionBlock:^(BOOL ready) { completionBlock:^(BOOL ready) {
DDLogInfo(@"%@ finished registering async.", self.logTag); DDLogInfo(@"%@ finished registering async.", self.logTag);
}]; }];
} }
// We should not normally hit this, as we should have prefer registering async, but it is useful for testing. // We should not normally hit this, as we should have prefer registering async, but it is useful for testing.

@ -19,6 +19,9 @@ extern NSString *const StorageIsReadyNotification;
// sync _AND_ async view registrations. // sync _AND_ async view registrations.
+ (BOOL)isStorageReady; + (BOOL)isStorageReady;
// This object can be used to filter database notifications.
@property (nonatomic, readonly, nullable) id dbNotificationObject;
/** /**
* The safeBlockingMigrationsBlock block will * The safeBlockingMigrationsBlock block will
* run any outstanding version migrations that are a) blocking and b) safe * run any outstanding version migrations that are a) blocking and b) safe

@ -286,6 +286,13 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
- (nullable id)dbNotificationObject
{
OWSAssert(self.database);
return self.database;
}
- (BOOL)areAsyncRegistrationsComplete - (BOOL)areAsyncRegistrationsComplete
{ {
OWS_ABSTRACT_METHOD(); OWS_ABSTRACT_METHOD();

@ -1,7 +1,8 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSStorage.h"
#import <YapDatabase/YapDatabaseViewTransaction.h> #import <YapDatabase/YapDatabaseViewTransaction.h>
extern NSString *const TSInboxGroup; extern NSString *const TSInboxGroup;
@ -20,27 +21,27 @@ extern NSString *const TSSecondaryDevicesDatabaseViewExtensionName;
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
+ (void)registerCrossProcessNotifier; + (void)registerCrossProcessNotifier:(OWSStorage *)storage;
// This method must be called _AFTER_ registerThreadInteractionsDatabaseView. // This method must be called _AFTER_ registerThreadInteractionsDatabaseView.
+ (void)registerThreadDatabaseView; + (void)registerThreadDatabaseView:(OWSStorage *)storage;
+ (void)registerThreadInteractionsDatabaseView; + (void)registerThreadInteractionsDatabaseView:(OWSStorage *)storage;
+ (void)asyncRegisterThreadOutgoingMessagesDatabaseView; + (void)asyncRegisterThreadOutgoingMessagesDatabaseView:(OWSStorage *)storage;
// Instances of OWSReadTracking for wasRead is NO and shouldAffectUnreadCounts is YES. // Instances of OWSReadTracking for wasRead is NO and shouldAffectUnreadCounts is YES.
// //
// Should be used for "unread message counts". // Should be used for "unread message counts".
+ (void)registerUnreadDatabaseView; + (void)registerUnreadDatabaseView:(OWSStorage *)storage;
// Should be used for "unread indicator". // Should be used for "unread indicator".
// //
// Instances of OWSReadTracking for wasRead is NO. // Instances of OWSReadTracking for wasRead is NO.
+ (void)asyncRegisterUnseenDatabaseView; + (void)asyncRegisterUnseenDatabaseView:(OWSStorage *)storage;
+ (void)asyncRegisterThreadSpecialMessagesDatabaseView; + (void)asyncRegisterThreadSpecialMessagesDatabaseView:(OWSStorage *)storage;
+ (void)asyncRegisterSecondaryDevicesDatabaseView; + (void)asyncRegisterSecondaryDevicesDatabaseView:(OWSStorage *)storage;
// Returns the "unseen" database view if it is ready; // Returns the "unseen" database view if it is ready;
// otherwise it returns the "unread" database view. // otherwise it returns the "unread" database view.

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
@ -8,7 +8,6 @@
#import "TSIncomingMessage.h" #import "TSIncomingMessage.h"
#import "TSInvalidIdentityKeyErrorMessage.h" #import "TSInvalidIdentityKeyErrorMessage.h"
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import "TSStorageManager.h"
#import "TSThread.h" #import "TSThread.h"
#import <YapDatabase/YapDatabaseAutoView.h> #import <YapDatabase/YapDatabaseAutoView.h>
#import <YapDatabase/YapDatabaseCrossProcessNotification.h> #import <YapDatabase/YapDatabaseCrossProcessNotification.h>
@ -32,25 +31,29 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
@implementation TSDatabaseView @implementation TSDatabaseView
+ (void)registerCrossProcessNotifier + (void)registerCrossProcessNotifier:(OWSStorage *)storage
{ {
OWSAssert(storage);
// I don't think the identifier and name of this extension matter for our purposes, // I don't think the identifier and name of this extension matter for our purposes,
// so long as they don't conflict with any other extension names. // so long as they don't conflict with any other extension names.
YapDatabaseExtension *extension = YapDatabaseExtension *extension =
[[YapDatabaseCrossProcessNotification alloc] initWithIdentifier:@"SignalCrossProcessNotifier"]; [[YapDatabaseCrossProcessNotification alloc] initWithIdentifier:@"SignalCrossProcessNotifier"];
[[TSStorageManager sharedManager] registerExtension:extension withName:@"SignalCrossProcessNotifier"]; [storage registerExtension:extension withName:@"SignalCrossProcessNotifier"];
} }
+ (void)registerMessageDatabaseViewWithName:(NSString *)viewName + (void)registerMessageDatabaseViewWithName:(NSString *)viewName
viewGrouping:(YapDatabaseViewGrouping *)viewGrouping viewGrouping:(YapDatabaseViewGrouping *)viewGrouping
version:(NSString *)version version:(NSString *)version
async:(BOOL)async async:(BOOL)async
storage:(OWSStorage *)storage
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
OWSAssert(viewName.length > 0); OWSAssert(viewName.length > 0);
OWSAssert((viewGrouping)); OWSAssert((viewGrouping));
OWSAssert(storage);
YapDatabaseView *existingView = [[TSStorageManager sharedManager] registeredExtension:viewName]; YapDatabaseView *existingView = [storage registeredExtension:viewName];
if (existingView) { if (existingView) {
OWSFail(@"Registered database view twice: %@", viewName); OWSFail(@"Registered database view twice: %@", viewName);
return; return;
@ -69,20 +72,19 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
options:options]; options:options];
if (async) { if (async) {
[[TSStorageManager sharedManager] [storage asyncRegisterExtension:view
asyncRegisterExtension:view withName:viewName
withName:viewName completionBlock:^(BOOL ready) {
completionBlock:^(BOOL ready) { OWSCAssert(ready);
OWSCAssert(ready);
DDLogInfo(@"%@ asyncRegisterExtension: %@ -> %d", self.logTag, viewName, ready);
DDLogInfo(@"%@ asyncRegisterExtension: %@ -> %d", self.logTag, viewName, ready); }];
}];
} else { } else {
[[TSStorageManager sharedManager] registerExtension:view withName:viewName]; [storage registerExtension:view withName:viewName];
} }
} }
+ (void)registerUnreadDatabaseView + (void)registerUnreadDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
@ -98,10 +100,11 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
[self registerMessageDatabaseViewWithName:TSUnreadDatabaseViewExtensionName [self registerMessageDatabaseViewWithName:TSUnreadDatabaseViewExtensionName
viewGrouping:viewGrouping viewGrouping:viewGrouping
version:@"1" version:@"1"
async:NO]; async:NO
storage:storage];
} }
+ (void)asyncRegisterUnseenDatabaseView + (void)asyncRegisterUnseenDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
@ -117,10 +120,11 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
[self registerMessageDatabaseViewWithName:TSUnseenDatabaseViewExtensionName [self registerMessageDatabaseViewWithName:TSUnseenDatabaseViewExtensionName
viewGrouping:viewGrouping viewGrouping:viewGrouping
version:@"1" version:@"1"
async:YES]; async:YES
storage:storage];
} }
+ (void)asyncRegisterThreadSpecialMessagesDatabaseView + (void)asyncRegisterThreadSpecialMessagesDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
@ -144,10 +148,11 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
[self registerMessageDatabaseViewWithName:TSThreadSpecialMessagesDatabaseViewExtensionName [self registerMessageDatabaseViewWithName:TSThreadSpecialMessagesDatabaseViewExtensionName
viewGrouping:viewGrouping viewGrouping:viewGrouping
version:@"1" version:@"1"
async:YES]; async:YES
storage:storage];
} }
+ (void)registerThreadInteractionsDatabaseView + (void)registerThreadInteractionsDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
@ -160,10 +165,11 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
[self registerMessageDatabaseViewWithName:TSMessageDatabaseViewExtensionName [self registerMessageDatabaseViewWithName:TSMessageDatabaseViewExtensionName
viewGrouping:viewGrouping viewGrouping:viewGrouping
version:@"1" version:@"1"
async:NO]; async:NO
storage:storage];
} }
+ (void)asyncRegisterThreadOutgoingMessagesDatabaseView + (void)asyncRegisterThreadOutgoingMessagesDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
@ -176,13 +182,13 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
[self registerMessageDatabaseViewWithName:TSThreadOutgoingMessageDatabaseViewExtensionName [self registerMessageDatabaseViewWithName:TSThreadOutgoingMessageDatabaseViewExtensionName
viewGrouping:viewGrouping viewGrouping:viewGrouping
version:@"2" version:@"2"
async:YES]; async:YES
storage:storage];
} }
+ (void)registerThreadDatabaseView + (void)registerThreadDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseView *threadView = YapDatabaseView *threadView = [storage registeredExtension:TSThreadDatabaseViewExtensionName];
[[TSStorageManager sharedManager] registeredExtension:TSThreadDatabaseViewExtensionName];
if (threadView) { if (threadView) {
OWSFail(@"Registered database view twice: %@", TSThreadDatabaseViewExtensionName); OWSFail(@"Registered database view twice: %@", TSThreadDatabaseViewExtensionName);
return; return;
@ -228,7 +234,7 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
YapDatabaseView *databaseView = YapDatabaseView *databaseView =
[[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options]; [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options];
[[TSStorageManager sharedManager] registerExtension:databaseView withName:TSThreadDatabaseViewExtensionName]; [storage registerExtension:databaseView withName:TSThreadDatabaseViewExtensionName];
} }
/** /**
@ -296,7 +302,7 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
}]; }];
} }
+ (void)asyncRegisterSecondaryDevicesDatabaseView + (void)asyncRegisterSecondaryDevicesDatabaseView:(OWSStorage *)storage
{ {
YapDatabaseViewGrouping *viewGrouping = YapDatabaseViewGrouping *viewGrouping =
[YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(YapDatabaseReadTransaction *_Nonnull transaction, [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(YapDatabaseReadTransaction *_Nonnull transaction,
@ -341,16 +347,15 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
YapDatabaseView *view = YapDatabaseView *view =
[[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options]; [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options];
[[TSStorageManager sharedManager] [storage asyncRegisterExtension:view
asyncRegisterExtension:view withName:TSSecondaryDevicesDatabaseViewExtensionName
withName:TSSecondaryDevicesDatabaseViewExtensionName completionBlock:^(BOOL ready) {
completionBlock:^(BOOL ready) { if (ready) {
if (ready) { DDLogDebug(@"%@ Successfully set up extension: %@", self.logTag, TSSecondaryDevicesGroup);
DDLogDebug(@"%@ Successfully set up extension: %@", self.logTag, TSSecondaryDevicesGroup); } else {
} else { DDLogError(@"%@ Unable to setup extension: %@", self.logTag, TSSecondaryDevicesGroup);
DDLogError(@"%@ Unable to setup extension: %@", self.logTag, TSSecondaryDevicesGroup); }
} }];
}];
} }
+ (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction + (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction

@ -1,11 +1,15 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSStorage.h" #import "OWSStorage.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
void runSyncRegistrationsForPrimaryStorage(OWSStorage *storage);
void runAsyncRegistrationsForPrimaryStorage(OWSStorage *storage);
// TODO: Rename to OWSPrimaryStorage?
@interface TSStorageManager : OWSStorage @interface TSStorageManager : OWSStorage
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;

@ -3,6 +3,7 @@
// //
#import "TSStorageManager.h" #import "TSStorageManager.h"
#import "AppContext.h"
#import "OWSAnalytics.h" #import "OWSAnalytics.h"
#import "OWSBatchMessageProcessor.h" #import "OWSBatchMessageProcessor.h"
#import "OWSDisappearingMessagesFinder.h" #import "OWSDisappearingMessagesFinder.h"
@ -22,8 +23,41 @@ NSString *const TSStorageManagerExceptionName_CouldNotMoveDatabaseFile
NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
= @"TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory"; = @"TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory";
#pragma mark - void runSyncRegistrationsForPrimaryStorage(OWSStorage *storage)
{
OWSCAssert(storage);
// Synchronously register extensions which are essential for views.
[TSDatabaseView registerCrossProcessNotifier:storage];
[TSDatabaseView registerThreadInteractionsDatabaseView:storage];
[TSDatabaseView registerThreadDatabaseView:storage];
[TSDatabaseView registerUnreadDatabaseView:storage];
[storage registerExtension:[TSDatabaseSecondaryIndexes registerTimeStampIndex] withName:@"idx"];
[OWSMessageReceiver syncRegisterDatabaseExtension:storage];
[OWSBatchMessageProcessor syncRegisterDatabaseExtension:storage];
}
void runAsyncRegistrationsForPrimaryStorage(OWSStorage *storage)
{
OWSCAssert(storage);
// Asynchronously register other extensions.
//
// All sync registrations must be done before all async registrations,
// or the sync registrations will block on the async registrations.
[TSDatabaseView asyncRegisterUnseenDatabaseView:storage];
[TSDatabaseView asyncRegisterThreadOutgoingMessagesDatabaseView:storage];
[TSDatabaseView asyncRegisterThreadSpecialMessagesDatabaseView:storage];
// Register extensions which aren't essential for rendering threads async.
[OWSIncomingMessageFinder asyncRegisterExtensionWithStorageManager:storage];
[TSDatabaseView asyncRegisterSecondaryDevicesDatabaseView:storage];
[OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:storage];
[OWSFailedMessagesJob asyncRegisterDatabaseExtensionsWithStorageManager:storage];
[OWSFailedAttachmentDownloadsJob asyncRegisterDatabaseExtensionsWithStorageManager:storage];
}
#pragma mark -
@interface TSStorageManager () @interface TSStorageManager ()
@property (nonatomic, readonly, nullable) YapDatabaseConnection *dbReadConnection; @property (nonatomic, readonly, nullable) YapDatabaseConnection *dbReadConnection;
@ -75,14 +109,7 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
- (void)runSyncRegistrations - (void)runSyncRegistrations
{ {
// Synchronously register extensions which are essential for views. runSyncRegistrationsForPrimaryStorage(self);
[TSDatabaseView registerCrossProcessNotifier];
[TSDatabaseView registerThreadInteractionsDatabaseView];
[TSDatabaseView registerThreadDatabaseView];
[TSDatabaseView registerUnreadDatabaseView];
[self registerExtension:[TSDatabaseSecondaryIndexes registerTimeStampIndex] withName:@"idx"];
[OWSMessageReceiver syncRegisterDatabaseExtension:self];
[OWSBatchMessageProcessor syncRegisterDatabaseExtension:self];
// See comments on OWSDatabaseConnection. // See comments on OWSDatabaseConnection.
// //
@ -98,29 +125,18 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
{ {
OWSAssert(completion); OWSAssert(completion);
// Asynchronously register other extensions. runAsyncRegistrationsForPrimaryStorage(self);
//
// All sync registrations must be done before all async registrations,
// or the sync registrations will block on the async registrations.
[TSDatabaseView asyncRegisterUnseenDatabaseView];
[TSDatabaseView asyncRegisterThreadOutgoingMessagesDatabaseView];
[TSDatabaseView asyncRegisterThreadSpecialMessagesDatabaseView];
// Register extensions which aren't essential for rendering threads async.
[OWSIncomingMessageFinder asyncRegisterExtensionWithStorageManager:self];
[TSDatabaseView asyncRegisterSecondaryDevicesDatabaseView];
[OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:self];
[OWSFailedMessagesJob asyncRegisterDatabaseExtensionsWithStorageManager:self];
[OWSFailedAttachmentDownloadsJob asyncRegisterDatabaseExtensionsWithStorageManager:self];
// Block until all async registrations are complete. // Block until all async registrations are complete.
[self.newDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { YapDatabaseConnection *dbConnection = self.newDatabaseConnection;
OWSAssert(!self.areAsyncRegistrationsComplete); [dbConnection flushTransactionsWithCompletionQueue:dispatch_get_main_queue()
completionBlock:^{
OWSAssert(!self.areAsyncRegistrationsComplete);
self.areAsyncRegistrationsComplete = YES; self.areAsyncRegistrationsComplete = YES;
completion(); completion();
}]; }];
} }
+ (void)protectFiles + (void)protectFiles
@ -135,10 +151,6 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
[OWSFileSystem protectFileOrFolderAtPath:self.sharedDataDatabaseDirPath]; [OWSFileSystem protectFileOrFolderAtPath:self.sharedDataDatabaseDirPath];
} }
- (BOOL)userSetPassword {
return FALSE;
}
+ (NSString *)legacyDatabaseDirPath + (NSString *)legacyDatabaseDirPath
{ {
return [OWSFileSystem appDocumentDirectoryPath]; return [OWSFileSystem appDocumentDirectoryPath];

Loading…
Cancel
Save