Detect and handle corrupt database views.

pull/1/head
Matthew Chen 7 years ago
parent d3b484482c
commit 50a59c907d

@ -120,6 +120,11 @@ NS_ASSUME_NONNULL_BEGIN
}]];
#endif
[items addObject:[OWSTableItem itemWithTitle:@"Increment database extension version suffix"
actionBlock:^() {
[OWSStorage incrementDatabaseExtensionVersionSuffix];
}]];
return [OWSTableSection sectionWithTitle:self.name items:items];
}

@ -203,7 +203,11 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
options.allowedCollections =
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[OWSMessageContentJob collection]]];
return [[YapDatabaseAutoView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options];
return [[YapDatabaseAutoView alloc]
initWithGrouping:grouping
sorting:sorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]
options:options];
}

@ -185,7 +185,10 @@ static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_mess
dict[OWSDisappearingMessageFinderThreadIdColumn] = message.uniqueThreadId;
}];
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];
return [[YapDatabaseSecondaryIndex alloc]
initWithSetup:setup
handler:handler
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]];
}
#ifdef DEBUG

@ -114,7 +114,10 @@ static NSString *const OWSFailedAttachmentDownloadsJobAttachmentStateIndex = @"i
dict[OWSFailedAttachmentDownloadsJobAttachmentStateColumn] = @(attachment.state);
}];
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];
return [[YapDatabaseSecondaryIndex alloc]
initWithSetup:setup
handler:handler
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]];
}
#ifdef DEBUG

@ -124,7 +124,10 @@ static NSString *const OWSFailedMessagesJobMessageStateIndex = @"index_outoing_m
dict[OWSFailedMessagesJobMessageStateColumn] = @(message.messageState);
}];
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];
return [[YapDatabaseSecondaryIndex alloc]
initWithSetup:setup
handler:handler
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]];
}
#ifdef DEBUG

@ -183,7 +183,11 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
options.allowedCollections =
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[OWSMessageDecryptJob collection]]];
return [[YapDatabaseAutoView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options];
return [[YapDatabaseAutoView alloc]
initWithGrouping:grouping
sorting:sorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]
options:options];
}
+ (void)registerLegacyClasses

@ -89,7 +89,10 @@ NSString *const OWSIncomingMessageFinderColumnSourceDeviceId = @"OWSIncomingMess
YapDatabaseSecondaryIndexHandler *handler = [YapDatabaseSecondaryIndexHandler withObjectBlock:block];
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];
return [[YapDatabaseSecondaryIndex alloc]
initWithSetup:setup
handler:handler
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]];
}
+ (NSString *)databaseExtensionName

@ -163,8 +163,12 @@ static NSString *const OWSMediaGalleryFinderExtensionName = @"OWSMediaGalleryFin
YapDatabaseViewOptions *options = [YapDatabaseViewOptions new];
options.allowedCollections = [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:TSMessage.collection]];
return [[YapDatabaseAutoView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"1" options:options];
return [[YapDatabaseAutoView alloc]
initWithGrouping:grouping
sorting:sorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]
options:options];
}
+ (BOOL)attachmentIdShouldAppearInMediaGallery:(NSString *)attachmentId transaction:(YapDatabaseReadTransaction *)transaction

@ -139,6 +139,9 @@ void VerifyRegistrationsForStorage(OWSStorage *storage)
}
}
}];
if (hasMissingDatabaseView) {
[OWSStorage incrementDatabaseExtensionVersionSuffix];
}
}
#pragma mark -

@ -64,9 +64,12 @@ typedef void (^OWSStorageMigrationBlock)(void);
- (YapDatabaseConnection *)newDatabaseConnection;
#ifdef DEBUG
#pragma mark - Extension Registration
+ (void)incrementDatabaseExtensionVersionSuffix;
+ (NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(NSString *)versionTag;
- (BOOL)registerExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName;
#endif
- (void)asyncRegisterExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName;
- (void)asyncRegisterExtension:(YapDatabaseExtension *)extension
@ -75,6 +78,8 @@ typedef void (^OWSStorageMigrationBlock)(void);
- (nullable id)registeredExtension:(NSString *)extensionName;
#pragma mark -
- (unsigned long long)databaseFileSize;
- (unsigned long long)databaseWALFileSize;
- (unsigned long long)databaseSHMFileSize;

@ -6,6 +6,7 @@
#import "AppContext.h"
#import "NSData+Base64.h"
#import "NSNotificationCenter+OWS.h"
#import "NSUserDefaults+OWS.h"
#import "OWSBackgroundTask.h"
#import "OWSFileSystem.h"
#import "OWSPrimaryStorage.h"
@ -15,6 +16,8 @@
#import <SAMKeychain/SAMKeychain.h>
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseCryptoUtils.h>
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
#import <YapDatabase/YapDatabaseView.h>
NS_ASSUME_NONNULL_BEGIN
@ -36,6 +39,8 @@ const NSUInteger kDatabasePasswordLength = 30;
typedef NSData *_Nullable (^LoadDatabaseMetadataBlock)(NSError **_Nullable);
typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
NSString *const kNSUserDefaults_DatabaseExtensionVersionSuffix = @"kNSUserDefaults_DatabaseExtensionVersionSuffix";
#pragma mark -
@interface YapDatabaseConnection ()
@ -461,6 +466,43 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
return dbConnection;
}
#pragma mark - Extension Registration
+ (void)incrementDatabaseExtensionVersionSuffix
{
DDLogError(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
OWSAssert(appUserDefaults);
NSNumber *_Nullable suffix = [appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionSuffix];
[appUserDefaults setValue:@(suffix.intValue + 1) forKey:kNSUserDefaults_DatabaseExtensionVersionSuffix];
[appUserDefaults synchronize];
}
+ (nullable NSString *)databaseExtensionVersionSuffix
{
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
OWSAssert(appUserDefaults);
NSNumber *_Nullable suffix = [appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionSuffix];
if (!suffix) {
return nil;
}
return [NSString stringWithFormat:@".%@", suffix];
}
+ (NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(NSString *)versionTag
{
OWSAssertIsOnMainThread();
NSString *_Nullable suffix = [self databaseExtensionVersionSuffix];
if (suffix) {
NSString *result = [versionTag stringByAppendingString:suffix];
DDLogWarn(@"%@ database extension version: %@ + %@ -> %@", self.logTag, versionTag, suffix, result);
return result;
}
return versionTag;
}
- (BOOL)registerExtension:(YapDatabaseExtension *)extension withName:(NSString *)extensionName
{
return [self.database registerExtension:extension withName:extensionName];
@ -476,6 +518,24 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
withName:(NSString *)extensionName
completion:(nullable dispatch_block_t)completion
{
if ([extension isKindOfClass:[YapDatabaseView class]]) {
YapDatabaseView *databaseView = (YapDatabaseView *)extension;
NSString *_Nullable databaseExtensionVersionSuffix = [OWSStorage databaseExtensionVersionSuffix];
if (databaseExtensionVersionSuffix) {
OWSAssert([databaseView.versionTag hasSuffix:databaseExtensionVersionSuffix]);
}
} else if ([extension isKindOfClass:[YapDatabaseSecondaryIndex class]]) {
YapDatabaseSecondaryIndex *secondaryIndex = (YapDatabaseSecondaryIndex *)extension;
NSString *_Nullable databaseExtensionVersionSuffix = [OWSStorage databaseExtensionVersionSuffix];
if (databaseExtensionVersionSuffix) {
OWSAssert([secondaryIndex.versionTag hasSuffix:databaseExtensionVersionSuffix]);
}
} else {
OWSProdLogAndFail(@"%@ Unknown extension type: %@", self.logTag, [extension class]);
}
[self.database asyncRegisterExtension:extension
withName:extensionName
completionBlock:^(BOOL ready) {

@ -3,6 +3,7 @@
//
#import "TSDatabaseSecondaryIndexes.h"
#import "OWSStorage.h"
#import "TSInteraction.h"
#define TSTimeStampSQLiteIndex @"messagesTimeStamp"
@ -25,7 +26,10 @@
YapDatabaseSecondaryIndexHandler *handler = [YapDatabaseSecondaryIndexHandler withObjectBlock:block];
YapDatabaseSecondaryIndex *secondaryIndex = [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];
YapDatabaseSecondaryIndex *secondaryIndex = [[YapDatabaseSecondaryIndex alloc]
initWithSetup:setup
handler:handler
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"1"]];
return secondaryIndex;
}

@ -78,10 +78,11 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
options.allowedCollections =
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSInteraction collection]]];
YapDatabaseView *view = [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping
sorting:viewSorting
versionTag:version
options:options];
YapDatabaseView *view = [[YapDatabaseAutoView alloc]
initWithGrouping:viewGrouping
sorting:viewSorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:version]
options:options];
[storage asyncRegisterExtension:view withName:viewName];
}
@ -227,8 +228,11 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
options.allowedCollections =
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSThread collection]]];
YapDatabaseView *databaseView =
[[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options];
YapDatabaseView *databaseView = [[YapDatabaseAutoView alloc]
initWithGrouping:viewGrouping
sorting:viewSorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"3"]
options:options];
[storage asyncRegisterExtension:databaseView withName:TSThreadDatabaseViewExtensionName];
}
@ -336,8 +340,11 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
NSSet *deviceCollection = [NSSet setWithObject:[OWSDevice collection]];
options.allowedCollections = [[YapWhitelistBlacklist alloc] initWithWhitelist:deviceCollection];
YapDatabaseView *view =
[[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options];
YapDatabaseView *view = [[YapDatabaseAutoView alloc]
initWithGrouping:viewGrouping
sorting:viewSorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"3"]
options:options];
[storage asyncRegisterExtension:view withName:TSSecondaryDevicesDatabaseViewExtensionName];
}
@ -390,8 +397,11 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
options.isPersistent = YES;
options.allowedCollections =
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSAttachment collection]]];
YapDatabaseView *view =
[[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options];
YapDatabaseView *view = [[YapDatabaseAutoView alloc]
initWithGrouping:viewGrouping
sorting:viewSorting
versionTag:[OWSStorage appendSuffixToDatabaseExtensionVersionIfNecessary:@"3"]
options:options];
[storage asyncRegisterExtension:view
withName:TSLazyRestoreAttachmentsDatabaseViewExtensionName
completion:completion];

Loading…
Cancel
Save