From e26a8e1bd4f6fc8713c435cae0cdb22f1433cb60 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 21 Jun 2019 15:21:57 -0400 Subject: [PATCH 1/4] Convert attachments to be any-only. --- .../xcshareddata/xcschemes/Signal.xcscheme | 6 +- Signal/src/AppDelegate.m | 9 +- .../Cells/OWSMessageStickerView.m | 2 +- .../ConversationViewController.m | 16 +- .../ConversationView/ConversationViewItem.m | 189 ++++++++---------- .../DebugUI/DebugUIDiskUsage.m | 34 ++-- .../ViewControllers/DebugUI/DebugUIMessages.m | 8 +- .../MessageDetailViewController.swift | 2 +- Signal/src/util/Backup/OWSBackupImportJob.m | 9 +- .../util/Backup/OWSBackupLazyRestore.swift | 10 +- .../ConversationViewItemTest.m | 105 ++++++++-- .../SharingThreadPickerViewController.m | 2 +- .../ViewModels/ContactShareViewModel.swift | 4 +- .../ViewModels/OWSQuotedReplyModel.m | 10 +- .../migrations/OWS105AttachmentFilePaths.m | 5 +- .../OWS113MultiAttachmentMediaMessages.swift | 8 +- SignalMessaging/utils/OWSOrphanDataCleaner.m | 4 +- SignalMessaging/utils/ThreadUtil.m | 2 +- .../src/Devices/OWSRecordTranscriptJob.m | 14 +- .../Attachments/OWSAttachmentDownloads.h | 7 +- .../Attachments/OWSAttachmentDownloads.m | 106 ++++++---- .../src/Messages/Attachments/TSAttachment.h | 37 ++++ .../Attachments/TSAttachmentPointer.h | 3 +- .../Attachments/TSAttachmentPointer.m | 22 +- .../Messages/Attachments/TSAttachmentStream.h | 1 - .../Messages/Attachments/TSAttachmentStream.m | 105 ++++++---- .../OWSIncomingSentMessageTranscript.m | 9 +- .../src/Messages/Interactions/OWSContact.h | 15 +- .../src/Messages/Interactions/OWSContact.m | 18 +- .../Interactions/OWSLinkPreview.swift | 12 +- .../Messages/Interactions/TSIncomingMessage.m | 3 +- .../src/Messages/Interactions/TSMessage.h | 10 +- .../src/Messages/Interactions/TSMessage.m | 40 ++-- .../Messages/Interactions/TSOutgoingMessage.m | 15 +- .../Messages/Interactions/TSQuotedMessage.h | 6 +- .../Messages/Interactions/TSQuotedMessage.m | 38 ++-- .../OWSFailedAttachmentDownloadsJob.m | 21 +- .../src/Messages/OWSMessageManager.m | 22 +- .../src/Messages/OWSMessageSender.m | 25 ++- .../Messages/Stickers/MessageSticker.swift | 9 - .../src/Network/API/OWSUploadOperation.m | 17 +- .../Database/Records/InteractionFinder.swift | 1 + .../src/Storage/Database/SDSModel.swift | 2 +- SignalServiceKit/src/Storage/OWSStorage.m | 4 +- .../src/Storage/TSYapDatabaseObject.h | 26 +++ .../src/Storage/TSYapDatabaseObject.m | 100 +++++++++ .../tests/Messages/OWSLinkPreviewTest.swift | 8 +- 47 files changed, 720 insertions(+), 401 deletions(-) diff --git a/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme b/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme index a274fca292..00a258e9d1 100644 --- a/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme +++ b/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> @@ -56,7 +56,7 @@ skipped = "NO"> @@ -66,7 +66,7 @@ skipped = "NO"> diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index f19cf37d3a..a442a0e278 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -1336,10 +1336,11 @@ static NSTimeInterval launchStartedAt; if (!Environment.shared.preferences.hasGeneratedThumbnails) { [self.primaryStorage.newDatabaseConnection - asyncReadWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - [TSAttachmentStream enumerateCollectionObjectsUsingBlock:^(id _Nonnull obj, BOOL *_Nonnull stop){ - // no-op. It's sufficient to initWithCoder: each object. - }]; + asyncReadWithBlock:^(YapDatabaseReadTransaction *transaction) { + [TSAttachment anyEnumerateWithTransaction:transaction.asAnyRead + block:^(TSAttachment *attachment, BOOL *stop){ + // no-op. It's sufficient to initWithCoder: each object. + }]; } completionBlock:^{ [Environment.shared.preferences setHasGeneratedThumbnails:YES]; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageStickerView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageStickerView.m index 5a119abfe4..2023a82d5b 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageStickerView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageStickerView.m @@ -497,7 +497,7 @@ NS_ASSUME_NONNULL_BEGIN [self.primaryStorage.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [self.attachmentDownloads downloadAllAttachmentsForMessage:message - transaction:transaction + transaction:transaction.asAnyRead success:^(NSArray *_Nonnull attachmentStreams) { // Do nothing. } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index f132f6f8aa..7d8e343670 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -1846,7 +1846,7 @@ typedef enum : NSUInteger { { OWSAssert(message); - [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [self.databaseStorage uiReadWithBlock:^(SDSAnyReadTransaction *transaction) { [self.attachmentDownloads downloadAllAttachmentsForMessage:message transaction:transaction success:^(NSArray *attachmentStreams) { @@ -3086,15 +3086,15 @@ typedef enum : NSUInteger { BOOL didAddToProfileWhitelist = [ThreadUtil addThreadToProfileWhitelistIfEmptyContactThread:self.thread]; - [self.editingDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self.databaseStorage + asyncWriteWithBlock:^(SDSAnyWriteTransaction *transaction) { // TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending // preparation rather than duplicated here and in the SAE if (contactShare.avatarImage) { [contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction]; } } - completionBlock:^{ + completion:^{ TSOutgoingMessage *message = [ThreadUtil enqueueMessageWithContactShare:contactShare.dbRecord inThread:self.thread]; [self messageWasSent:message]; @@ -3611,8 +3611,8 @@ typedef enum : NSUInteger { __block TSThread *thread = _thread; __block NSString *currentDraft = [self.inputToolbar messageText]; - [self.editingDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [thread updateWithDraft:currentDraft transaction:transaction.asAnyWrite]; + [self.databaseStorage asyncWriteWithBlock:^(SDSAnyWriteTransaction *transaction) { + [thread updateWithDraft:currentDraft transaction:transaction]; }]; } } @@ -4362,8 +4362,8 @@ typedef enum : NSUInteger { [BenchManager completeEventWithEventId:@"fromSendUntil_toggleDefaultKeyboard"]; }); - [self.editingDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self.thread updateWithDraft:@"" transaction:transaction.asAnyWrite]; + [self.databaseStorage asyncWriteWithBlock:^(SDSAnyWriteTransaction *transaction) { + [self.thread updateWithDraft:@"" transaction:transaction]; }]; if (didAddToProfileWhitelist) { diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m index 145f088a3d..102fbf2fd9 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m @@ -738,118 +738,100 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) } } - if (transaction.transitional_yapReadTransaction != nil) { - TSAttachment *_Nullable oversizeTextAttachment = - [message oversizeTextAttachmentWithTransaction:transaction.transitional_yapReadTransaction]; - if ([oversizeTextAttachment isKindOfClass:[TSAttachmentStream class]]) { - TSAttachmentStream *oversizeTextAttachmentStream = (TSAttachmentStream *)oversizeTextAttachment; - self.displayableBodyText = [self displayableBodyTextForOversizeTextAttachment:oversizeTextAttachmentStream - interactionId:message.uniqueId]; - } else if ([oversizeTextAttachment isKindOfClass:[TSAttachmentPointer class]]) { - TSAttachmentPointer *oversizeTextAttachmentPointer = (TSAttachmentPointer *)oversizeTextAttachment; - // TODO: Handle backup restore. - self.messageCellType = OWSMessageCellType_OversizeTextDownloading; - self.attachmentPointer = (TSAttachmentPointer *)oversizeTextAttachmentPointer; - return; - } else { - NSString *_Nullable bodyText = [message bodyTextWithTransaction:transaction]; - if (bodyText) { - self.displayableBodyText = [self displayableBodyTextForText:bodyText interactionId:message.uniqueId]; - } - } + TSAttachment *_Nullable oversizeTextAttachment = [message oversizeTextAttachmentWithTransaction:transaction]; + if ([oversizeTextAttachment isKindOfClass:[TSAttachmentStream class]]) { + TSAttachmentStream *oversizeTextAttachmentStream = (TSAttachmentStream *)oversizeTextAttachment; + self.displayableBodyText = [self displayableBodyTextForOversizeTextAttachment:oversizeTextAttachmentStream + interactionId:message.uniqueId]; + } else if ([oversizeTextAttachment isKindOfClass:[TSAttachmentPointer class]]) { + TSAttachmentPointer *oversizeTextAttachmentPointer = (TSAttachmentPointer *)oversizeTextAttachment; + // TODO: Handle backup restore. + self.messageCellType = OWSMessageCellType_OversizeTextDownloading; + self.attachmentPointer = (TSAttachmentPointer *)oversizeTextAttachmentPointer; + return; } else { - // GRDB TODO: accomodate long text NSString *_Nullable bodyText = [message bodyTextWithTransaction:transaction]; if (bodyText) { self.displayableBodyText = [self displayableBodyTextForText:bodyText interactionId:message.uniqueId]; } } - if (transaction.transitional_yapReadTransaction != nil) { - NSArray *mediaAttachments = - [message mediaAttachmentsWithTransaction:transaction.transitional_yapReadTransaction]; - NSArray *mediaAlbumItems = [self albumItemsForMediaAttachments:mediaAttachments]; - if (mediaAlbumItems.count > 0) { - if (mediaAlbumItems.count == 1) { - ConversationMediaAlbumItem *mediaAlbumItem = mediaAlbumItems.firstObject; - if (mediaAlbumItem.attachmentStream && !mediaAlbumItem.attachmentStream.isValidVisualMedia) { - OWSLogWarn(@"Treating invalid media as generic attachment."); - self.messageCellType = OWSMessageCellType_GenericAttachment; - return; - } + NSArray *mediaAttachments = [message mediaAttachmentsWithTransaction:transaction]; + NSArray *mediaAlbumItems = [self albumItemsForMediaAttachments:mediaAttachments]; + if (mediaAlbumItems.count > 0) { + if (mediaAlbumItems.count == 1) { + ConversationMediaAlbumItem *mediaAlbumItem = mediaAlbumItems.firstObject; + if (mediaAlbumItem.attachmentStream && !mediaAlbumItem.attachmentStream.isValidVisualMedia) { + OWSLogWarn(@"Treating invalid media as generic attachment."); + self.messageCellType = OWSMessageCellType_GenericAttachment; + return; } - - self.mediaAlbumItems = mediaAlbumItems; - self.messageCellType = OWSMessageCellType_MediaMessage; - return; } - // Only media galleries should have more than one attachment. - OWSAssertDebug(mediaAttachments.count <= 1); + self.mediaAlbumItems = mediaAlbumItems; + self.messageCellType = OWSMessageCellType_MediaMessage; + return; + } - TSAttachment *_Nullable mediaAttachment = mediaAttachments.firstObject; - if (mediaAttachment) { - if ([mediaAttachment isKindOfClass:[TSAttachmentStream class]]) { - self.attachmentStream = (TSAttachmentStream *)mediaAttachment; - if ([self.attachmentStream isAudio]) { - CGFloat audioDurationSeconds = [self.attachmentStream audioDurationSeconds]; - if (audioDurationSeconds > 0) { - self.audioDurationSeconds = audioDurationSeconds; - self.messageCellType = OWSMessageCellType_Audio; - } else { - self.messageCellType = OWSMessageCellType_GenericAttachment; - } - } else if (self.messageCellType == OWSMessageCellType_Unknown) { - self.messageCellType = OWSMessageCellType_GenericAttachment; - } - } else if ([mediaAttachment isKindOfClass:[TSAttachmentPointer class]]) { - if ([mediaAttachment isAudio]) { - self.audioDurationSeconds = 0; + // Only media galleries should have more than one attachment. + OWSAssertDebug(mediaAttachments.count <= 1); + + TSAttachment *_Nullable mediaAttachment = mediaAttachments.firstObject; + if (mediaAttachment) { + if ([mediaAttachment isKindOfClass:[TSAttachmentStream class]]) { + self.attachmentStream = (TSAttachmentStream *)mediaAttachment; + if ([self.attachmentStream isAudio]) { + CGFloat audioDurationSeconds = [self.attachmentStream audioDurationSeconds]; + if (audioDurationSeconds > 0) { + self.audioDurationSeconds = audioDurationSeconds; self.messageCellType = OWSMessageCellType_Audio; } else { self.messageCellType = OWSMessageCellType_GenericAttachment; } - self.attachmentPointer = (TSAttachmentPointer *)mediaAttachment; - } else { - OWSFailDebug(@"Unknown attachment type"); + } else if (self.messageCellType == OWSMessageCellType_Unknown) { + self.messageCellType = OWSMessageCellType_GenericAttachment; } + } else if ([mediaAttachment isKindOfClass:[TSAttachmentPointer class]]) { + if ([mediaAttachment isAudio]) { + self.audioDurationSeconds = 0; + self.messageCellType = OWSMessageCellType_Audio; + } else { + self.messageCellType = OWSMessageCellType_GenericAttachment; + } + self.attachmentPointer = (TSAttachmentPointer *)mediaAttachment; + } else { + OWSFailDebug(@"Unknown attachment type"); } } if (self.hasBodyText) { if (self.messageCellType == OWSMessageCellType_Unknown) { OWSAssertDebug(message.attachmentIds.count == 0 - || (message.attachmentIds.count == 1 - && (transaction.transitional_yapReadTransaction != nil && - [message - oversizeTextAttachmentWithTransaction:transaction.transitional_yapReadTransaction] - != nil))); + || (message.attachmentIds.count == 1 && + [message oversizeTextAttachmentWithTransaction:transaction] != nil)); self.messageCellType = OWSMessageCellType_TextOnlyMessage; } OWSAssertDebug(self.displayableBodyText); } - if (transaction.transitional_yapReadTransaction != nil) { - if (self.hasBodyText && message.linkPreview) { - self.linkPreview = message.linkPreview; - if (message.linkPreview.imageAttachmentId.length > 0) { - TSAttachment *_Nullable linkPreviewAttachment = - [TSAttachment fetchObjectWithUniqueID:message.linkPreview.imageAttachmentId - transaction:transaction.transitional_yapReadTransaction]; - if (!linkPreviewAttachment) { - OWSFailDebug(@"Could not load link preview image attachment."); - } else if (!linkPreviewAttachment.isImage) { - OWSFailDebug(@"Link preview attachment isn't an image."); - } else if ([linkPreviewAttachment isKindOfClass:[TSAttachmentStream class]]) { - TSAttachmentStream *attachmentStream = (TSAttachmentStream *)linkPreviewAttachment; - if (!attachmentStream.isValidImage) { - OWSFailDebug(@"Link preview image attachment isn't valid."); - } else { - self.linkPreviewAttachment = linkPreviewAttachment; - } + if (self.hasBodyText && message.linkPreview) { + self.linkPreview = message.linkPreview; + if (message.linkPreview.imageAttachmentId.length > 0) { + TSAttachment *_Nullable linkPreviewAttachment = + [TSAttachment anyFetchWithUniqueId:message.linkPreview.imageAttachmentId transaction:transaction]; + if (!linkPreviewAttachment) { + OWSFailDebug(@"Could not load link preview image attachment."); + } else if (!linkPreviewAttachment.isImage) { + OWSFailDebug(@"Link preview attachment isn't an image."); + } else if ([linkPreviewAttachment isKindOfClass:[TSAttachmentStream class]]) { + TSAttachmentStream *attachmentStream = (TSAttachmentStream *)linkPreviewAttachment; + if (!attachmentStream.isValidImage) { + OWSFailDebug(@"Link preview image attachment isn't valid."); } else { self.linkPreviewAttachment = linkPreviewAttachment; } + } else { + self.linkPreviewAttachment = linkPreviewAttachment; } } } @@ -888,31 +870,28 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) return; } - if (transaction.transitional_yapReadTransaction) { - NSArray *mediaAttachments = - [message mediaAttachmentsWithTransaction:transaction.transitional_yapReadTransaction]; - // TODO: We currently only support single attachments for messages - // with per-message expiration. - TSAttachment *_Nullable mediaAttachment = mediaAttachments.firstObject; - if ([mediaAttachment isKindOfClass:[TSAttachmentPointer class]]) { + NSArray *mediaAttachments = [message mediaAttachmentsWithTransaction:transaction]; + // TODO: We currently only support single attachments for messages + // with per-message expiration. + TSAttachment *_Nullable mediaAttachment = mediaAttachments.firstObject; + if ([mediaAttachment isKindOfClass:[TSAttachmentPointer class]]) { + self.messageCellType = OWSMessageCellType_PerMessageExpiration; + self.attachmentPointer = (TSAttachmentPointer *)mediaAttachment; + self.perMessageExpirationState = (self.attachmentPointer.state == TSAttachmentPointerStateFailed + ? PerMessageExpirationState_IncomingFailed + : PerMessageExpirationState_IncomingDownloading); + return; + } else if ([mediaAttachment isKindOfClass:[TSAttachmentStream class]]) { + TSAttachmentStream *attachmentStream = (TSAttachmentStream *)mediaAttachment; + if (attachmentStream.isValidVisualMedia && (attachmentStream.isImage || attachmentStream.isAnimated)) { self.messageCellType = OWSMessageCellType_PerMessageExpiration; - self.attachmentPointer = (TSAttachmentPointer *)mediaAttachment; - self.perMessageExpirationState = (self.attachmentPointer.state == TSAttachmentPointerStateFailed - ? PerMessageExpirationState_IncomingFailed - : PerMessageExpirationState_IncomingDownloading); - return; - } else if ([mediaAttachment isKindOfClass:[TSAttachmentStream class]]) { - TSAttachmentStream *attachmentStream = (TSAttachmentStream *)mediaAttachment; - if (attachmentStream.isValidVisualMedia && (attachmentStream.isImage || attachmentStream.isAnimated)) { - self.messageCellType = OWSMessageCellType_PerMessageExpiration; - self.perMessageExpirationState = PerMessageExpirationState_IncomingAvailable; - self.attachmentStream = attachmentStream; - } else { - self.messageCellType = OWSMessageCellType_PerMessageExpiration; - self.perMessageExpirationState = PerMessageExpirationState_IncomingInvalidContent; - } - return; + self.perMessageExpirationState = PerMessageExpirationState_IncomingAvailable; + self.attachmentStream = attachmentStream; + } else { + self.messageCellType = OWSMessageCellType_PerMessageExpiration; + self.perMessageExpirationState = PerMessageExpirationState_IncomingInvalidContent; } + return; } OWSFailDebug(@"Invalid media for message with per-message expiration."); diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m b/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m index 05f8dd5f49..82d0089843 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "DebugUIDiskUsage.h" @@ -15,6 +15,13 @@ NS_ASSUME_NONNULL_BEGIN @implementation DebugUIDiskUsage +#pragma mark - Dependencies + ++ (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + #pragma mark - Factory Methods - (NSString *)name @@ -47,18 +54,16 @@ NS_ASSUME_NONNULL_BEGIN + (void)saveAllAttachments { - OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; - [primaryStorage.newDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { NSMutableArray *attachmentStreams = [NSMutableArray new]; - [transaction enumerateKeysAndObjectsInCollection:TSAttachmentStream.collection - usingBlock:^(NSString *key, TSAttachment *attachment, BOOL *stop) { - if (![attachment isKindOfClass:[TSAttachmentStream class]]) { - return; - } - TSAttachmentStream *attachmentStream - = (TSAttachmentStream *)attachment; - [attachmentStreams addObject:attachmentStream]; - }]; + [TSAttachment anyEnumerateWithTransaction:transaction + block:^(TSAttachment *attachment, BOOL *stop) { + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + return; + } + TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; + [attachmentStreams addObject:attachmentStream]; + }]; OWSLogInfo(@"Saving %zd attachment streams.", attachmentStreams.count); @@ -66,7 +71,10 @@ NS_ASSUME_NONNULL_BEGIN // For performance, we want to upgrade all existing attachment streams in // a single transaction. for (TSAttachmentStream *attachmentStream in attachmentStreams) { - [attachmentStream saveWithTransaction:transaction]; + [attachmentStream anyUpdateWithTransaction:transaction + block:^(TSAttachment *attachment){ + // Do nothing, rewriting is sufficient. + }]; } }]; } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 1d5bb8a725..cc4925120a 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -3135,9 +3135,7 @@ typedef OWSContact * (^OWSContactBlock)(SDSAnyWriteTransaction *transaction); UIImage *avatarImage = [OWSAvatarBuilder buildRandomAvatarWithDiameter:200]; if (transaction.transitional_yapWriteTransaction) { - [contact - saveAvatarImage:avatarImage - transaction:transaction.transitional_yapWriteTransaction]; + [contact saveAvatarImage:avatarImage transaction:transaction]; } else { OWSFailDebug(@"failure: not yet implemented for GRDB"); } @@ -3324,9 +3322,7 @@ typedef OWSContact * (^OWSContactBlock)(SDSAnyWriteTransaction *transaction); UIImage *avatarImage = [OWSAvatarBuilder buildRandomAvatarWithDiameter:200]; if (transaction.transitional_yapWriteTransaction) { - [contact - saveAvatarImage:avatarImage - transaction:transaction.transitional_yapWriteTransaction]; + [contact saveAvatarImage:avatarImage transaction:transaction]; } else { OWSFailDebug(@"failure: not yet implemented for GRDB"); } diff --git a/Signal/src/ViewControllers/MessageDetailViewController.swift b/Signal/src/ViewControllers/MessageDetailViewController.swift index b47e741748..fbd267fc5d 100644 --- a/Signal/src/ViewControllers/MessageDetailViewController.swift +++ b/Signal/src/ViewControllers/MessageDetailViewController.swift @@ -431,7 +431,7 @@ class MessageDetailViewController: OWSViewController { return nil } - guard let attachment = TSAttachment.fetch(uniqueId: attachmentId, transaction: transaction) else { + guard let attachment = TSAttachment.anyFetch(uniqueId: attachmentId, transaction: transaction.asAnyRead) else { Logger.warn("Missing attachment. Was it deleted?") return nil } diff --git a/Signal/src/util/Backup/OWSBackupImportJob.m b/Signal/src/util/Backup/OWSBackupImportJob.m index 131a735dfe..73c22ef007 100644 --- a/Signal/src/util/Backup/OWSBackupImportJob.m +++ b/Signal/src/util/Backup/OWSBackupImportJob.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWSBackupImportJob.h" @@ -409,8 +409,8 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe // Attachment-related errors are recoverable and can be ignored. continue; } - TSAttachmentPointer *_Nullable attachment = - [TSAttachmentPointer fetchObjectWithUniqueID:item.attachmentId transaction:transaction]; + TSAttachment *_Nullable attachment = + [TSAttachmentPointer anyFetchWithUniqueId:item.attachmentId transaction:transaction.asAnyRead]; if (!attachment) { OWSLogError(@"attachment to restore could not be found."); // Attachment-related errors are recoverable and can be ignored. @@ -421,7 +421,8 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe // Attachment-related errors are recoverable and can be ignored. continue; } - [attachment markForLazyRestoreWithFragment:item transaction:transaction]; + TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)attachment; + [attachmentPointer markForLazyRestoreWithFragment:item transaction:transaction.asAnyWrite]; count++; [self updateProgressWithDescription:NSLocalizedString(@"BACKUP_IMPORT_PHASE_RESTORING_FILES", @"Indicates that the backup import data is being restored.") diff --git a/Signal/src/util/Backup/OWSBackupLazyRestore.swift b/Signal/src/util/Backup/OWSBackupLazyRestore.swift index e8c1bd6e73..bb77c17a9a 100644 --- a/Signal/src/util/Backup/OWSBackupLazyRestore.swift +++ b/Signal/src/util/Backup/OWSBackupLazyRestore.swift @@ -23,6 +23,10 @@ public class BackupLazyRestore: NSObject { return TSAccountManager.sharedInstance() } + var databaseStorage: SDSDatabaseStorage { + return SSKEnvironment.shared.databaseStorage + } + // MARK: - private var isRunning = false @@ -139,7 +143,11 @@ public class BackupLazyRestore: NSObject { complete(errorCount: errorCount) return } - guard let attachmentPointer = TSAttachment.fetch(uniqueId: attachmentId) as? TSAttachmentPointer else { + var attachment: TSAttachment? + databaseStorage.read { (transaction) in + attachment = TSAttachment.anyFetch(uniqueId: attachmentId, transaction: transaction) + } + guard let attachmentPointer = attachment as? TSAttachmentPointer else { Logger.warn("could not load attachment.") // Not necessarily an error. // The attachment might have been deleted since the job began. diff --git a/Signal/test/ViewControllers/ConversationViewItemTest.m b/Signal/test/ViewControllers/ConversationViewItemTest.m index 43d5c4cb24..eef7133ec2 100644 --- a/Signal/test/ViewControllers/ConversationViewItemTest.m +++ b/Signal/test/ViewControllers/ConversationViewItemTest.m @@ -13,6 +13,65 @@ #import #import +@interface TSMessage (ConversationViewItemTest) + +@end + +#pragma mark - + +@implementation TSMessage (ConversationViewItemTest) + ++ (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + ++ (nullable TSMessage *)anyFetchWithUniqueId:(NSString *)uniqueId +{ + __block TSInteraction *_Nullable instance; + [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { + instance = [TSInteraction anyFetchWithUniqueId:uniqueId transaction:transaction]; + }]; + if (!instance) { + return nil; + } + if (![instance isKindOfClass:[TSMessage class]]) { + OWSFailDebug(@"Unexpected object type: %@", [instance class]); + return nil; + } + return (TSMessage *)instance; +} + +@end + +#pragma mark - + +@interface TSAttachment (ConversationViewItemTest) + +@end + +#pragma mark - + +@implementation TSAttachment (ConversationViewItemTest) + ++ (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + ++ (nullable TSAttachment *)anyFetchWithUniqueId:(NSString *)uniqueId +{ + __block TSAttachment *_Nullable instance; + [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { + instance = [TSAttachment anyFetchWithUniqueId:uniqueId transaction:transaction]; + }]; + return instance; +} + +@end + +#pragma mark - + @interface ConversationViewItemTest : SignalBaseTest @property TSThread *thread; @@ -20,6 +79,8 @@ @end +#pragma mark - + @implementation ConversationViewItemTest - (void)setUp @@ -112,9 +173,9 @@ { ConversationInteractionViewItem *viewItem = self.textViewItem; - XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); + XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); [viewItem deleteAction]; - XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); + XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); } - (void)testPerformDeleteActionWithPhotoMessage @@ -124,18 +185,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId]; + TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -146,18 +207,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId]; + TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -168,18 +229,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId]; + TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -190,18 +251,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId]; + TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]); + XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } diff --git a/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m b/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m index db14858c1a..2617561637 100644 --- a/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m +++ b/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m @@ -376,7 +376,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { if (contactShare.avatarImage) { - [contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction]; + [contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction.asAnyWrite]; } } completionBlock:^{ diff --git a/SignalMessaging/ViewModels/ContactShareViewModel.swift b/SignalMessaging/ViewModels/ContactShareViewModel.swift index 4397f0045b..35350a21d6 100644 --- a/SignalMessaging/ViewModels/ContactShareViewModel.swift +++ b/SignalMessaging/ViewModels/ContactShareViewModel.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -41,7 +41,7 @@ public class ContactShareViewModel: NSObject { @objc public convenience init(contactShareRecord: OWSContact, transaction: YapDatabaseReadTransaction) { - if let avatarAttachment = contactShareRecord.avatarAttachment(with: transaction) as? TSAttachmentStream { + if let avatarAttachment = contactShareRecord.avatarAttachment(with: transaction.asAnyRead) as? TSAttachmentStream { self.init(contactShareRecord: contactShareRecord, avatarImageData: avatarAttachment.validStillImageData()) } else { self.init(contactShareRecord: contactShareRecord, avatarImageData: nil) diff --git a/SignalMessaging/ViewModels/OWSQuotedReplyModel.m b/SignalMessaging/ViewModels/OWSQuotedReplyModel.m index 2b53723912..9f12ce661b 100644 --- a/SignalMessaging/ViewModels/OWSQuotedReplyModel.m +++ b/SignalMessaging/ViewModels/OWSQuotedReplyModel.m @@ -82,8 +82,8 @@ NS_ASSUME_NONNULL_BEGIN UIImage *_Nullable thumbnailImage; TSAttachmentPointer *attachmentPointer; if (attachmentInfo.thumbnailAttachmentStreamId) { - TSAttachment *attachment = - [TSAttachment fetchObjectWithUniqueID:attachmentInfo.thumbnailAttachmentStreamId transaction:transaction]; + TSAttachment *attachment = [TSAttachment anyFetchWithUniqueId:attachmentInfo.thumbnailAttachmentStreamId + transaction:transaction.asAnyRead]; TSAttachmentStream *attachmentStream; if ([attachment isKindOfClass:[TSAttachmentStream class]]) { @@ -92,8 +92,8 @@ NS_ASSUME_NONNULL_BEGIN } } else if (attachmentInfo.thumbnailAttachmentPointerId) { // download failed, or hasn't completed yet. - TSAttachment *attachment = - [TSAttachment fetchObjectWithUniqueID:attachmentInfo.thumbnailAttachmentPointerId transaction:transaction]; + TSAttachment *attachment = [TSAttachment anyFetchWithUniqueId:attachmentInfo.thumbnailAttachmentPointerId + transaction:transaction.asAnyRead]; if ([attachment isKindOfClass:[TSAttachmentPointer class]]) { attachmentPointer = (TSAttachmentPointer *)attachment; @@ -196,7 +196,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *_Nullable quotedText = message.body; BOOL hasText = quotedText.length > 0; - TSAttachment *_Nullable attachment = [message bodyAttachmentsWithTransaction:transaction].firstObject; + TSAttachment *_Nullable attachment = [message bodyAttachmentsWithTransaction:transaction.asAnyRead].firstObject; TSAttachmentStream *quotedAttachment; if (attachment && [attachment isKindOfClass:[TSAttachmentStream class]]) { diff --git a/SignalMessaging/environment/migrations/OWS105AttachmentFilePaths.m b/SignalMessaging/environment/migrations/OWS105AttachmentFilePaths.m index 3ff8b6357d..57b3e61c46 100644 --- a/SignalMessaging/environment/migrations/OWS105AttachmentFilePaths.m +++ b/SignalMessaging/environment/migrations/OWS105AttachmentFilePaths.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWS105AttachmentFilePaths.h" @@ -38,7 +38,8 @@ static NSString *const OWS105AttachmentFilePathsMigrationId = @"105"; // For performance, we want to upgrade all existing attachment streams in // a single transaction. for (TSAttachmentStream *attachmentStream in attachmentStreams) { - [attachmentStream saveWithTransaction:transaction]; + // NOTE: Use legacy save. + [attachmentStream ydb_saveWithTransaction:transaction]; } } diff --git a/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift b/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift index 68919222b5..e3101fa9cb 100644 --- a/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift +++ b/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -56,13 +56,15 @@ public class OWS113MultiAttachmentMediaMessages: OWSDatabaseMigration { self.dbReadWriteConnection().readWrite { transaction in for (attachmentId, messageId) in legacyAttachments { autoreleasepool { - guard let attachment = TSAttachment.fetch(uniqueId: attachmentId, transaction: transaction) else { + // NOTE: Use legacy fetch. + guard let attachment = TSAttachment.ydb_fetch(uniqueId: attachmentId, transaction: transaction) else { Logger.warn("missing attachment for messageId: \(messageId)") return } attachment.migrateAlbumMessageId(messageId) - attachment.save(with: transaction) + // NOTE: Use legacy save. + attachment.ydb_save(with: transaction) } } self.save(with: transaction) diff --git a/SignalMessaging/utils/OWSOrphanDataCleaner.m b/SignalMessaging/utils/OWSOrphanDataCleaner.m index 60d060b62b..097b781278 100644 --- a/SignalMessaging/utils/OWSOrphanDataCleaner.m +++ b/SignalMessaging/utils/OWSOrphanDataCleaner.m @@ -679,7 +679,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); return; } TSAttachment *_Nullable attachment = - [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction.asAnyRead]; if (!attachment) { // This can happen on launch since we sync contacts/groups, especially if you have a lot of attachments // to churn through, it's likely it's been deleted since starting this job. @@ -701,7 +701,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); if (!shouldRemoveOrphans) { continue; } - [attachmentStream removeWithTransaction:transaction]; + [attachmentStream anyRemoveWithTransaction:transaction.asAnyWrite]; } OWSLogInfo(@"Deleted orphan attachments: %zu", attachmentsRemoved); }]; diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index 0636533bf1..0585224885 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -465,7 +465,7 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess } NSError *linkPreviewError; OWSLinkPreview *_Nullable linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft - transaction:transaction + transaction:transaction.asAnyWrite error:&linkPreviewError]; if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) { OWSLogError(@"linkPreviewError: %@", linkPreviewError); diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m index 50fdca71b8..58b7566126 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m @@ -142,18 +142,20 @@ NS_ASSUME_NONNULL_BEGIN [TSAttachmentPointer attachmentPointersFromProtos:transcript.attachmentPointerProtos albumMessage:outgoingMessage]; for (TSAttachmentPointer *pointer in attachmentPointers) { - [pointer saveWithTransaction:transaction]; + [pointer anyInsertWithTransaction:transaction.asAnyWrite]; [outgoingMessage.attachmentIds addObject:pointer.uniqueId]; } TSQuotedMessage *_Nullable quotedMessage = transcript.quotedMessage; if (quotedMessage && quotedMessage.thumbnailAttachmentPointerId) { // We weren't able to derive a local thumbnail, so we'll fetch the referenced attachment. - TSAttachmentPointer *attachmentPointer = - [TSAttachmentPointer fetchObjectWithUniqueID:quotedMessage.thumbnailAttachmentPointerId - transaction:transaction]; + TSAttachment *_Nullable attachment = + [TSAttachment anyFetchWithUniqueId:quotedMessage.thumbnailAttachmentPointerId + transaction:transaction.asAnyRead]; + + if ([attachment isKindOfClass:[TSAttachmentPointer class]]) { + TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)attachment; - if ([attachmentPointer isKindOfClass:[TSAttachmentPointer class]]) { OWSLogDebug(@"downloading attachments for transcript: %lu", (unsigned long)transcript.timestamp); [self.attachmentDownloads downloadAttachmentPointer:attachmentPointer @@ -210,7 +212,7 @@ NS_ASSUME_NONNULL_BEGIN if (outgoingMessage.hasAttachments) { [self.attachmentDownloads downloadAllAttachmentsForMessage:outgoingMessage - transaction:transaction + transaction:transaction.asAnyRead success:attachmentHandler failure:^(NSError *error) { OWSLogError(@"failed to fetch transcripts attachments for message: %@", diff --git a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.h b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.h index fa725429ab..6b4c027a99 100644 --- a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.h +++ b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.h @@ -8,13 +8,12 @@ extern NSString *const kAttachmentDownloadProgressNotification; extern NSString *const kAttachmentDownloadProgressKey; extern NSString *const kAttachmentDownloadAttachmentIDKey; +@class SDSAnyReadTransaction; @class SSKProtoAttachmentPointer; @class TSAttachment; @class TSAttachmentPointer; @class TSAttachmentStream; @class TSMessage; -@class YapDatabaseReadTransaction; -@class YapDatabaseReadWriteTransaction; #pragma mark - @@ -32,7 +31,7 @@ extern NSString *const kAttachmentDownloadAttachmentIDKey; // // success/failure are always called on a worker queue. - (void)downloadBodyAttachmentsForMessage:(TSMessage *)message - transaction:(YapDatabaseReadTransaction *)transaction + transaction:(SDSAnyReadTransaction *)transaction success:(void (^)(NSArray *attachmentStreams))success failure:(void (^)(NSError *error))failure; @@ -42,7 +41,7 @@ extern NSString *const kAttachmentDownloadAttachmentIDKey; // // success/failure are always called on a worker queue. - (void)downloadAllAttachmentsForMessage:(TSMessage *)message - transaction:(YapDatabaseReadTransaction *)transaction + transaction:(SDSAnyReadTransaction *)transaction success:(void (^)(NSArray *attachmentStreams))success failure:(void (^)(NSError *error))failure; diff --git a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m index 6902106f39..19c5861707 100644 --- a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m +++ b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m @@ -25,7 +25,6 @@ #import #import #import -#import NS_ASSUME_NONNULL_BEGIN @@ -91,9 +90,9 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); #pragma mark - Dependencies -- (OWSPrimaryStorage *)primaryStorage +- (SDSDatabaseStorage *)databaseStorage { - return SSKEnvironment.shared.primaryStorage; + return SSKEnvironment.shared.databaseStorage; } - (TSNetworkManager *)networkManager @@ -136,7 +135,7 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); } - (void)downloadBodyAttachmentsForMessage:(TSMessage *)message - transaction:(YapDatabaseReadTransaction *)transaction + transaction:(SDSAnyReadTransaction *)transaction success:(void (^)(NSArray *attachmentStreams))success failure:(void (^)(NSError *error))failure { @@ -148,7 +147,7 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); } - (void)downloadAllAttachmentsForMessage:(TSMessage *)message - transaction:(YapDatabaseReadTransaction *)transaction + transaction:(SDSAnyReadTransaction *)transaction success:(void (^)(NSArray *attachmentStreams))success failure:(void (^)(NSError *error))failure { @@ -161,7 +160,7 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); - (void)downloadAttachmentsForMessage:(TSMessage *)message attachments:(NSArray *)attachments - transaction:(YapDatabaseReadTransaction *)transaction + transaction:(SDSAnyReadTransaction *)transaction success:(void (^)(NSArray *attachmentStreams))success failure:(void (^)(NSError *error))failure { @@ -318,18 +317,29 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); } __block TSAttachmentPointer *_Nullable attachmentPointer; - [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { // Fetch latest to ensure we don't overwrite an attachment stream, resurrect an attachment, etc. - attachmentPointer = [TSAttachmentPointer fetchObjectWithUniqueID:job.attachmentId transaction:transaction]; - if (![attachmentPointer isKindOfClass:[TSAttachmentPointer class]]) { + TSAttachment *_Nullable attachment = + [TSAttachmentPointer anyFetchWithUniqueId:job.attachmentId transaction:transaction]; + if (![attachment isKindOfClass:[TSAttachmentPointer class]]) { return; } - attachmentPointer.state = TSAttachmentPointerStateDownloading; - [attachmentPointer saveWithTransaction:transaction]; + attachmentPointer = (TSAttachmentPointer *)attachment; + [attachmentPointer anyUpdateWithTransaction:transaction + block:^(TSAttachment *attachment) { + if (![attachment isKindOfClass:[TSAttachmentPointer class]]) { + OWSFailDebug(@"Unexpected object: %@", attachment.class); + return; + } + TSAttachmentPointer *pointer = (TSAttachmentPointer *)attachment; + pointer.state = TSAttachmentPointerStateDownloading; + }]; if (job.message) { - [job.message touchWithTransaction:transaction]; + if (transaction.transitional_yapWriteTransaction) { + [job.message touchWithTransaction:transaction.transitional_yapWriteTransaction]; + } } }]; @@ -344,25 +354,27 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); success:^(TSAttachmentStream *attachmentStream) { OWSLogVerbose(@"Attachment download succeeded."); - [self.primaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - TSAttachment *_Nullable existingAttachment = - [TSAttachment fetchObjectWithUniqueID:attachmentStream.uniqueId transaction:transaction]; - if (!existingAttachment) { - OWSFailDebug(@"Attachment no longer exists."); - return; - } - if (![existingAttachment isKindOfClass:[TSAttachmentPointer class]]) { - OWSFailDebug(@"Attachment unexpectedly already saved."); - return; - } + [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { + TSAttachment *_Nullable existingAttachment = + [TSAttachment anyFetchWithUniqueId:attachmentStream.uniqueId transaction:transaction]; + if (!existingAttachment) { + OWSFailDebug(@"Attachment no longer exists."); + return; + } + if (![existingAttachment isKindOfClass:[TSAttachmentPointer class]]) { + OWSFailDebug(@"Attachment unexpectedly already saved."); + return; + } - [attachmentStream saveWithTransaction:transaction]; + [existingAttachment anyRemoveWithTransaction:transaction]; + [attachmentStream anyInsertWithTransaction:transaction]; - if (job.message) { - [job.message touchWithTransaction:transaction]; + if (job.message) { + if (transaction.transitional_yapWriteTransaction) { + [job.message touchWithTransaction:transaction.transitional_yapWriteTransaction]; } - }]; + } + }]; job.success(attachmentStream); @@ -375,22 +387,32 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); failure:^(NSError *error) { OWSLogError(@"Attachment download failed with error: %@", error); - [self.primaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - // Fetch latest to ensure we don't overwrite an attachment stream, resurrect an attachment, etc. - TSAttachmentPointer *_Nullable attachmentPointer = - [TSAttachmentPointer fetchObjectWithUniqueID:job.attachmentId transaction:transaction]; - if (![attachmentPointer isKindOfClass:[TSAttachmentPointer class]]) { - return; - } - attachmentPointer.mostRecentFailureLocalizedText = error.localizedDescription; - attachmentPointer.state = TSAttachmentPointerStateFailed; - [attachmentPointer saveWithTransaction:transaction]; + [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { + // Fetch latest to ensure we don't overwrite an attachment stream, resurrect an attachment, etc. + TSAttachment *_Nullable attachment = + [TSAttachmentPointer anyFetchWithUniqueId:job.attachmentId transaction:transaction]; + if (![attachment isKindOfClass:[TSAttachmentPointer class]]) { + return; + } + TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)attachment; + [attachmentPointer + anyUpdateWithTransaction:transaction + block:^(TSAttachment *attachment) { + if (![attachment isKindOfClass:[TSAttachmentPointer class]]) { + OWSFailDebug(@"Unexpected object: %@", attachment.class); + return; + } + TSAttachmentPointer *pointer = (TSAttachmentPointer *)attachment; + pointer.mostRecentFailureLocalizedText = error.localizedDescription; + pointer.state = TSAttachmentPointerStateFailed; + }]; - if (job.message) { - [job.message touchWithTransaction:transaction]; + if (job.message) { + if (transaction.transitional_yapWriteTransaction) { + [job.message touchWithTransaction:transaction.transitional_yapWriteTransaction]; } - }]; + } + }]; @synchronized(self) { [self.downloadingJobMap removeObjectForKey:job.attachmentId]; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachment.h b/SignalServiceKit/src/Messages/Attachments/TSAttachment.h index d70c034f8d..d1f094718e 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachment.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachment.h @@ -123,6 +123,43 @@ NS_SWIFT_NAME(init(uniqueId:albumMessageId:attachmentSchemaVersion:attachmentTyp + (NSString *)emojiForMimeType:(NSString *)contentType; +#pragma mark - YDB Deprecation + +// Deprecate all YDB methods. +// +// This will break Swift usage and generate warnings for Obj-C usage. +// Note: this functionality can still be accessed (for example by the +// SDS model extensions) via the ydb_ methods of TSYapDatabaseObject. ++ (NSUInteger)numberOfKeysInCollection NS_UNAVAILABLE; ++ (NSUInteger)numberOfKeysInCollectionWithTransaction:(YapDatabaseReadTransaction *)transaction NS_UNAVAILABLE; ++ (void)removeAllObjectsInCollection NS_UNAVAILABLE; ++ (NSArray *)allObjectsInCollection NS_UNAVAILABLE; ++ (void)enumerateCollectionObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block NS_UNAVAILABLE; ++ (void)enumerateCollectionObjectsWithTransaction:(YapDatabaseReadTransaction *)transaction + usingBlock:(void (^)(id object, BOOL *stop))block NS_UNAVAILABLE; +- (YapDatabaseConnection *)dbReadConnection NS_UNAVAILABLE; ++ (YapDatabaseConnection *)dbReadConnection NS_UNAVAILABLE; +- (YapDatabaseConnection *)dbReadWriteConnection NS_UNAVAILABLE; ++ (YapDatabaseConnection *)dbReadWriteConnection NS_UNAVAILABLE; +- (OWSPrimaryStorage *)primaryStorage NS_UNAVAILABLE; ++ (OWSPrimaryStorage *)primaryStorage NS_UNAVAILABLE; ++ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID + transaction:(YapDatabaseReadTransaction *)transaction NS_UNAVAILABLE; ++ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID NS_UNAVAILABLE; +- (void)save NS_UNAVAILABLE; +- (void)reload NS_UNAVAILABLE; +- (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction NS_UNAVAILABLE; +- (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction + ignoreMissing:(BOOL)ignoreMissing NS_UNAVAILABLE; +- (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock NS_UNAVAILABLE; +- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction NS_UNAVAILABLE; +- (void)touch NS_UNAVAILABLE; +- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction NS_UNAVAILABLE; +- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction NS_UNAVAILABLE; +- (void)remove NS_UNAVAILABLE; +- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction + changeBlock:(void (^)(id))changeBlock NS_UNAVAILABLE; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.h index bb36c65bf3..bdcc776c9f 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.h @@ -7,6 +7,7 @@ NS_ASSUME_NONNULL_BEGIN @class OWSBackupFragment; +@class SDSAnyWriteTransaction; @class SSKProtoAttachmentPointer; @class TSAttachmentStream; @class TSMessage; @@ -96,7 +97,7 @@ NS_SWIFT_NAME(init(uniqueId:albumMessageId:attachmentSchemaVersion:attachmentTyp // Marks attachment as needing "lazy backup restore." - (void)markForLazyRestoreWithFragment:(OWSBackupFragment *)lazyRestoreFragment - transaction:(YapDatabaseReadWriteTransaction *)transaction; + transaction:(SDSAnyWriteTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m index d58303870d..3db7df02bf 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m @@ -7,8 +7,6 @@ #import "TSAttachmentStream.h" #import #import -#import -#import NS_ASSUME_NONNULL_BEGIN @@ -275,24 +273,30 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Update With... Methods - (void)markForLazyRestoreWithFragment:(OWSBackupFragment *)lazyRestoreFragment - transaction:(YapDatabaseReadWriteTransaction *)transaction + transaction:(SDSAnyWriteTransaction *)transaction { OWSAssertDebug(lazyRestoreFragment); OWSAssertDebug(transaction); if (!lazyRestoreFragment.uniqueId) { // If metadata hasn't been saved yet, save now. - [lazyRestoreFragment saveWithTransaction:transaction]; + [lazyRestoreFragment anyInsertWithTransaction:transaction]; OWSAssertDebug(lazyRestoreFragment.uniqueId); } - [self applyChangeToSelfAndLatestCopy:transaction - changeBlock:^(TSAttachmentPointer *attachment) { - [attachment setLazyRestoreFragmentId:lazyRestoreFragment.uniqueId]; + [self anyUpdateWithTransaction:transaction + block:^(TSAttachment *attachment) { + if (![attachment isKindOfClass:[TSAttachmentPointer class]]) { + OWSFailDebug(@"Object has unexpected type: %@", [attachment class]); + return; + } + TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)attachment; + [attachmentPointer setLazyRestoreFragmentId:lazyRestoreFragment.uniqueId]; }]; } -- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +// TODO: We could add a similar check to the GRDB insert logic. +- (void)ydb_saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { #ifdef DEBUG if (self.uniqueId.length > 0) { @@ -305,7 +309,7 @@ NS_ASSUME_NONNULL_BEGIN } #endif - [super saveWithTransaction:transaction]; + [super ydb_saveWithTransaction:transaction]; } @end diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h index 25bc93aec6..72b7230199 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h @@ -14,7 +14,6 @@ NS_ASSUME_NONNULL_BEGIN @class SSKProtoAttachmentPointer; @class TSAttachmentPointer; -@class YapDatabaseReadWriteTransaction; typedef void (^OWSThumbnailSuccess)(UIImage *image); typedef void (^OWSThumbnailFailure)(void); diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index 4aa5692ae1..e0736dee7d 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -10,7 +10,6 @@ #import #import #import -#import NS_ASSUME_NONNULL_BEGIN @@ -48,6 +47,20 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); @implementation TSAttachmentStream +#pragma mark - Dependencies + ++ (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + +- (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + +#pragma mark - + - (instancetype)initWithContentType:(NSString *)contentType byteCount:(UInt32)byteCount sourceFilename:(nullable NSString *)sourceFilename @@ -400,7 +413,6 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); } - (void)anyDidRemoveWithTransaction:(SDSAnyWriteTransaction *)transaction -{ [super anyDidRemoveWithTransaction:transaction]; [self removeFile]; @@ -619,27 +631,51 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); #pragma mark - Update With... - (void)applyChangeAsyncToLatestCopyWithChangeBlock:(void (^)(TSAttachmentStream *))changeBlock +{ + [self applyChangeAsyncToLatestCopyWithChangeBlock:changeBlock completion:nil]; +} + +- (void)applyChangeAsyncToLatestCopyWithChangeBlock:(void (^)(TSAttachmentStream *))changeBlock + completion:(nullable dispatch_block_t)completion { OWSAssertDebug(changeBlock); - [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - NSString *collection = [TSAttachmentStream collection]; - TSAttachmentStream *latestInstance = [transaction objectForKey:self.uniqueId inCollection:collection]; - if (!latestInstance) { - // This attachment has either not yet been saved or has been deleted; do nothing. - // This isn't an error per se, but these race conditions should be - // _very_ rare. - // - // An exception is incoming group avatar updates which we don't ever save. - OWSLogWarn(@"Attachment not yet saved."); - } else if (![latestInstance isKindOfClass:[TSAttachmentStream class]]) { - OWSFailDebug(@"Attachment has unexpected type: %@", latestInstance.class); - } else { - changeBlock(latestInstance); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { + // We load a new instance before using anyUpdateWithTransaction() + // since it isn't thread-safe to mutate the current instance async. + TSAttachment *_Nullable attachment = + [TSAttachment anyFetchWithUniqueId:self.uniqueId transaction:transaction]; + if (!attachment) { + // This attachment has either not yet been saved or has been deleted; do nothing. + // This isn't an error per se, but these race conditions should be + // _very_ rare. + // + // An exception is incoming group avatar updates which we don't ever save. + OWSLogWarn(@"Could not load attachment."); + return; + } + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + OWSFailDebug(@"Object has unexpected type: %@.", [attachment class]); + return; + } + TSAttachmentStream *latestInstance = (TSAttachmentStream *)attachment; + [latestInstance + anyUpdateWithTransaction:transaction + block:^(TSAttachment *attachment) { + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + OWSFailDebug(@"Object has unexpected type: %@.", [attachment class]); + return; + } + TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; + changeBlock(attachmentStream); + }]; + }]; - [latestInstance saveWithTransaction:transaction]; + if (completion != nil) { + completion(); } - }]; + }); } #pragma mark - @@ -874,17 +910,14 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); OWSAssertDebug(digest.length > 0); OWSAssertDebug(serverId > 0); - [[self dbReadWriteConnection] - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self applyChangeToSelfAndLatestCopy:transaction - changeBlock:^(TSAttachmentStream *attachment) { - [attachment setEncryptionKey:encryptionKey]; - [attachment setDigest:digest]; - [attachment setServerId:serverId]; - [attachment setIsUploaded:YES]; - }]; + [self + applyChangeAsyncToLatestCopyWithChangeBlock:^(TSAttachmentStream *attachment) { + [attachment setEncryptionKey:encryptionKey]; + [attachment setDigest:digest]; + [attachment setServerId:serverId]; + [attachment setIsUploaded:YES]; } - completionBlock:completion]; + completion:completion]; } - (nullable TSAttachmentStream *)cloneAsThumbnail @@ -932,17 +965,21 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); // TODO we should past in a transaction, rather than sneakily generate one in `fetch...` to make sure we're // getting a consistent view in the message sending process. A brief glance shows it touches quite a bit of code, // but should be straight forward. - TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:attachmentId]; - if (![attachment isKindOfClass:[TSAttachmentStream class]]) { - OWSLogError(@"Unexpected type for attachment builder: %@", attachment); + __block TSAttachmentStream *_Nullable attachmentStream; + [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { + TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction]; + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + OWSFailDebug(@"Object has unexpected type: %@", [attachment class]); + return; + } + attachmentStream = (TSAttachmentStream *)attachment; + }]; + if (attachmentStream == nil) { return nil; } - - TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; return [attachmentStream buildProto]; } - - (nullable SSKProtoAttachmentPointer *)buildProto { OWSAssertDebug(self.serverId > 0); diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m index ee3f00c8aa..b1cc2a94a2 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m @@ -68,14 +68,15 @@ NS_ASSUME_NONNULL_BEGIN _thread = [TSContactThread getOrCreateThreadWithContactId:_recipientId transaction:transaction]; } - _quotedMessage = - [TSQuotedMessage quotedMessageForDataMessage:_dataMessage thread:_thread transaction:transaction]; - _contact = [OWSContacts contactForDataMessage:_dataMessage transaction:transaction]; + _quotedMessage = [TSQuotedMessage quotedMessageForDataMessage:_dataMessage + thread:_thread + transaction:transaction.asAnyWrite]; + _contact = [OWSContacts contactForDataMessage:_dataMessage transaction:transaction.asAnyWrite]; NSError *linkPreviewError; _linkPreview = [OWSLinkPreview buildValidatedLinkPreviewWithDataMessage:_dataMessage body:_body - transaction:transaction + transaction:transaction.asAnyWrite error:&linkPreviewError]; if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) { OWSLogError(@"linkPreviewError: %@", linkPreviewError); diff --git a/SignalServiceKit/src/Messages/Interactions/OWSContact.h b/SignalServiceKit/src/Messages/Interactions/OWSContact.h index 3702cf4df4..6ccbf4dba8 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSContact.h +++ b/SignalServiceKit/src/Messages/Interactions/OWSContact.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import @@ -9,12 +9,12 @@ NS_ASSUME_NONNULL_BEGIN @class CNContact; @class OWSAttachmentInfo; +@class SDSAnyReadTransaction; +@class SDSAnyWriteTransaction; @class SSKProtoDataMessage; @class SSKProtoDataMessageContact; @class TSAttachment; @class TSAttachmentStream; -@class YapDatabaseReadTransaction; -@class YapDatabaseReadWriteTransaction; extern BOOL kIsSendingContactSharesEnabled; @@ -128,10 +128,11 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value); @property (nonatomic, readonly) NSArray *addresses; @property (nonatomic, readonly, nullable) NSString *avatarAttachmentId; -- (nullable TSAttachment *)avatarAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction; -- (void)removeAvatarAttachmentWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; -- (void)saveAvatarImage:(UIImage *)image transaction:(YapDatabaseReadWriteTransaction *)transaction; +- (nullable TSAttachment *)avatarAttachmentWithTransaction:(SDSAnyReadTransaction *)transaction; +- (void)removeAvatarAttachmentWithTransaction:(SDSAnyWriteTransaction *)transaction; + +- (void)saveAvatarImage:(UIImage *)image transaction:(SDSAnyWriteTransaction *)transaction; // "Profile" avatars should _not_ be saved to device contacts. @property (nonatomic, readonly) BOOL isProfileAvatar; @@ -176,7 +177,7 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value); + (nullable SSKProtoDataMessageContact *)protoForContact:(OWSContact *)contact; + (nullable OWSContact *)contactForDataMessage:(SSKProtoDataMessage *)dataMessage - transaction:(YapDatabaseReadWriteTransaction *)transaction; + transaction:(SDSAnyWriteTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Messages/Interactions/OWSContact.m b/SignalServiceKit/src/Messages/Interactions/OWSContact.m index 4f7ba2163e..1ae87da1b6 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSContact.m +++ b/SignalServiceKit/src/Messages/Interactions/OWSContact.m @@ -483,12 +483,12 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value) #pragma mark - Avatar -- (nullable TSAttachment *)avatarAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction +- (nullable TSAttachment *)avatarAttachmentWithTransaction:(SDSAnyReadTransaction *)transaction { - return [TSAttachment fetchObjectWithUniqueID:self.avatarAttachmentId transaction:transaction]; + return [TSAttachment anyFetchWithUniqueId:self.avatarAttachmentId transaction:transaction]; } -- (void)saveAvatarImage:(UIImage *)image transaction:(YapDatabaseReadWriteTransaction *)transaction +- (void)saveAvatarImage:(UIImage *)image transaction:(SDSAnyWriteTransaction *)transaction { NSData *imageData = UIImageJPEGRepresentation(image, (CGFloat)0.9); @@ -503,15 +503,15 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value) BOOL success = [attachmentStream writeData:imageData error:&error]; OWSAssertDebug(success && !error); - [attachmentStream saveWithTransaction:transaction]; + [attachmentStream anyInsertWithTransaction:transaction]; self.avatarAttachmentId = attachmentStream.uniqueId; } -- (void)removeAvatarAttachmentWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +- (void)removeAvatarAttachmentWithTransaction:(SDSAnyWriteTransaction *)transaction { TSAttachment *_Nullable attachment = - [TSAttachment fetchObjectWithUniqueID:self.avatarAttachmentId transaction:transaction]; - [attachment removeWithTransaction:transaction]; + [TSAttachment anyFetchWithUniqueId:self.avatarAttachmentId transaction:transaction]; + [attachment anyRemoveWithTransaction:transaction]; } #pragma mark - Phone Numbers and Recipient IDs @@ -925,7 +925,7 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value) } + (nullable OWSContact *)contactForDataMessage:(SSKProtoDataMessage *)dataMessage - transaction:(YapDatabaseReadWriteTransaction *)transaction + transaction:(SDSAnyWriteTransaction *)transaction { OWSAssertDebug(dataMessage); @@ -1002,7 +1002,7 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value) TSAttachmentPointer *_Nullable attachmentPointer = [TSAttachmentPointer attachmentPointerFromProto:avatarAttachment albumMessage:nil]; if (attachmentPointer) { - [attachmentPointer saveWithTransaction:transaction]; + [attachmentPointer anyInsertWithTransaction:transaction]; contact.avatarAttachmentId = attachmentPointer.uniqueId; contact.isProfileAvatar = avatarInfo.isProfile; } else { diff --git a/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift b/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift index 0e40bd073f..f711477038 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift +++ b/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift @@ -119,7 +119,7 @@ public class OWSLinkPreview: MTLModel { @objc public class func buildValidatedLinkPreview(dataMessage: SSKProtoDataMessage, body: String?, - transaction: YapDatabaseReadWriteTransaction) throws -> OWSLinkPreview { + transaction: SDSAnyWriteTransaction) throws -> OWSLinkPreview { guard let previewProto = dataMessage.preview.first else { throw LinkPreviewError.noPreview } @@ -161,7 +161,7 @@ public class OWSLinkPreview: MTLModel { var imageAttachmentId: String? if let imageProto = previewProto.image { if let imageAttachmentPointer = TSAttachmentPointer(fromProto: imageProto, albumMessage: nil) { - imageAttachmentPointer.save(with: transaction) + imageAttachmentPointer.anyInsert(transaction: transaction) imageAttachmentId = imageAttachmentPointer.uniqueId } else { Logger.error("Could not parse image proto.") @@ -181,8 +181,8 @@ public class OWSLinkPreview: MTLModel { @objc public class func buildValidatedLinkPreview(fromInfo info: OWSLinkPreviewDraft, - transaction: YapDatabaseReadWriteTransaction) throws -> OWSLinkPreview { - guard SSKPreferences.areLinkPreviewsEnabled(transaction: transaction.asAnyRead) else { + transaction: SDSAnyWriteTransaction) throws -> OWSLinkPreview { + guard SSKPreferences.areLinkPreviewsEnabled(transaction: transaction) else { throw LinkPreviewError.noPreview } let imageAttachmentId = OWSLinkPreview.saveAttachmentIfPossible(imageData: info.imageData, @@ -201,7 +201,7 @@ public class OWSLinkPreview: MTLModel { private class func saveAttachmentIfPossible(imageData: Data?, imageMimeType: String?, - transaction: YapDatabaseReadWriteTransaction) -> String? { + transaction: SDSAnyWriteTransaction) -> String? { guard let imageData = imageData else { return nil } @@ -235,7 +235,7 @@ public class OWSLinkPreview: MTLModel { owsFailDebug("Could not write data source for path: \(filePath)") return nil } - attachment.save(with: transaction) + attachment.anyInsert(transaction: transaction) return attachment.uniqueId } diff --git a/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m index 0e0cbfd738..121047a5a4 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m @@ -12,6 +12,7 @@ #import "TSDatabaseSecondaryIndexes.h" #import "TSGroupThread.h" #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -188,7 +189,7 @@ perMessageExpirationDurationSeconds:perMessageExpirationDurationSeconds { for (NSString *attachmentId in self.attachmentIds) { TSAttachment *_Nullable attachment = - [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction.asAnyRead]; if ([attachment isKindOfClass:[TSAttachmentPointer class]]) { return NO; } diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.h b/SignalServiceKit/src/Messages/Interactions/TSMessage.h index ddd6a110b2..1175f1a9b7 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.h @@ -93,10 +93,10 @@ NS_SWIFT_NAME(init(uniqueId:receivedAtTimestamp:sortId:timestamp:uniqueThreadId: - (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (BOOL)hasAttachments; -- (NSArray *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction; -- (NSArray *)mediaAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction; -- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction; -- (NSArray *)allAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction; +- (NSArray *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction; +- (NSArray *)mediaAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction; +- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(SDSAnyReadTransaction *)transaction; +- (NSArray *)allAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction; - (void)removeAttachment:(TSAttachment *)attachment transaction:(SDSAnyWriteTransaction *)transaction NS_SWIFT_NAME(removeAttachment(_:transaction:)); @@ -107,7 +107,7 @@ NS_SWIFT_NAME(init(uniqueId:receivedAtTimestamp:sortId:timestamp:uniqueThreadId: - (void)setQuotedMessageThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream; -- (nullable NSString *)oversizeTextWithTransaction:(YapDatabaseReadTransaction *)transaction; +- (nullable NSString *)oversizeTextWithTransaction:(SDSAnyReadTransaction *)transaction; - (nullable NSString *)bodyTextWithTransaction:(SDSAnyReadTransaction *)transaction; - (BOOL)shouldStartExpireTimerWithTransaction:(YapDatabaseReadTransaction *)transaction; diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index 2335e9b051..cfa634a945 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -293,31 +293,32 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe return [NSSet setWithArray:result].allObjects; } -- (NSArray *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction +- (NSArray *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction { return [TSMessage attachmentsWithIds:self.attachmentIds transaction:transaction]; } -- (NSArray *)allAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction +- (NSArray *)allAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction { return [TSMessage attachmentsWithIds:self.allAttachmentIds transaction:transaction]; } + (NSArray *)attachmentsWithIds:(NSArray *)attachmentIds - transaction:(YapDatabaseReadTransaction *)transaction + transaction:(SDSAnyReadTransaction *)transaction { NSMutableArray *attachments = [NSMutableArray new]; for (NSString *attachmentId in attachmentIds) { - TSAttachment *_Nullable attachment = - [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction]; if (attachment) { [attachments addObject:attachment]; + } else { + OWSFailDebug(@"Missing attachment: %@", attachmentId); } } return [attachments copy]; } -- (NSArray *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction +- (NSArray *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction contentType:(NSString *)contentType { NSArray *attachments = [self bodyAttachmentsWithTransaction:transaction]; @@ -327,7 +328,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe }]]; } -- (NSArray *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction +- (NSArray *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction exceptContentType:(NSString *)contentType { NSArray *attachments = [self bodyAttachmentsWithTransaction:transaction]; @@ -367,17 +368,17 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe } } -- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction +- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(SDSAnyReadTransaction *)transaction { return [self bodyAttachmentsWithTransaction:transaction contentType:OWSMimeTypeOversizeTextMessage].firstObject; } -- (NSArray *)mediaAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction +- (NSArray *)mediaAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction { return [self bodyAttachmentsWithTransaction:transaction exceptContentType:OWSMimeTypeOversizeTextMessage]; } -- (nullable NSString *)oversizeTextWithTransaction:(YapDatabaseReadTransaction *)transaction +- (nullable NSString *)oversizeTextWithTransaction:(SDSAnyReadTransaction *)transaction { TSAttachment *_Nullable attachment = [self oversizeTextAttachmentWithTransaction:transaction]; if (!attachment) { @@ -405,10 +406,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe - (nullable NSString *)bodyTextWithTransaction:(SDSAnyReadTransaction *)transaction { - NSString *_Nullable oversizeText; - if (transaction.transitional_yapReadTransaction != nil) { - oversizeText = [self oversizeTextWithTransaction:transaction.transitional_yapReadTransaction]; - } + NSString *_Nullable oversizeText = [self oversizeTextWithTransaction:transaction]; if (oversizeText) { return oversizeText; } @@ -436,11 +434,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe } if (bodyDescription == nil) { - TSAttachment *_Nullable oversizeTextAttachment; - if (transaction.transitional_yapReadTransaction) { - oversizeTextAttachment = - [self oversizeTextAttachmentWithTransaction:transaction.transitional_yapReadTransaction]; - } + TSAttachment *_Nullable oversizeTextAttachment = [self oversizeTextAttachmentWithTransaction:transaction]; if ([oversizeTextAttachment isKindOfClass:[TSAttachmentStream class]]) { TSAttachmentStream *oversizeTextAttachmentStream = (TSAttachmentStream *)oversizeTextAttachment; NSData *_Nullable data = [NSData dataWithContentsOfFile:oversizeTextAttachmentStream.originalFilePath]; @@ -455,11 +449,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe NSString *_Nullable attachmentDescription = nil; - TSAttachment *_Nullable mediaAttachment; - if (transaction.transitional_yapReadTransaction) { - mediaAttachment = - [self mediaAttachmentsWithTransaction:transaction.transitional_yapReadTransaction].firstObject; - } + TSAttachment *_Nullable mediaAttachment = [self mediaAttachmentsWithTransaction:transaction].firstObject; if (mediaAttachment != nil) { attachmentDescription = mediaAttachment.description; } @@ -486,6 +476,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe } } +// TODO: Convert to Any. - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { // StickerManager does reference counting of "known" sticker packs. @@ -501,6 +492,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe [super saveWithTransaction:transaction]; } +// TODO: Convert to Any. - (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { // StickerManager does reference counting of "known" sticker packs. diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index bb6e7d1ed4..dc6c1eaaec 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -107,6 +107,15 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt @implementation TSOutgoingMessage +#pragma mark - Dependencies + +- (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + +#pragma mark - + // --- CODE GENERATION MARKER // This snippet is generated by /Scripts/sds_codegen/sds_generate.py. Do not manually edit it, instead run `sds_codegen.sh`. @@ -482,16 +491,16 @@ perMessageExpirationDurationSeconds:perMessageExpirationDurationSeconds if (attachmentIds.count < 1) { return; } - [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self.databaseStorage asyncWriteWithBlock:^(SDSAnyWriteTransaction *transaction) { for (NSString *attachmentId in attachmentIds) { // We need to fetch each attachment, since [TSAttachment removeWithTransaction:] does important work. TSAttachment *_Nullable attachment = - [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction]; if (!attachment) { OWSLogError(@"Couldn't load interaction's attachment for deletion."); continue; } - [attachment removeWithTransaction:transaction]; + [attachment anyRemoveWithTransaction:transaction]; }; }]; } diff --git a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h index a8f83da9ec..8f43631efb 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h @@ -7,12 +7,12 @@ NS_ASSUME_NONNULL_BEGIN +@class SDSAnyWriteTransaction; @class SSKProtoDataMessage; @class TSAttachment; @class TSAttachmentStream; @class TSQuotedMessage; @class TSThread; -@class YapDatabaseReadWriteTransaction; @interface OWSAttachmentInfo : MTLModel @@ -87,7 +87,7 @@ typedef NS_ENUM(NSUInteger, TSQuotedMessageContentSource) { // Before sending, persist a thumbnail attachment derived from the quoted attachment - (NSArray *)createThumbnailAttachmentsIfNecessaryWithTransaction: - (YapDatabaseReadWriteTransaction *)transaction; + (SDSAnyWriteTransaction *)transaction; - (instancetype)init NS_UNAVAILABLE; @@ -107,7 +107,7 @@ typedef NS_ENUM(NSUInteger, TSQuotedMessageContentSource) { + (nullable instancetype)quotedMessageForDataMessage:(SSKProtoDataMessage *)dataMessage thread:(TSThread *)thread - transaction:(YapDatabaseReadWriteTransaction *)transaction; + transaction:(SDSAnyWriteTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m index 6ae1f09258..b3b7d3f339 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m @@ -128,7 +128,7 @@ NS_ASSUME_NONNULL_BEGIN + (TSQuotedMessage *_Nullable)quotedMessageForDataMessage:(SSKProtoDataMessage *)dataMessage thread:(TSThread *)thread - transaction:(YapDatabaseReadWriteTransaction *)transaction + transaction:(SDSAnyWriteTransaction *)transaction { OWSAssertDebug(dataMessage); @@ -164,7 +164,7 @@ NS_ASSUME_NONNULL_BEGIN if (quotedMessage) { bodySource = TSQuotedMessageContentSourceLocal; - NSString *localText = [quotedMessage bodyTextWithTransaction:transaction.asAnyRead]; + NSString *localText = [quotedMessage bodyTextWithTransaction:transaction]; if (localText.length > 0) { body = localText; } @@ -199,7 +199,7 @@ NS_ASSUME_NONNULL_BEGIN thread.uniqueId, (unsigned long)timestamp); - [localThumbnail saveWithTransaction:transaction]; + [localThumbnail anyInsertWithTransaction:transaction]; attachmentInfo.thumbnailAttachmentStreamId = localThumbnail.uniqueId; } else if (quotedAttachment.thumbnail) { @@ -211,7 +211,7 @@ NS_ASSUME_NONNULL_BEGIN TSAttachmentPointer *_Nullable thumbnailPointer = [TSAttachmentPointer attachmentPointerFromProto:thumbnailAttachmentProto albumMessage:nil]; if (thumbnailPointer) { - [thumbnailPointer saveWithTransaction:transaction]; + [thumbnailPointer anyInsertWithTransaction:transaction]; attachmentInfo.thumbnailAttachmentPointerId = thumbnailPointer.uniqueId; } else { @@ -244,7 +244,7 @@ NS_ASSUME_NONNULL_BEGIN threadId:(NSString *)threadId authorId:(NSString *)authorId contentType:(NSString *)contentType - transaction:(YapDatabaseReadWriteTransaction *)transaction + transaction:(SDSAnyWriteTransaction *)transaction { TSMessage *_Nullable quotedMessage = [self findQuotedMessageWithTimestamp:timestamp threadId:threadId authorId:authorId transaction:transaction]; @@ -257,10 +257,10 @@ NS_ASSUME_NONNULL_BEGIN attachmentToQuote = [quotedMessage bodyAttachmentsWithTransaction:transaction].firstObject; } else if (quotedMessage.linkPreview && quotedMessage.linkPreview.imageAttachmentId.length > 0) { attachmentToQuote = - [TSAttachment fetchObjectWithUniqueID:quotedMessage.linkPreview.imageAttachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:quotedMessage.linkPreview.imageAttachmentId transaction:transaction]; } else if (quotedMessage.messageSticker && quotedMessage.messageSticker.attachmentId.length > 0) { attachmentToQuote = - [TSAttachment fetchObjectWithUniqueID:quotedMessage.messageSticker.attachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:quotedMessage.messageSticker.attachmentId transaction:transaction]; } if (![attachmentToQuote isKindOfClass:[TSAttachmentStream class]]) { return nil; @@ -275,7 +275,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable TSMessage *)findQuotedMessageWithTimestamp:(uint64_t)timestamp threadId:(NSString *)threadId authorId:(NSString *)authorId - transaction:(YapDatabaseReadWriteTransaction *)transaction + transaction:(SDSAnyWriteTransaction *)transaction { OWSAssertDebug(transaction); @@ -292,8 +292,20 @@ NS_ASSUME_NONNULL_BEGIN return nil; } - for (TSMessage *message in - [TSInteraction interactionsWithTimestamp:timestamp ofClass:TSMessage.class withTransaction:transaction]) { + NSError *error; + NSArray *interactions = + [InteractionFinder interactionsWithTimestamp:timestamp + filter:^(TSInteraction *interaction) { + return [interaction isKindOfClass:[TSMessage class]]; + } + transaction:transaction + error:&error]; + if (error != nil) { + OWSFailDebug(@"Error loading interactions: %@", error); + return nil; + } + for (TSInteraction *interaction in interactions) { + TSMessage *message = (TSMessage *)interaction; if (![message.uniqueThreadId isEqualToString:threadId]) { continue; } @@ -373,14 +385,14 @@ NS_ASSUME_NONNULL_BEGIN // Before sending, persist a thumbnail attachment derived from the quoted attachment - (NSArray *)createThumbnailAttachmentsIfNecessaryWithTransaction: - (YapDatabaseReadWriteTransaction *)transaction + (SDSAnyWriteTransaction *)transaction { NSMutableArray *thumbnailAttachments = [NSMutableArray new]; for (OWSAttachmentInfo *info in self.quotedAttachments) { OWSAssertDebug(info.attachmentId); - TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction]; + TSAttachment *attachment = [TSAttachment anyFetchWithUniqueId:info.attachmentId transaction:transaction]; if (![attachment isKindOfClass:[TSAttachmentStream class]]) { continue; } @@ -391,7 +403,7 @@ NS_ASSUME_NONNULL_BEGIN continue; } - [thumbnailStream saveWithTransaction:transaction]; + [thumbnailStream anyInsertWithTransaction:transaction]; info.thumbnailAttachmentStreamId = thumbnailStream.uniqueId; [thumbnailAttachments addObject:thumbnailStream]; } diff --git a/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m b/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m index d132878801..c415ec572c 100644 --- a/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m +++ b/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m @@ -1,10 +1,11 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWSFailedAttachmentDownloadsJob.h" #import "OWSPrimaryStorage.h" #import "TSAttachmentPointer.h" +#import #import #import #import @@ -64,10 +65,11 @@ static NSString *const OWSFailedAttachmentDownloadsJobAttachmentStateIndex = @"i // Since we can't directly mutate the enumerated attachments, we store only their ids in hopes // of saving a little memory and then enumerate the (larger) TSAttachment objects one at a time. for (NSString *attachmentId in [self fetchAttemptingOutAttachmentIdsWithTransaction:transaction]) { - TSAttachmentPointer *_Nullable attachment = - [TSAttachmentPointer fetchObjectWithUniqueID:attachmentId transaction:transaction]; + TSAttachment *_Nullable attachment = + [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction.asAnyRead]; if ([attachment isKindOfClass:[TSAttachmentPointer class]]) { - block(attachment); + TSAttachmentPointer *pointer = (TSAttachmentPointer *)attachment; + block(pointer); } else { OWSLogError(@"unexpected object: %@", attachment); } @@ -82,8 +84,15 @@ static NSString *const OWSFailedAttachmentDownloadsJobAttachmentStateIndex = @"i [self enumerateAttemptingOutAttachmentsWithBlock:^(TSAttachmentPointer *attachment) { // sanity check if (attachment.state != TSAttachmentPointerStateFailed) { - attachment.state = TSAttachmentPointerStateFailed; - [attachment saveWithTransaction:transaction]; + [attachment anyUpdateWithTransaction:transaction.asAnyWrite + block:^(TSAttachment *attachment) { + if (![attachment isKindOfClass:[TSAttachmentPointer class]]) { + OWSFailDebug(@"unexpected object: %@", attachment); + return; + } + TSAttachmentPointer *pointer = (TSAttachmentPointer *)attachment; + pointer.state = TSAttachmentPointerStateFailed; + }]; count++; } } diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index cc95053c3e..f0b5b5636b 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -855,7 +855,7 @@ NS_ASSUME_NONNULL_BEGIN OWSLogDebug(@"incoming attachment message: %@", message.debugDescription); [self.attachmentDownloads downloadBodyAttachmentsForMessage:message - transaction:transaction.transitional_yapWriteTransaction + transaction:transaction success:^(NSArray *attachmentStreams) { OWSLogDebug(@"successfully fetched attachments: %lu for message: %@", (unsigned long)attachmentStreams.count, @@ -1459,8 +1459,10 @@ NS_ASSUME_NONNULL_BEGIN NSString *body = dataMessage.body; NSNumber *_Nullable serverTimestamp = (envelope.hasServerTimestamp ? @(envelope.serverTimestamp) : nil); + TSQuotedMessage *_Nullable quotedMessage = + [TSQuotedMessage quotedMessageForDataMessage:dataMessage thread:thread transaction:transaction]; + OWSContact *_Nullable contact; - TSQuotedMessage *_Nullable quotedMessage; OWSLinkPreview *_Nullable linkPreview; if (transaction.transitional_yapWriteTransaction) { [[OWSDisappearingMessagesJob sharedJob] @@ -1470,19 +1472,13 @@ NS_ASSUME_NONNULL_BEGIN createdInExistingGroup:NO transaction:transaction.transitional_yapWriteTransaction]; - contact = - [OWSContacts contactForDataMessage:dataMessage transaction:transaction.transitional_yapWriteTransaction]; - - quotedMessage = [TSQuotedMessage quotedMessageForDataMessage:dataMessage - thread:thread - transaction:transaction.transitional_yapWriteTransaction]; + contact = [OWSContacts contactForDataMessage:dataMessage transaction:transaction]; NSError *linkPreviewError; - linkPreview = - [OWSLinkPreview buildValidatedLinkPreviewWithDataMessage:dataMessage - body:body - transaction:transaction.transitional_yapWriteTransaction - error:&linkPreviewError]; + linkPreview = [OWSLinkPreview buildValidatedLinkPreviewWithDataMessage:dataMessage + body:body + transaction:transaction + error:&linkPreviewError]; if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) { OWSLogError(@"linkPreviewError: %@", linkPreviewError); } diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index f58d4173f1..8ce8fdc371 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -153,6 +153,15 @@ void AssertIsOnSendingQueue() @implementation OWSSendMessageOperation +#pragma mark - Dependencies + +- (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + +#pragma mark - + - (instancetype)initWithMessage:(TSOutgoingMessage *)message messageSender:(OWSMessageSender *)messageSender dbConnection:(YapDatabaseConnection *)dbConnection @@ -184,7 +193,7 @@ void AssertIsOnSendingQueue() // Sanity check preconditions if (self.message.hasAttachments) { - [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { for (TSAttachment *attachment in [self.message allAttachmentsWithTransaction:transaction]) { if (![attachment isKindOfClass:[TSAttachmentStream class]]) { error = OWSErrorMakeFailedToSendOutgoingMessageError(); @@ -1863,14 +1872,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // suggests this could change. The logic is intended to work with multiple, but // if we ever actually want to send multiple, we should do more testing. NSArray *quotedThumbnailAttachments = - [message.quotedMessage createThumbnailAttachmentsIfNecessaryWithTransaction:transaction]; + [message.quotedMessage createThumbnailAttachmentsIfNecessaryWithTransaction:transaction.asAnyWrite]; for (TSAttachmentStream *attachment in quotedThumbnailAttachments) { [attachmentIds addObject:attachment.uniqueId]; } } if (message.contactShare.avatarAttachmentId != nil) { - TSAttachment *attachment = [message.contactShare avatarAttachmentWithTransaction:transaction]; + TSAttachment *attachment = [message.contactShare avatarAttachmentWithTransaction:transaction.asAnyWrite]; if ([attachment isKindOfClass:[TSAttachmentStream class]]) { [attachmentIds addObject:attachment.uniqueId]; } else { @@ -1880,7 +1889,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (message.linkPreview.imageAttachmentId != nil) { TSAttachment *attachment = - [TSAttachment fetchObjectWithUniqueID:message.linkPreview.imageAttachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:message.linkPreview.imageAttachmentId transaction:transaction.asAnyRead]; if ([attachment isKindOfClass:[TSAttachmentStream class]]) { [attachmentIds addObject:attachment.uniqueId]; } else { @@ -1890,7 +1899,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (message.messageSticker.attachmentId != nil) { TSAttachment *attachment = - [TSAttachment fetchObjectWithUniqueID:message.messageSticker.attachmentId transaction:transaction]; + [TSAttachment anyFetchWithUniqueId:message.messageSticker.attachmentId transaction:transaction.asAnyRead]; if ([attachment isKindOfClass:[TSAttachmentStream class]]) { [attachmentIds addObject:attachment.uniqueId]; } else { @@ -1947,17 +1956,17 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [attachmentStreams addObject:attachmentStream]; } - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (TSAttachmentStream *attachmentStream in attachmentStreams) { [outgoingMessage.attachmentIds addObject:attachmentStream.uniqueId]; if (attachmentStream.sourceFilename) { outgoingMessage.attachmentFilenameMap[attachmentStream.uniqueId] = attachmentStream.sourceFilename; } } - [outgoingMessage saveWithTransaction:transaction]; for (TSAttachmentStream *attachmentStream in attachmentStreams) { - [attachmentStream saveWithTransaction:transaction]; + [attachmentStream anyInsertWithTransaction:transaction.asAnyWrite]; } + [outgoingMessage saveWithTransaction:transaction]; }]; completionHandler(nil); diff --git a/SignalServiceKit/src/Messages/Stickers/MessageSticker.swift b/SignalServiceKit/src/Messages/Stickers/MessageSticker.swift index c9db5c1b20..a2323646d8 100644 --- a/SignalServiceKit/src/Messages/Stickers/MessageSticker.swift +++ b/SignalServiceKit/src/Messages/Stickers/MessageSticker.swift @@ -221,13 +221,4 @@ public class MessageSticker: MTLModel { } return attachmentId } - - @objc - public func removeAttachment(transaction: YapDatabaseReadWriteTransaction) { - guard let attachment = TSAttachment.fetch(uniqueId: attachmentId, transaction: transaction) else { - owsFailDebug("Could not load attachment.") - return - } - attachment.remove(with: transaction) - } } diff --git a/SignalServiceKit/src/Network/API/OWSUploadOperation.m b/SignalServiceKit/src/Network/API/OWSUploadOperation.m index 252b49232e..43bb0c72dc 100644 --- a/SignalServiceKit/src/Network/API/OWSUploadOperation.m +++ b/SignalServiceKit/src/Network/API/OWSUploadOperation.m @@ -63,9 +63,20 @@ static const CGFloat kAttachmentUploadProgressTheta = 0.001f; - (void)run { - __block TSAttachmentStream *attachmentStream; - [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - attachmentStream = [TSAttachmentStream fetchObjectWithUniqueID:self.attachmentId transaction:transaction]; + __block TSAttachmentStream *_Nullable attachmentStream; + [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + TSAttachment *_Nullable attachment = + [TSAttachment anyFetchWithUniqueId:self.attachmentId transaction:transaction.asAnyRead]; + if (attachment == nil) { + // Message may have been removed. + OWSLogWarn(@"Missing attachment."); + return; + } + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + OWSFailDebug(@"Unexpected object: %@", [attachment class]); + return; + } + attachmentStream = (TSAttachmentStream *)attachment; }]; if (!attachmentStream) { diff --git a/SignalServiceKit/src/Storage/Database/Records/InteractionFinder.swift b/SignalServiceKit/src/Storage/Database/Records/InteractionFinder.swift index 5684b4f044..7f612de95f 100644 --- a/SignalServiceKit/src/Storage/Database/Records/InteractionFinder.swift +++ b/SignalServiceKit/src/Storage/Database/Records/InteractionFinder.swift @@ -150,6 +150,7 @@ public class InteractionFinder: NSObject, InteractionFinderAdapter { } } + @objc public class func interactions(withTimestamp timestamp: UInt64, filter: @escaping (TSInteraction) -> Bool, transaction: SDSAnyReadTransaction) throws -> [TSInteraction] { switch transaction.readTransaction { case .yapRead(let yapRead): diff --git a/SignalServiceKit/src/Storage/Database/SDSModel.swift b/SignalServiceKit/src/Storage/Database/SDSModel.swift index a3833a4c72..297b8e043b 100644 --- a/SignalServiceKit/src/Storage/Database/SDSModel.swift +++ b/SignalServiceKit/src/Storage/Database/SDSModel.swift @@ -23,7 +23,7 @@ public extension SDSModel { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - save(with: ydbTransaction) + ydb_save(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() diff --git a/SignalServiceKit/src/Storage/OWSStorage.m b/SignalServiceKit/src/Storage/OWSStorage.m index c21dca829b..d5d863ab46 100644 --- a/SignalServiceKit/src/Storage/OWSStorage.m +++ b/SignalServiceKit/src/Storage/OWSStorage.m @@ -648,7 +648,9 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_ if (!ready) { OWSFailDebug(@"asyncRegisterExtension failed: %@", extensionName); } else { - OWSLogVerbose(@"asyncRegisterExtension succeeded: %@", extensionName); + if (!CurrentAppContext().isRunningTests) { + OWSLogVerbose(@"asyncRegisterExtension succeeded: %@", extensionName); + } } dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.h b/SignalServiceKit/src/Storage/TSYapDatabaseObject.h index d9140dedbf..144cfd1d04 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.h +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.h @@ -173,6 +173,32 @@ NS_ASSUME_NONNULL_BEGIN - (void)anyDidRemoveWithTransaction:(SDSAnyWriteTransaction *)transaction; // GRDB TODO: didUpdate? +#pragma mark - YDB Deprecation + ++ (NSUInteger)ydb_numberOfKeysInCollection; ++ (NSUInteger)ydb_numberOfKeysInCollectionWithTransaction:(YapDatabaseReadTransaction *)transaction; ++ (void)ydb_removeAllObjectsInCollection; ++ (NSArray *)ydb_allObjectsInCollection; ++ (void)ydb_enumerateCollectionObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block; ++ (void)ydb_enumerateCollectionObjectsWithTransaction:(YapDatabaseReadTransaction *)transaction + usingBlock:(void (^)(id object, BOOL *stop))block; ++ (nullable instancetype)ydb_fetchObjectWithUniqueID:(NSString *)uniqueID + transaction:(YapDatabaseReadTransaction *)transaction + NS_SWIFT_NAME(ydb_fetch(uniqueId:transaction:)); ++ (nullable instancetype)ydb_fetchObjectWithUniqueID:(NSString *)uniqueID NS_SWIFT_NAME(ydb_fetch(uniqueId:)); +- (void)ydb_save; +- (void)ydb_reload; +- (void)ydb_reloadWithTransaction:(YapDatabaseReadTransaction *)transaction; +- (void)ydb_reloadWithTransaction:(YapDatabaseReadTransaction *)transaction ignoreMissing:(BOOL)ignoreMissing; +- (void)ydb_saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock; +- (void)ydb_saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)ydb_touch; +- (void)ydb_touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)ydb_removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)ydb_remove; +- (void)ydb_applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction + changeBlock:(void (^)(id))changeBlock; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m index e466b639ac..9f99b373a2 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m @@ -272,6 +272,106 @@ NS_ASSUME_NONNULL_BEGIN // Do nothing. } +#pragma mark - YDB Deprecation + ++ (NSUInteger)ydb_numberOfKeysInCollection +{ + return [self numberOfKeysInCollection]; +} + ++ (NSUInteger)ydb_numberOfKeysInCollectionWithTransaction:(YapDatabaseReadTransaction *)transaction +{ + return [self numberOfKeysInCollectionWithTransaction:transaction]; +} + ++ (void)ydb_removeAllObjectsInCollection +{ + [self removeAllObjectsInCollection]; +} + ++ (NSArray *)ydb_allObjectsInCollection +{ + return [self allObjectsInCollection]; +} + ++ (void)ydb_enumerateCollectionObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block +{ + return [self enumerateCollectionObjectsUsingBlock:block]; +} + ++ (void)ydb_enumerateCollectionObjectsWithTransaction:(YapDatabaseReadTransaction *)transaction + usingBlock:(void (^)(id object, BOOL *stop))block +{ + return [self enumerateCollectionObjectsWithTransaction:transaction usingBlock:block]; +} + ++ (nullable instancetype)ydb_fetchObjectWithUniqueID:(NSString *)uniqueID + transaction:(YapDatabaseReadTransaction *)transaction +{ + return [self fetchObjectWithUniqueID:uniqueID transaction:transaction]; +} + ++ (nullable instancetype)ydb_fetchObjectWithUniqueID:(NSString *)uniqueID +{ + return [self fetchObjectWithUniqueID:uniqueID]; +} + +- (void)ydb_save +{ + [self save]; +} + +- (void)ydb_reload +{ + [self reload]; +} + +- (void)ydb_reloadWithTransaction:(YapDatabaseReadTransaction *)transaction +{ + [self reloadWithTransaction:transaction]; +} + +- (void)ydb_reloadWithTransaction:(YapDatabaseReadTransaction *)transaction ignoreMissing:(BOOL)ignoreMissing +{ + [self reloadWithTransaction:transaction ignoreMissing:ignoreMissing]; +} + +- (void)ydb_saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock +{ + [self saveAsyncWithCompletionBlock:completionBlock]; +} + +- (void)ydb_saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + [self saveWithTransaction:transaction]; +} + +- (void)ydb_touch +{ + [self touch]; +} + +- (void)ydb_touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + [self touchWithTransaction:transaction]; +} + +- (void)ydb_removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + [self removeWithTransaction:transaction]; +} + +- (void)ydb_remove +{ + [self remove]; +} + +- (void)ydb_applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction + changeBlock:(void (^)(id))changeBlock +{ + [self applyChangeToSelfAndLatestCopy:transaction changeBlock:changeBlock]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift b/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift index db18484b2c..5ce7e6ed6d 100644 --- a/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift +++ b/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift @@ -35,7 +35,7 @@ class OWSLinkPreviewTest: SSKBaseTestSwift { let dataBuilder = SSKProtoDataMessage.builder() dataBuilder.addPreview(try! previewBuilder.build()) - self.yapWrite { (transaction) in + self.write { (transaction) in XCTAssertNotNil(try! OWSLinkPreview.buildValidatedLinkPreview(dataMessage: try! dataBuilder.build(), body: body, transaction: transaction)) @@ -50,7 +50,7 @@ class OWSLinkPreviewTest: SSKBaseTestSwift { let dataBuilder = SSKProtoDataMessage.builder() dataBuilder.addPreview(try! previewBuilder.build()) - self.yapWrite { (transaction) in + self.write { (transaction) in XCTAssertNotNil(try! OWSLinkPreview.buildValidatedLinkPreview(dataMessage: try! dataBuilder.build(), body: body, transaction: transaction)) @@ -68,7 +68,7 @@ class OWSLinkPreviewTest: SSKBaseTestSwift { let dataBuilder = SSKProtoDataMessage.builder() dataBuilder.addPreview(try! previewBuilder.build()) - self.yapWrite { (transaction) in + self.write { (transaction) in XCTAssertNotNil(try! OWSLinkPreview.buildValidatedLinkPreview(dataMessage: try! dataBuilder.build(), body: body, transaction: transaction)) @@ -82,7 +82,7 @@ class OWSLinkPreviewTest: SSKBaseTestSwift { let dataBuilder = SSKProtoDataMessage.builder() dataBuilder.addPreview(try! previewBuilder.build()) - self.yapWrite { (transaction) in + self.write { (transaction) in do { _ = try OWSLinkPreview.buildValidatedLinkPreview(dataMessage: try! dataBuilder.build(), body: body, From 85af6572e31acaf7ae1a353185557d713a6b32f7 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 21 Jun 2019 15:22:07 -0400 Subject: [PATCH 2/4] Convert attachments to be any-only - code generated changes. --- Scripts/sds_codegen/sds_generate.py | 6 +++--- .../environment/migrations/OWSDatabaseMigration+SDS.swift | 6 +++--- .../Contacts/OWSDisappearingMessagesConfiguration+SDS.swift | 6 +++--- SignalServiceKit/src/Contacts/SignalAccount+SDS.swift | 6 +++--- SignalServiceKit/src/Contacts/SignalRecipient+SDS.swift | 6 +++--- SignalServiceKit/src/Contacts/TSThread+SDS.swift | 6 +++--- SignalServiceKit/src/Devices/OWSDevice+SDS.swift | 6 +++--- .../src/Devices/OWSLinkedDeviceReadReceipt+SDS.swift | 6 +++--- .../src/Messages/Attachments/TSAttachment+SDS.swift | 6 +++--- .../src/Messages/Interactions/TSInteraction+SDS.swift | 6 +++--- .../src/Messages/OWSBatchMessageProcessor+SDS.swift | 6 +++--- SignalServiceKit/src/Messages/OWSMessageReceiver+SDS.swift | 6 +++--- .../src/Messages/OWSReadReceiptManager+SDS.swift | 6 +++--- .../src/Messages/Stickers/InstalledSticker+SDS.swift | 6 +++--- .../src/Messages/Stickers/KnownStickerPack+SDS.swift | 6 +++--- .../src/Messages/Stickers/StickerPack+SDS.swift | 6 +++--- .../src/Security/OWSRecipientIdentity+SDS.swift | 6 +++--- SignalServiceKit/src/Storage/Jobs/SSKJobRecord+SDS.swift | 6 +++--- SignalServiceKit/src/Util/ExperienceUpgrade+SDS.swift | 6 +++--- SignalServiceKit/src/Util/OWSBackupFragment+SDS.swift | 6 +++--- SignalServiceKit/src/Util/OWSUserProfile+SDS.swift | 6 +++--- 21 files changed, 63 insertions(+), 63 deletions(-) diff --git a/Scripts/sds_codegen/sds_generate.py b/Scripts/sds_codegen/sds_generate.py index b5ad0180e8..51120d39e6 100755 --- a/Scripts/sds_codegen/sds_generate.py +++ b/Scripts/sds_codegen/sds_generate.py @@ -1114,7 +1114,7 @@ public extension %s { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -1222,7 +1222,7 @@ public extension %s { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return %(class_name)s.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return %(class_name)s.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(%(record_name)s.databaseTableName) WHERE \(%(record_identifier)sColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -1237,7 +1237,7 @@ public extension %s { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (%s, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - %s.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + %s.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? %s else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalMessaging/environment/migrations/OWSDatabaseMigration+SDS.swift b/SignalMessaging/environment/migrations/OWSDatabaseMigration+SDS.swift index a2852dc0b1..adc68f5300 100644 --- a/SignalMessaging/environment/migrations/OWSDatabaseMigration+SDS.swift +++ b/SignalMessaging/environment/migrations/OWSDatabaseMigration+SDS.swift @@ -273,7 +273,7 @@ public extension OWSDatabaseMigration { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -369,7 +369,7 @@ public extension OWSDatabaseMigration { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSDatabaseMigration.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSDatabaseMigration.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(DatabaseMigrationRecord.databaseTableName) WHERE \(databaseMigrationColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -382,7 +382,7 @@ public extension OWSDatabaseMigration { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSDatabaseMigration, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSDatabaseMigration.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSDatabaseMigration.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSDatabaseMigration else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration+SDS.swift b/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration+SDS.swift index e2346954c1..c9ba7cec67 100644 --- a/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration+SDS.swift +++ b/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration+SDS.swift @@ -198,7 +198,7 @@ public extension OWSDisappearingMessagesConfiguration { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -294,7 +294,7 @@ public extension OWSDisappearingMessagesConfiguration { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSDisappearingMessagesConfiguration.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSDisappearingMessagesConfiguration.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(DisappearingMessagesConfigurationRecord.databaseTableName) WHERE \(disappearingMessagesConfigurationColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -307,7 +307,7 @@ public extension OWSDisappearingMessagesConfiguration { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSDisappearingMessagesConfiguration, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSDisappearingMessagesConfiguration.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSDisappearingMessagesConfiguration.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSDisappearingMessagesConfiguration else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Contacts/SignalAccount+SDS.swift b/SignalServiceKit/src/Contacts/SignalAccount+SDS.swift index 678651ae94..40b2980c30 100644 --- a/SignalServiceKit/src/Contacts/SignalAccount+SDS.swift +++ b/SignalServiceKit/src/Contacts/SignalAccount+SDS.swift @@ -211,7 +211,7 @@ public extension SignalAccount { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -307,7 +307,7 @@ public extension SignalAccount { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return SignalAccount.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return SignalAccount.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(SignalAccountRecord.databaseTableName) WHERE \(signalAccountColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -320,7 +320,7 @@ public extension SignalAccount { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (SignalAccount, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - SignalAccount.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + SignalAccount.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? SignalAccount else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Contacts/SignalRecipient+SDS.swift b/SignalServiceKit/src/Contacts/SignalRecipient+SDS.swift index 3503e13b35..a1d59aa178 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient+SDS.swift +++ b/SignalServiceKit/src/Contacts/SignalRecipient+SDS.swift @@ -193,7 +193,7 @@ public extension SignalRecipient { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -289,7 +289,7 @@ public extension SignalRecipient { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return SignalRecipient.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return SignalRecipient.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(SignalRecipientRecord.databaseTableName) WHERE \(signalRecipientColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -302,7 +302,7 @@ public extension SignalRecipient { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (SignalRecipient, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - SignalRecipient.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + SignalRecipient.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? SignalRecipient else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Contacts/TSThread+SDS.swift b/SignalServiceKit/src/Contacts/TSThread+SDS.swift index fda971e80e..25367f8e3e 100644 --- a/SignalServiceKit/src/Contacts/TSThread+SDS.swift +++ b/SignalServiceKit/src/Contacts/TSThread+SDS.swift @@ -310,7 +310,7 @@ public extension TSThread { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -406,7 +406,7 @@ public extension TSThread { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return TSThread.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return TSThread.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(ThreadRecord.databaseTableName) WHERE \(threadColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -419,7 +419,7 @@ public extension TSThread { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (TSThread, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - TSThread.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + TSThread.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? TSThread else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Devices/OWSDevice+SDS.swift b/SignalServiceKit/src/Devices/OWSDevice+SDS.swift index e8cafcc8f7..18d41224cb 100644 --- a/SignalServiceKit/src/Devices/OWSDevice+SDS.swift +++ b/SignalServiceKit/src/Devices/OWSDevice+SDS.swift @@ -210,7 +210,7 @@ public extension OWSDevice { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -306,7 +306,7 @@ public extension OWSDevice { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSDevice.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSDevice.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(DeviceRecord.databaseTableName) WHERE \(deviceColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -319,7 +319,7 @@ public extension OWSDevice { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSDevice, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSDevice.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSDevice.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSDevice else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt+SDS.swift b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt+SDS.swift index c6ac25bcba..f077c084ca 100644 --- a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt+SDS.swift +++ b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt+SDS.swift @@ -204,7 +204,7 @@ public extension OWSLinkedDeviceReadReceipt { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -300,7 +300,7 @@ public extension OWSLinkedDeviceReadReceipt { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSLinkedDeviceReadReceipt.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSLinkedDeviceReadReceipt.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(LinkedDeviceReadReceiptRecord.databaseTableName) WHERE \(linkedDeviceReadReceiptColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -313,7 +313,7 @@ public extension OWSLinkedDeviceReadReceipt { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSLinkedDeviceReadReceipt, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSLinkedDeviceReadReceipt.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSLinkedDeviceReadReceipt.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSLinkedDeviceReadReceipt else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachment+SDS.swift b/SignalServiceKit/src/Messages/Attachments/TSAttachment+SDS.swift index db931ac3bf..179eed4f5b 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachment+SDS.swift +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachment+SDS.swift @@ -403,7 +403,7 @@ public extension TSAttachment { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -499,7 +499,7 @@ public extension TSAttachment { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return TSAttachment.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return TSAttachment.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(AttachmentRecord.databaseTableName) WHERE \(attachmentColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -512,7 +512,7 @@ public extension TSAttachment { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (TSAttachment, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - TSAttachment.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + TSAttachment.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? TSAttachment else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/Interactions/TSInteraction+SDS.swift b/SignalServiceKit/src/Messages/Interactions/TSInteraction+SDS.swift index 2036f3e09b..64e1a9aa0c 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInteraction+SDS.swift +++ b/SignalServiceKit/src/Messages/Interactions/TSInteraction+SDS.swift @@ -1357,7 +1357,7 @@ public extension TSInteraction { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -1453,7 +1453,7 @@ public extension TSInteraction { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return TSInteraction.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return TSInteraction.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(InteractionRecord.databaseTableName) WHERE \(interactionColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -1466,7 +1466,7 @@ public extension TSInteraction { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (TSInteraction, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - TSInteraction.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + TSInteraction.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? TSInteraction else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor+SDS.swift b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor+SDS.swift index 456fd4e9bd..6323280a5a 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor+SDS.swift +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor+SDS.swift @@ -210,7 +210,7 @@ public extension OWSMessageContentJob { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -306,7 +306,7 @@ public extension OWSMessageContentJob { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSMessageContentJob.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSMessageContentJob.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(MessageContentJobRecord.databaseTableName) WHERE \(messageContentJobColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -319,7 +319,7 @@ public extension OWSMessageContentJob { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSMessageContentJob, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSMessageContentJob.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSMessageContentJob.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSMessageContentJob else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver+SDS.swift b/SignalServiceKit/src/Messages/OWSMessageReceiver+SDS.swift index a55922feb5..62136eae1a 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver+SDS.swift +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver+SDS.swift @@ -198,7 +198,7 @@ public extension OWSMessageDecryptJob { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -294,7 +294,7 @@ public extension OWSMessageDecryptJob { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSMessageDecryptJob.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSMessageDecryptJob.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(MessageDecryptJobRecord.databaseTableName) WHERE \(messageDecryptJobColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -307,7 +307,7 @@ public extension OWSMessageDecryptJob { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSMessageDecryptJob, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSMessageDecryptJob.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSMessageDecryptJob.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSMessageDecryptJob else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager+SDS.swift b/SignalServiceKit/src/Messages/OWSReadReceiptManager+SDS.swift index 0959dc156f..8d4f2e1fc5 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager+SDS.swift +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager+SDS.swift @@ -199,7 +199,7 @@ public extension TSRecipientReadReceipt { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -295,7 +295,7 @@ public extension TSRecipientReadReceipt { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return TSRecipientReadReceipt.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return TSRecipientReadReceipt.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(RecipientReadReceiptRecord.databaseTableName) WHERE \(recipientReadReceiptColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -308,7 +308,7 @@ public extension TSRecipientReadReceipt { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (TSRecipientReadReceipt, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - TSRecipientReadReceipt.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + TSRecipientReadReceipt.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? TSRecipientReadReceipt else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/Stickers/InstalledSticker+SDS.swift b/SignalServiceKit/src/Messages/Stickers/InstalledSticker+SDS.swift index cb40b856be..656932abc4 100644 --- a/SignalServiceKit/src/Messages/Stickers/InstalledSticker+SDS.swift +++ b/SignalServiceKit/src/Messages/Stickers/InstalledSticker+SDS.swift @@ -199,7 +199,7 @@ public extension InstalledSticker { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -295,7 +295,7 @@ public extension InstalledSticker { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return InstalledSticker.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return InstalledSticker.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(InstalledStickerRecord.databaseTableName) WHERE \(installedStickerColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -308,7 +308,7 @@ public extension InstalledSticker { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (InstalledSticker, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - InstalledSticker.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + InstalledSticker.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? InstalledSticker else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/Stickers/KnownStickerPack+SDS.swift b/SignalServiceKit/src/Messages/Stickers/KnownStickerPack+SDS.swift index d87c362d5a..2138a42adb 100644 --- a/SignalServiceKit/src/Messages/Stickers/KnownStickerPack+SDS.swift +++ b/SignalServiceKit/src/Messages/Stickers/KnownStickerPack+SDS.swift @@ -205,7 +205,7 @@ public extension KnownStickerPack { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -301,7 +301,7 @@ public extension KnownStickerPack { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return KnownStickerPack.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return KnownStickerPack.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(KnownStickerPackRecord.databaseTableName) WHERE \(knownStickerPackColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -314,7 +314,7 @@ public extension KnownStickerPack { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (KnownStickerPack, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - KnownStickerPack.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + KnownStickerPack.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? KnownStickerPack else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Messages/Stickers/StickerPack+SDS.swift b/SignalServiceKit/src/Messages/Stickers/StickerPack+SDS.swift index 7a12b8ac1c..1b25b0423d 100644 --- a/SignalServiceKit/src/Messages/Stickers/StickerPack+SDS.swift +++ b/SignalServiceKit/src/Messages/Stickers/StickerPack+SDS.swift @@ -231,7 +231,7 @@ public extension StickerPack { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -327,7 +327,7 @@ public extension StickerPack { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return StickerPack.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return StickerPack.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(StickerPackRecord.databaseTableName) WHERE \(stickerPackColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -340,7 +340,7 @@ public extension StickerPack { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (StickerPack, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - StickerPack.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + StickerPack.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? StickerPack else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Security/OWSRecipientIdentity+SDS.swift b/SignalServiceKit/src/Security/OWSRecipientIdentity+SDS.swift index f4eced2912..3cec459063 100644 --- a/SignalServiceKit/src/Security/OWSRecipientIdentity+SDS.swift +++ b/SignalServiceKit/src/Security/OWSRecipientIdentity+SDS.swift @@ -216,7 +216,7 @@ public extension OWSRecipientIdentity { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -312,7 +312,7 @@ public extension OWSRecipientIdentity { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSRecipientIdentity.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSRecipientIdentity.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(RecipientIdentityRecord.databaseTableName) WHERE \(recipientIdentityColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -325,7 +325,7 @@ public extension OWSRecipientIdentity { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSRecipientIdentity, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSRecipientIdentity.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSRecipientIdentity.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSRecipientIdentity else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Storage/Jobs/SSKJobRecord+SDS.swift b/SignalServiceKit/src/Storage/Jobs/SSKJobRecord+SDS.swift index dc6c209858..967379d7aa 100644 --- a/SignalServiceKit/src/Storage/Jobs/SSKJobRecord+SDS.swift +++ b/SignalServiceKit/src/Storage/Jobs/SSKJobRecord+SDS.swift @@ -297,7 +297,7 @@ public extension SSKJobRecord { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -393,7 +393,7 @@ public extension SSKJobRecord { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return SSKJobRecord.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return SSKJobRecord.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(JobRecordRecord.databaseTableName) WHERE \(jobRecordColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -406,7 +406,7 @@ public extension SSKJobRecord { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (SSKJobRecord, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - SSKJobRecord.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + SSKJobRecord.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? SSKJobRecord else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Util/ExperienceUpgrade+SDS.swift b/SignalServiceKit/src/Util/ExperienceUpgrade+SDS.swift index 4c9f6900d7..d2bb0e3714 100644 --- a/SignalServiceKit/src/Util/ExperienceUpgrade+SDS.swift +++ b/SignalServiceKit/src/Util/ExperienceUpgrade+SDS.swift @@ -183,7 +183,7 @@ public extension ExperienceUpgrade { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -279,7 +279,7 @@ public extension ExperienceUpgrade { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return ExperienceUpgrade.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return ExperienceUpgrade.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(ExperienceUpgradeRecord.databaseTableName) WHERE \(experienceUpgradeColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -292,7 +292,7 @@ public extension ExperienceUpgrade { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (ExperienceUpgrade, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - ExperienceUpgrade.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + ExperienceUpgrade.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? ExperienceUpgrade else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Util/OWSBackupFragment+SDS.swift b/SignalServiceKit/src/Util/OWSBackupFragment+SDS.swift index 865ed6cc76..ae83a08289 100644 --- a/SignalServiceKit/src/Util/OWSBackupFragment+SDS.swift +++ b/SignalServiceKit/src/Util/OWSBackupFragment+SDS.swift @@ -222,7 +222,7 @@ public extension OWSBackupFragment { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -318,7 +318,7 @@ public extension OWSBackupFragment { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSBackupFragment.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSBackupFragment.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(BackupFragmentRecord.databaseTableName) WHERE \(backupFragmentColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -331,7 +331,7 @@ public extension OWSBackupFragment { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSBackupFragment, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSBackupFragment.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSBackupFragment.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSBackupFragment else { owsFailDebug("unexpected object: \(type(of: object))") return diff --git a/SignalServiceKit/src/Util/OWSUserProfile+SDS.swift b/SignalServiceKit/src/Util/OWSUserProfile+SDS.swift index fed646d0f3..78e4ed0c0c 100644 --- a/SignalServiceKit/src/Util/OWSUserProfile+SDS.swift +++ b/SignalServiceKit/src/Util/OWSUserProfile+SDS.swift @@ -217,7 +217,7 @@ public extension OWSUserProfile { switch transaction.writeTransaction { case .yapWrite(let ydbTransaction): - remove(with: ydbTransaction) + ydb_remove(with: ydbTransaction) case .grdbWrite(let grdbTransaction): do { let record = try asRecord() @@ -313,7 +313,7 @@ public extension OWSUserProfile { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - return OWSUserProfile.fetch(uniqueId: uniqueId, transaction: ydbTransaction) + return OWSUserProfile.ydb_fetch(uniqueId: uniqueId, transaction: ydbTransaction) case .grdbRead(let grdbTransaction): let sql = "SELECT * FROM \(UserProfileRecord.databaseTableName) WHERE \(userProfileColumn: .uniqueId) = ?" return grdbFetchOne(sql: sql, arguments: [uniqueId], transaction: grdbTransaction) @@ -326,7 +326,7 @@ public extension OWSUserProfile { class func anyEnumerate(transaction: SDSAnyReadTransaction, block: @escaping (OWSUserProfile, UnsafeMutablePointer) -> Void) { switch transaction.readTransaction { case .yapRead(let ydbTransaction): - OWSUserProfile.enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in + OWSUserProfile.ydb_enumerateCollectionObjects(with: ydbTransaction) { (object, stop) in guard let value = object as? OWSUserProfile else { owsFailDebug("unexpected object: \(type(of: object))") return From 3c112b7da539233c28250204ffcc32b68ac655ed Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 24 Jun 2019 15:52:26 -0400 Subject: [PATCH 3/4] Respond to CR. --- .../util/Backup/OWSBackupLazyRestore.swift | 5 +- .../ConversationViewItemTest.m | 135 +++++++----------- .../Messages/Attachments/TSAttachmentStream.m | 1 + .../src/Messages/Interactions/TSMessage.m | 2 - .../src/Messages/OWSMessageSender.m | 4 +- 5 files changed, 60 insertions(+), 87 deletions(-) diff --git a/Signal/src/util/Backup/OWSBackupLazyRestore.swift b/Signal/src/util/Backup/OWSBackupLazyRestore.swift index bb77c17a9a..79f61d8df9 100644 --- a/Signal/src/util/Backup/OWSBackupLazyRestore.swift +++ b/Signal/src/util/Backup/OWSBackupLazyRestore.swift @@ -143,9 +143,8 @@ public class BackupLazyRestore: NSObject { complete(errorCount: errorCount) return } - var attachment: TSAttachment? - databaseStorage.read { (transaction) in - attachment = TSAttachment.anyFetch(uniqueId: attachmentId, transaction: transaction) + let attachment = databaseStorage.readReturningResult { (transaction) in + return TSAttachment.anyFetch(uniqueId: attachmentId, transaction: transaction) } guard let attachmentPointer = attachment as? TSAttachmentPointer else { Logger.warn("could not load attachment.") diff --git a/Signal/test/ViewControllers/ConversationViewItemTest.m b/Signal/test/ViewControllers/ConversationViewItemTest.m index eef7133ec2..100b342fba 100644 --- a/Signal/test/ViewControllers/ConversationViewItemTest.m +++ b/Signal/test/ViewControllers/ConversationViewItemTest.m @@ -13,65 +13,6 @@ #import #import -@interface TSMessage (ConversationViewItemTest) - -@end - -#pragma mark - - -@implementation TSMessage (ConversationViewItemTest) - -+ (SDSDatabaseStorage *)databaseStorage -{ - return SDSDatabaseStorage.shared; -} - -+ (nullable TSMessage *)anyFetchWithUniqueId:(NSString *)uniqueId -{ - __block TSInteraction *_Nullable instance; - [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { - instance = [TSInteraction anyFetchWithUniqueId:uniqueId transaction:transaction]; - }]; - if (!instance) { - return nil; - } - if (![instance isKindOfClass:[TSMessage class]]) { - OWSFailDebug(@"Unexpected object type: %@", [instance class]); - return nil; - } - return (TSMessage *)instance; -} - -@end - -#pragma mark - - -@interface TSAttachment (ConversationViewItemTest) - -@end - -#pragma mark - - -@implementation TSAttachment (ConversationViewItemTest) - -+ (SDSDatabaseStorage *)databaseStorage -{ - return SDSDatabaseStorage.shared; -} - -+ (nullable TSAttachment *)anyFetchWithUniqueId:(NSString *)uniqueId -{ - __block TSAttachment *_Nullable instance; - [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { - instance = [TSAttachment anyFetchWithUniqueId:uniqueId transaction:transaction]; - }]; - return instance; -} - -@end - -#pragma mark - - @interface ConversationViewItemTest : SignalBaseTest @property TSThread *thread; @@ -83,6 +24,11 @@ @implementation ConversationViewItemTest +- (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + - (void)setUp { [super setUp]; @@ -173,9 +119,9 @@ { ConversationInteractionViewItem *viewItem = self.textViewItem; - XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); [viewItem deleteAction]; - XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); } - (void)testPerformDeleteActionWithPhotoMessage @@ -185,18 +131,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; + TSAttachment *_Nullable attachment = [self fetchAttachmentWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -207,18 +153,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; + TSAttachment *_Nullable attachment = [self fetchAttachmentWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -229,18 +175,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; + TSAttachment *_Nullable attachment = [self fetchAttachmentWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -251,18 +197,18 @@ XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count); NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject; XCTAssertNotNil(attachmentId); - TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId]; + TSAttachment *_Nullable attachment = [self fetchAttachmentWithUniqueId:attachmentId]; XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]); TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment; NSString *_Nullable filePath = attachmentStream.originalFilePath; XCTAssertNotNil(filePath); - XCTAssertNotNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNotNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]); [viewItem deleteAction]; - XCTAssertNil([TSMessage anyFetchWithUniqueId:viewItem.interaction.uniqueId]); - XCTAssertNil([TSAttachment anyFetchWithUniqueId:attachmentId]); + XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]); + XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]); XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]); } @@ -334,4 +280,31 @@ // It's easier to create this stub method than to suppress the "unknown selector" build warnings. } +#pragma mark - Helpers + +- (nullable TSMessage *)fetchMessageWithUniqueId:(NSString *)uniqueId +{ + __block TSInteraction *_Nullable instance; + [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { + instance = [TSInteraction anyFetchWithUniqueId:uniqueId transaction:transaction]; + }]; + if (!instance) { + return nil; + } + if (![instance isKindOfClass:[TSMessage class]]) { + OWSFailDebug(@"Unexpected object type: %@", [instance class]); + return nil; + } + return (TSMessage *)instance; +} + +- (nullable TSAttachment *)fetchAttachmentWithUniqueId:(NSString *)uniqueId +{ + __block TSAttachment *_Nullable instance; + [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { + instance = [TSAttachment anyFetchWithUniqueId:uniqueId transaction:transaction]; + }]; + return instance; +} + @end diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index e0736dee7d..96a64683b5 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -413,6 +413,7 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); } - (void)anyDidRemoveWithTransaction:(SDSAnyWriteTransaction *)transaction +{ [super anyDidRemoveWithTransaction:transaction]; [self removeFile]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index cfa634a945..ee4047cbfe 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -311,8 +311,6 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe TSAttachment *_Nullable attachment = [TSAttachment anyFetchWithUniqueId:attachmentId transaction:transaction]; if (attachment) { [attachments addObject:attachment]; - } else { - OWSFailDebug(@"Missing attachment: %@", attachmentId); } } return [attachments copy]; diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 8ce8fdc371..017b525543 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1963,10 +1963,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; outgoingMessage.attachmentFilenameMap[attachmentStream.uniqueId] = attachmentStream.sourceFilename; } } + + [outgoingMessage saveWithTransaction:transaction]; + for (TSAttachmentStream *attachmentStream in attachmentStreams) { [attachmentStream anyInsertWithTransaction:transaction.asAnyWrite]; } - [outgoingMessage saveWithTransaction:transaction]; }]; completionHandler(nil); From 2beb81631483a4c4335ce14b7deaa6a1f57c0114 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 24 Jun 2019 16:02:18 -0400 Subject: [PATCH 4/4] First of many fixes for attachment sending. --- .../src/Messages/OWSMessageSender.m | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 017b525543..9b386e3230 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -352,6 +352,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; return SDSDatabaseStorage.shared; } ++ (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + #pragma mark - - (NSOperationQueue *)sendingQueueForMessage:(TSOutgoingMessage *)message @@ -1956,18 +1961,27 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [attachmentStreams addObject:attachmentStream]; } - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - for (TSAttachmentStream *attachmentStream in attachmentStreams) { - [outgoingMessage.attachmentIds addObject:attachmentStream.uniqueId]; - if (attachmentStream.sourceFilename) { - outgoingMessage.attachmentFilenameMap[attachmentStream.uniqueId] = attachmentStream.sourceFilename; - } - } + [OWSMessageSender.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { + [outgoingMessage + anyUpdateWithTransaction:transaction + block:^(TSInteraction *interaction) { + if (![interaction isKindOfClass:[TSOutgoingMessage class]]) { + OWSFailDebug(@"Object has unexpected type: %@", [interaction class]); + return; + } + TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)interaction; + for (TSAttachmentStream *attachmentStream in attachmentStreams) { + [outgoingMessage.attachmentIds addObject:attachmentStream.uniqueId]; - [outgoingMessage saveWithTransaction:transaction]; + if (attachmentStream.sourceFilename) { + outgoingMessage.attachmentFilenameMap[attachmentStream.uniqueId] + = attachmentStream.sourceFilename; + } + } + }]; for (TSAttachmentStream *attachmentStream in attachmentStreams) { - [attachmentStream anyInsertWithTransaction:transaction.asAnyWrite]; + [attachmentStream anyInsertWithTransaction:transaction]; } }];