From e096406e56194f55ce3f49f7ab383efe3c9258e6 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 7 Nov 2018 13:52:09 -0600 Subject: [PATCH] migrate existing attachments to album-compatible gallery schema --- Signal.xcodeproj/project.pbxproj | 4 ++ .../MediaGalleryViewController.swift | 2 +- .../OWS113MultiAttachmentMediaMessages.swift | 72 +++++++++++++++++++ .../migrations/OWSDatabaseMigrationRunner.m | 1 + .../src/Messages/Attachments/TSAttachment.h | 5 ++ .../src/Messages/Attachments/TSAttachment.m | 5 ++ 6 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 3aa8448ec..e85b8eae9 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -444,6 +444,7 @@ 4C4BC6C32102D697004040C9 /* ContactDiscoveryOperationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4BC6C22102D697004040C9 /* ContactDiscoveryOperationTest.swift */; }; 4C63CC00210A620B003AE45C /* SignalTSan.supp in Resources */ = {isa = PBXBuildFile; fileRef = 4C63CBFF210A620B003AE45C /* SignalTSan.supp */; }; 4C6F527C20FFE8400097DEEE /* SignalUBSan.supp in Resources */ = {isa = PBXBuildFile; fileRef = 4C6F527B20FFE8400097DEEE /* SignalUBSan.supp */; }; + 4C7537892193779700DF5E37 /* OWS113MultiAttachmentMediaMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7537882193779700DF5E37 /* OWS113MultiAttachmentMediaMessages.swift */; }; 4C858A52212DC5E1001B45D3 /* UIImage+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C858A51212DC5E1001B45D3 /* UIImage+OWS.swift */; }; 4C948FF72146EB4800349F0D /* BlockListCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C948FF62146EB4800349F0D /* BlockListCache.swift */; }; 4C9CA25D217E676900607C63 /* ZXingObjC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C9CA25C217E676900607C63 /* ZXingObjC.framework */; }; @@ -1142,6 +1143,7 @@ 4C4BC6C22102D697004040C9 /* ContactDiscoveryOperationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ContactDiscoveryOperationTest.swift; path = contact/ContactDiscoveryOperationTest.swift; sourceTree = ""; }; 4C63CBFF210A620B003AE45C /* SignalTSan.supp */ = {isa = PBXFileReference; lastKnownFileType = text; path = SignalTSan.supp; sourceTree = ""; }; 4C6F527B20FFE8400097DEEE /* SignalUBSan.supp */ = {isa = PBXFileReference; lastKnownFileType = text; path = SignalUBSan.supp; sourceTree = ""; }; + 4C7537882193779700DF5E37 /* OWS113MultiAttachmentMediaMessages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWS113MultiAttachmentMediaMessages.swift; sourceTree = ""; }; 4C858A51212DC5E1001B45D3 /* UIImage+OWS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+OWS.swift"; sourceTree = ""; }; 4C948FF62146EB4800349F0D /* BlockListCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockListCache.swift; sourceTree = ""; }; 4C9CA25C217E676900607C63 /* ZXingObjC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZXingObjC.framework; path = ThirdParty/Carthage/Build/iOS/ZXingObjC.framework; sourceTree = ""; }; @@ -1639,6 +1641,7 @@ 34D5872D208E2C4100D2255A /* OWS109OutgoingMessageState.m */, 349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */, 34B6A908218B8824007C4606 /* OWS112TypingIndicatorsMigration.swift */, + 4C7537882193779700DF5E37 /* OWS113MultiAttachmentMediaMessages.swift */, 346129931FD1E30000532771 /* OWSDatabaseMigration.h */, 346129941FD1E30000532771 /* OWSDatabaseMigration.m */, 346129E51FD5C0C600532771 /* OWSDatabaseMigrationRunner.h */, @@ -3267,6 +3270,7 @@ 34AC0A15211B39EA00997B47 /* ContactsViewHelper.m in Sources */, 346129FF1FD5F31400532771 /* OWS103EnableVideoCalling.m in Sources */, 346129E31FD5C0BE00532771 /* VersionMigrations.m in Sources */, + 4C7537892193779700DF5E37 /* OWS113MultiAttachmentMediaMessages.swift in Sources */, 34AC0A16211B39EA00997B47 /* OWSNavigationBar.swift in Sources */, 34AC0A1A211B39EA00997B47 /* CommonStrings.swift in Sources */, 34AC0A19211B39EA00997B47 /* OWSAlerts.swift in Sources */, diff --git a/Signal/src/ViewControllers/MediaGalleryViewController.swift b/Signal/src/ViewControllers/MediaGalleryViewController.swift index a831392ff..09dd3ce7e 100644 --- a/Signal/src/ViewControllers/MediaGalleryViewController.swift +++ b/Signal/src/ViewControllers/MediaGalleryViewController.swift @@ -640,7 +640,7 @@ class MediaGallery: NSObject, MediaGalleryDataSource, MediaTileViewControllerDel } guard let message = attachmentStream.fetchAlbumMessage(with: transaction) else { - owsFailDebug("attachment was unexpectedly empty") + owsFailDebug("message was unexpectedly nil") return nil } diff --git a/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift b/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift new file mode 100644 index 000000000..666e999d4 --- /dev/null +++ b/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift @@ -0,0 +1,72 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +import Foundation +import SignalServiceKit + +@objc +public class OWS113MultiAttachmentMediaMessages: OWSDatabaseMigration { + + // MARK: - Dependencies + + // MARK: - + + // Increment a similar constant for each migration. + @objc + class func migrationId() -> String { + return "113" + } + + override public func runUp(completion: @escaping OWSDatabaseMigrationCompletion) { + Logger.debug("") + BenchAsync(title: "\(self.logTag)") { (benchCompletion) in + self.doMigrationAsync(completion: { + benchCompletion() + completion() + }) + } + } + + private func doMigrationAsync(completion : @escaping OWSDatabaseMigrationCompletion) { + DispatchQueue.global().async { + var legacyAttachments: [(attachmentId: String, messageId: String)] = [] + + self.dbReadWriteConnection().read { transaction in + TSMessage.enumerateCollectionObjects(with: transaction) { object, _ in + autoreleasepool { + guard let message: TSMessage = object as? TSMessage else { + Logger.debug("ignoring message with type: \(object)") + return + } + + guard let messageId = message.uniqueId else { + owsFailDebug("messageId was unexpectedly nil") + return + } + + for attachmentId in message.attachmentIds { + legacyAttachments.append((attachmentId: attachmentId as! String, messageId: messageId)) + } + } + } + } + self.dbReadWriteConnection().readWrite { transaction in + for (attachmentId, messageId) in legacyAttachments { + autoreleasepool { + guard let attachment = TSAttachment.fetch(uniqueId: attachmentId, transaction: transaction) else { + Logger.warn("missing attachment for messageId: \(messageId)") + return + } + + attachment.migrateAlbumMessageId(messageId) + attachment.save(with: transaction) + } + } + self.save(with: transaction) + } + + completion() + } + } +} diff --git a/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m b/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m index a2ea1950b..4de648195 100644 --- a/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m +++ b/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m @@ -47,6 +47,7 @@ NS_ASSUME_NONNULL_BEGIN [[OWS109OutgoingMessageState alloc] initWithPrimaryStorage:primaryStorage], [[OWS111UDAttributesMigration alloc] initWithPrimaryStorage:primaryStorage], [[OWS112TypingIndicatorsMigration alloc] initWithPrimaryStorage:primaryStorage], + [[OWS113MultiAttachmentMediaMessages alloc] initWithPrimaryStorage:primaryStorage], ]; } diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachment.h b/SignalServiceKit/src/Messages/Attachments/TSAttachment.h index dbbbeee70..302fd8417 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachment.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachment.h @@ -45,6 +45,11 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) { @property (nonatomic, readonly, nullable) NSString *albumMessageId; - (nullable TSMessage *)fetchAlbumMessageWithTransaction:(YapDatabaseReadTransaction *)transaction; +// `migrateAlbumMessageId` is only used in the migration to the new multi-attachment message scheme, +// and shouldn't be used as a general purpose setter. Instead, `albumMessageId` should be passed as +// an initializer param. +- (void)migrateAlbumMessageId:(NSString *)albumMesssageId; + #pragma mark - // This constructor is used for new instances of TSAttachmentPointer, diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachment.m b/SignalServiceKit/src/Messages/Attachments/TSAttachment.m index 7a05bfa7d..badbcdae8 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachment.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachment.m @@ -254,6 +254,11 @@ NSUInteger const TSAttachmentSchemaVersion = 4; return [TSMessage fetchObjectWithUniqueID:self.albumMessageId transaction:transaction]; } +- (void)migrateAlbumMessageId:(NSString *)albumMesssageId +{ + _albumMessageId = albumMesssageId; +} + @end NS_ASSUME_NONNULL_END