Merge branch 'charlesmchen/noYdbAttachments'

This commit is contained in:
Matthew Chen 2019-06-24 16:02:51 -04:00
commit 72d0efce03
68 changed files with 775 additions and 469 deletions

View File

@ -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<ObjCBool>) -> 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

View File

@ -28,7 +28,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EF7BE58B1F949AF31E4AF4FD37150A86"
BlueprintIdentifier = "88466E9845300D40B5E5E16190FCF608"
BuildableName = "SignalServiceKit.framework"
BlueprintName = "SignalServiceKit"
ReferencedContainer = "container:Pods/Pods.xcodeproj">
@ -56,7 +56,7 @@
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2349E04BB99C0118E8F578CCBEAAC665"
BlueprintIdentifier = "59FFD47D610248F8216F6279B325E3BF"
BuildableName = "SignalServiceKit-Unit-Tests.xctest"
BlueprintName = "SignalServiceKit-Unit-Tests"
ReferencedContainer = "container:Pods/Pods.xcodeproj">
@ -66,7 +66,7 @@
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3AC929F2E4978F42ED9E9EA232D7247B"
BlueprintIdentifier = "1D5FBD12E05B627E46927DBA76985355"
BuildableName = "SignalCoreKit-Unit-Tests.xctest"
BlueprintName = "SignalCoreKit-Unit-Tests"
ReferencedContainer = "container:Pods/Pods.xcodeproj">

View File

@ -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];

View File

@ -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<TSAttachmentStream *> *_Nonnull attachmentStreams) {
// Do nothing.
}

View File

@ -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<TSAttachmentStream *> *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) {

View File

@ -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<TSAttachment *> *mediaAttachments =
[message mediaAttachmentsWithTransaction:transaction.transitional_yapReadTransaction];
NSArray<ConversationMediaAlbumItem *> *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<TSAttachment *> *mediaAttachments = [message mediaAttachmentsWithTransaction:transaction];
NSArray<ConversationMediaAlbumItem *> *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<TSAttachment *> *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<TSAttachment *> *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.");

View File

@ -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<TSAttachmentStream *> *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.
}];
}
}];
}

View File

@ -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");
}

View File

@ -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
}

View File

@ -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.")

View File

@ -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,10 @@ public class BackupLazyRestore: NSObject {
complete(errorCount: errorCount)
return
}
guard let attachmentPointer = TSAttachment.fetch(uniqueId: attachmentId) as? TSAttachmentPointer else {
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.")
// Not necessarily an error.
// The attachment might have been deleted since the job began.

View File

@ -20,8 +20,15 @@
@end
#pragma mark -
@implementation ConversationViewItemTest
- (SDSDatabaseStorage *)databaseStorage
{
return SDSDatabaseStorage.shared;
}
- (void)setUp
{
[super setUp];
@ -112,9 +119,9 @@
{
ConversationInteractionViewItem *viewItem = self.textViewItem;
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
}
- (void)testPerformDeleteActionWithPhotoMessage
@ -124,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 fetchObjectWithUniqueID: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 fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
@ -146,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 fetchObjectWithUniqueID: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 fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
@ -168,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 fetchObjectWithUniqueID: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 fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
@ -190,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 fetchObjectWithUniqueID: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 fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNotNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNotNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertNil([self fetchMessageWithUniqueId:viewItem.interaction.uniqueId]);
XCTAssertNil([self fetchAttachmentWithUniqueId:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
@ -273,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

View File

@ -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:^{

View File

@ -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)

View File

@ -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]]) {

View File

@ -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];
}
}

View File

@ -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)

View File

@ -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<ObjCBool>) -> 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

View File

@ -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);
}];

View File

@ -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);

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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: %@",

View File

@ -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<TSAttachmentStream *> *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<TSAttachmentStream *> *attachmentStreams))success
failure:(void (^)(NSError *error))failure;

View File

@ -25,7 +25,6 @@
#import <SignalCoreKit/Cryptography.h>
#import <SignalServiceKit/OWSSignalService.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabaseConnection.h>
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<TSAttachmentStream *> *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<TSAttachmentStream *> *attachmentStreams))success
failure:(void (^)(NSError *error))failure
{
@ -161,7 +160,7 @@ typedef void (^AttachmentDownloadFailure)(NSError *error);
- (void)downloadAttachmentsForMessage:(TSMessage *)message
attachments:(NSArray<TSAttachment *> *)attachments
transaction:(YapDatabaseReadTransaction *)transaction
transaction:(SDSAnyReadTransaction *)transaction
success:(void (^)(NSArray<TSAttachmentStream *> *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];

View File

@ -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<ObjCBool>) -> 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

View File

@ -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

View File

@ -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

View File

@ -7,8 +7,6 @@
#import "TSAttachmentStream.h"
#import <SignalServiceKit/MimeTypeUtil.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseTransaction.h>
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

View File

@ -14,7 +14,6 @@ NS_ASSUME_NONNULL_BEGIN
@class SSKProtoAttachmentPointer;
@class TSAttachmentPointer;
@class YapDatabaseReadWriteTransaction;
typedef void (^OWSThumbnailSuccess)(UIImage *image);
typedef void (^OWSThumbnailFailure)(void);

View File

@ -10,7 +10,6 @@
#import <AVFoundation/AVFoundation.h>
#import <SignalCoreKit/Threading.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabase.h>
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
@ -619,27 +632,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 +911,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 +966,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);

View File

@ -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);

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Mantle/MTLModel.h>
@ -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<OWSContactAddress *> *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

View File

@ -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 {

View File

@ -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
}

View File

@ -12,6 +12,7 @@
#import "TSDatabaseSecondaryIndexes.h"
#import "TSGroupThread.h"
#import <SignalCoreKit/NSDate+OWS.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabaseConnection.h>
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;
}

View File

@ -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<ObjCBool>) -> 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

View File

@ -93,10 +93,10 @@ NS_SWIFT_NAME(init(uniqueId:receivedAtTimestamp:sortId:timestamp:uniqueThreadId:
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (BOOL)hasAttachments;
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (NSArray<TSAttachment *> *)mediaAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (NSArray<TSAttachment *> *)allAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction;
- (NSArray<TSAttachment *> *)mediaAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction;
- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(SDSAnyReadTransaction *)transaction;
- (NSArray<TSAttachment *> *)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;

View File

@ -293,23 +293,22 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe
return [NSSet setWithArray:result].allObjects;
}
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction
{
return [TSMessage attachmentsWithIds:self.attachmentIds transaction:transaction];
}
- (NSArray<TSAttachment *> *)allAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction
- (NSArray<TSAttachment *> *)allAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction
{
return [TSMessage attachmentsWithIds:self.allAttachmentIds transaction:transaction];
}
+ (NSArray<TSAttachment *> *)attachmentsWithIds:(NSArray<NSString *> *)attachmentIds
transaction:(YapDatabaseReadTransaction *)transaction
transaction:(SDSAnyReadTransaction *)transaction
{
NSMutableArray<TSAttachment *> *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];
}
@ -317,7 +316,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe
return [attachments copy];
}
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction
contentType:(NSString *)contentType
{
NSArray<TSAttachment *> *attachments = [self bodyAttachmentsWithTransaction:transaction];
@ -327,7 +326,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe
}]];
}
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction
- (NSArray<TSAttachment *> *)bodyAttachmentsWithTransaction:(SDSAnyReadTransaction *)transaction
exceptContentType:(NSString *)contentType
{
NSArray<TSAttachment *> *attachments = [self bodyAttachmentsWithTransaction:transaction];
@ -367,17 +366,17 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe
}
}
- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction
- (nullable TSAttachment *)oversizeTextAttachmentWithTransaction:(SDSAnyReadTransaction *)transaction
{
return [self bodyAttachmentsWithTransaction:transaction contentType:OWSMimeTypeOversizeTextMessage].firstObject;
}
- (NSArray<TSAttachment *> *)mediaAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction
- (NSArray<TSAttachment *> *)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 +404,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 +432,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 +447,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 +474,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe
}
}
// TODO: Convert to Any.
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// StickerManager does reference counting of "known" sticker packs.
@ -501,6 +490,7 @@ perMessageExpirationDurationSeconds:(unsigned int)perMessageExpirationDurationSe
[super saveWithTransaction:transaction];
}
// TODO: Convert to Any.
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// StickerManager does reference counting of "known" sticker packs.

View File

@ -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];
};
}];
}

View File

@ -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<TSAttachmentStream *> *)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

View File

@ -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<TSInteraction *> *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<TSAttachmentStream *> *)createThumbnailAttachmentsIfNecessaryWithTransaction:
(YapDatabaseReadWriteTransaction *)transaction
(SDSAnyWriteTransaction *)transaction
{
NSMutableArray<TSAttachmentStream *> *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];
}

View File

@ -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<ObjCBool>) -> 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

View File

@ -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 <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseQuery.h>
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
@ -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++;
}
}

View File

@ -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<TSAttachmentStream *> *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);
}

View File

@ -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<ObjCBool>) -> 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

View File

@ -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();
@ -343,6 +352,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return SDSDatabaseStorage.shared;
}
+ (SDSDatabaseStorage *)databaseStorage
{
return SDSDatabaseStorage.shared;
}
#pragma mark -
- (NSOperationQueue *)sendingQueueForMessage:(TSOutgoingMessage *)message
@ -1863,14 +1877,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<TSAttachmentStream *> *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 +1894,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 +1904,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,16 +1961,27 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[attachmentStreams addObject:attachmentStream];
}
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[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];
if (attachmentStream.sourceFilename) {
outgoingMessage.attachmentFilenameMap[attachmentStream.uniqueId]
= attachmentStream.sourceFilename;
}
}
}];
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];
}
}];

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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)
}
}

View File

@ -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<ObjCBool>) -> 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

View File

@ -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) {

View File

@ -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<ObjCBool>) -> 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

View File

@ -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):

View File

@ -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()

View File

@ -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<ObjCBool>) -> 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

View File

@ -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(), ^{

View File

@ -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

View File

@ -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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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<ObjCBool>) -> 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

View File

@ -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,