diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 19a99d0c1..75c407f46 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -165,6 +165,8 @@ 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496744E2076ACCE00080B5F /* LongTextViewController.swift */; }; 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; }; 34A910601FFEB114000C4745 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A9105F1FFEB114000C4745 /* OWSBackup.m */; }; + 34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */; }; + 34ABB2C52090C59700C727A6 /* OWSResaveCollectionDBMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */; }; 34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; }; 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */; }; 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */; }; @@ -760,6 +762,8 @@ 34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = ""; }; 34A9105E1FFEB113000C4745 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = ""; }; 34A9105F1FFEB114000C4745 /* OWSBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackup.m; sourceTree = ""; }; + 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSResaveCollectionDBMigration.m; sourceTree = ""; }; + 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSResaveCollectionDBMigration.h; sourceTree = ""; }; 34B0796B1FCF46B000E248C2 /* MainAppContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainAppContext.m; sourceTree = ""; }; 34B0796C1FCF46B000E248C2 /* MainAppContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainAppContext.h; sourceTree = ""; }; 34B0796E1FD07B1E00E248C2 /* SignalShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SignalShareExtension.entitlements; sourceTree = ""; }; @@ -1535,6 +1539,8 @@ 346129941FD1E30000532771 /* OWSDatabaseMigration.m */, 346129E51FD5C0C600532771 /* OWSDatabaseMigrationRunner.h */, 346129E41FD5C0C600532771 /* OWSDatabaseMigrationRunner.m */, + 34ABB2C32090C59700C727A6 /* OWSResaveCollectionDBMigration.h */, + 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */, ); path = migrations; sourceTree = ""; @@ -2357,6 +2363,7 @@ 346129E71FD5C0C600532771 /* OWSDatabaseMigrationRunner.h in Headers */, 344D6CEA20069E070042AF96 /* SelectRecipientViewController.h in Headers */, 34480B521FD0A7A400BC14EF /* OWSLogger.h in Headers */, + 34ABB2C52090C59700C727A6 /* OWSResaveCollectionDBMigration.h in Headers */, 459B775D207BA4810071D0AB /* OWSQuotedReplyModel.h in Headers */, 34612A001FD5F31400532771 /* OWS105AttachmentFilePaths.h in Headers */, 346129F61FD5F31400532771 /* OWS103EnableVideoCalling.h in Headers */, @@ -3097,6 +3104,7 @@ 346129721FD1D74C00532771 /* SignalKeyingStorage.m in Sources */, 34480B561FD0A7A400BC14EF /* DebugLogger.m in Sources */, 459B775C207BA46C0071D0AB /* OWSQuotedReplyModel.m in Sources */, + 34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */, 4551DB5A205C562300C8AE75 /* Collection+OWS.swift in Sources */, 3461293C1FD1D46A00532771 /* OWSMath.m in Sources */, 451F8A391FD711D6005CB9DA /* ContactsViewHelper.m in Sources */, @@ -3433,7 +3441,11 @@ "DEBUG=1", "$(inherited)", ); - "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "DEBUG=1 $(inherited) SSK_BUILDING_FOR_TESTS=1"; + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = ( + "DEBUG=1", + "$(inherited)", + "SSK_BUILDING_FOR_TESTS=1", + ); GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; diff --git a/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.h b/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.h index b50e89d0c..6b6b23c5e 100644 --- a/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.h +++ b/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.h @@ -2,11 +2,11 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSDatabaseMigration.h" +#import "OWSResaveCollectionDBMigration.h" NS_ASSUME_NONNULL_BEGIN -@interface OWS109OutgoingMessageState : OWSDatabaseMigration +@interface OWS109OutgoingMessageState : OWSResaveCollectionDBMigration @end diff --git a/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.m b/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.m index 6eef8fe8d..3d2e47a67 100644 --- a/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.m +++ b/SignalMessaging/environment/migrations/OWS109OutgoingMessageState.m @@ -24,55 +24,20 @@ static NSString *const OWS109OutgoingMessageStateMigrationId = @"109"; { OWSAssert(completion); - OWSDatabaseConnection *dbConnection = (OWSDatabaseConnection *)self.primaryStorage.newDatabaseConnection; - - [dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - NSMutableArray *messageIds = - [[transaction allKeysInCollection:TSOutgoingMessage.collection] mutableCopy]; - DDLogInfo(@"%@ Migrating %zd outgoing messages.", self.logTag, messageIds.count); - - [self processBatch:messageIds - dbConnection:dbConnection - completion:^{ - DDLogInfo(@"Completed migration %@", self.uniqueId); - - [self save]; - - completion(); - }]; - }]; -} -- (void)processBatch:(NSMutableArray *)messageIds - dbConnection:(OWSDatabaseConnection *)dbConnection - completion:(OWSDatabaseMigrationCompletion)completion -{ - OWSAssert(dbConnection); - OWSAssert(completion); + OWSDatabaseConnection *dbConnection = (OWSDatabaseConnection *)self.primaryStorage.newDatabaseConnection; - DDLogVerbose(@"%@ %s: %zd", self.logTag, __PRETTY_FUNCTION__, messageIds.count); + [self resaveDBCollection:TSOutgoingMessage.collection + filter:^(id entity) { + return [entity isKindOfClass:[TSOutgoingMessage class]]; + } + dbConnection:dbConnection + completion:^{ + DDLogInfo(@"Completed migration %@", self.uniqueId); - if (messageIds.count < 1) { - completion(); - return; - } + [self save]; - [dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - const int kBatchSize = 1000; - for (int i = 0; i < kBatchSize && messageIds.count > 0; i++) { - NSString *messageId = [messageIds lastObject]; - [messageIds removeLastObject]; - id message = [transaction objectForKey:messageId inCollection:TSOutgoingMessage.collection]; - if (![message isKindOfClass:[TSOutgoingMessage class]]) { - continue; - } - TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)message; - [outgoingMessage saveWithTransaction:transaction]; - } - } - completionBlock:^{ - // Process the next batch. - [self processBatch:messageIds dbConnection:dbConnection completion:completion]; + completion(); }]; } diff --git a/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.h b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.h new file mode 100644 index 000000000..8f793dfb3 --- /dev/null +++ b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWSDatabaseMigration.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef BOOL (^DBRecordFilterBlock)(id record); + +@class YapDatabaseConnection; + +// Base class for migrations that resave all or a subset of +// records in a database collection. +@interface OWSResaveCollectionDBMigration : OWSDatabaseMigration + +- (void)resaveDBCollection:(NSString *)collection + filter:(nullable DBRecordFilterBlock)filter + dbConnection:(YapDatabaseConnection *)dbConnection + completion:(OWSDatabaseMigrationCompletion)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m new file mode 100644 index 000000000..f38e67812 --- /dev/null +++ b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m @@ -0,0 +1,80 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWSResaveCollectionDBMigration.h" +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation OWSResaveCollectionDBMigration + +- (void)resaveDBCollection:(NSString *)collection + filter:(nullable DBRecordFilterBlock)filter + dbConnection:(YapDatabaseConnection *)dbConnection + completion:(OWSDatabaseMigrationCompletion)completion +{ + OWSAssert(collection.length > 0); + OWSAssert(dbConnection); + OWSAssert(completion); + + NSMutableArray *recordIds = [NSMutableArray new]; + [dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [recordIds addObjectsFromArray:[transaction allKeysInCollection:collection]]; + DDLogInfo(@"%@ Migrating %zd records from: %@.", self.logTag, recordIds.count, collection); + } + completionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + completionBlock:^{ + [self resaveBatch:recordIds + collection:collection + filter:filter + dbConnection:dbConnection + completion:completion]; + }]; +} + +- (void)resaveBatch:(NSMutableArray *)recordIds + collection:(NSString *)collection + filter:(nullable DBRecordFilterBlock)filter + dbConnection:(YapDatabaseConnection *)dbConnection + completion:(OWSDatabaseMigrationCompletion)completion +{ + OWSAssert(recordIds); + OWSAssert(collection.length > 0); + OWSAssert(dbConnection); + OWSAssert(completion); + + DDLogVerbose(@"%@ %s: %zd", self.logTag, __PRETTY_FUNCTION__, recordIds.count); + + if (recordIds.count < 1) { + completion(); + return; + } + + [dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + const int kBatchSize = 1000; + for (int i = 0; i < kBatchSize && recordIds.count > 0; i++) { + NSString *messageId = [recordIds lastObject]; + [recordIds removeLastObject]; + id record = [transaction objectForKey:messageId inCollection:collection]; + if (filter && !filter(record)) { + continue; + } + TSYapDatabaseObject *entity = (TSYapDatabaseObject *)record; + [entity saveWithTransaction:transaction]; + } + } + completionBlock:^{ + // Process the next batch. + [self resaveBatch:recordIds + collection:collection + filter:filter + dbConnection:dbConnection + completion:completion]; + }]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m index e3d78babe..4b0bf8b86 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m @@ -4,6 +4,7 @@ #import "OWSOutgoingSentMessageTranscript.h" #import "OWSSignalServiceProtos.pb.h" +#import "TSAccountManager.h" #import "TSOutgoingMessage.h" #import "TSThread.h" @@ -49,8 +50,12 @@ NS_ASSUME_NONNULL_BEGIN OWSSignalServiceProtosSyncMessageSentBuilder *sentBuilder = [OWSSignalServiceProtosSyncMessageSentBuilder new]; [sentBuilder setTimestamp:self.message.timestamp]; - [sentBuilder setDestination:self.recipientIdentifierForMessage]; - [sentBuilder setMessage:[self.message buildDataMessage:self.recipientIdentifierForMessage]]; + + NSString *_Nullable localNumber = [TSAccountManager localNumber]; + OWSAssert(localNumber.length > 0); + OWSAssert([localNumber isEqualToString:self.message.thread.contactIdentifier]); + [sentBuilder setDestination:localNumber]; + [sentBuilder setMessage:[self.message buildDataMessage:localNumber]]; [sentBuilder setExpirationStartTimestamp:self.message.timestamp]; [syncMessageBuilder setSentBuilder:sentBuilder]; @@ -58,12 +63,6 @@ NS_ASSUME_NONNULL_BEGIN return syncMessageBuilder; } -// Note that this will return nil for group messages. -- (nullable NSString *)recipientIdentifierForMessage -{ - return self.message.thread.contactIdentifier; -} - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index b277825e9..deb82e03e 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -356,8 +356,6 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec if (!self.isExpiringMessage) { return NO; - } else if (self.recipientStateMap.count < 1) { - return YES; } else { return self.hasSentToAnyRecipient; }