|  |  |  | @ -5,6 +5,7 @@ | 
		
	
		
			
				|  |  |  |  | #import "OWSDisappearingMessagesFinder.h" | 
		
	
		
			
				|  |  |  |  | #import "NSDate+OWS.h" | 
		
	
		
			
				|  |  |  |  | #import "OWSPrimaryStorage.h" | 
		
	
		
			
				|  |  |  |  | #import "TSIncomingMessage.h" | 
		
	
		
			
				|  |  |  |  | #import "TSMessage.h" | 
		
	
		
			
				|  |  |  |  | #import "TSOutgoingMessage.h" | 
		
	
		
			
				|  |  |  |  | #import "TSThread.h" | 
		
	
	
		
			
				
					|  |  |  | @ -41,6 +42,44 @@ static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_mess | 
		
	
		
			
				|  |  |  |  |     return [messageIds copy]; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | - (NSArray<NSString *> *)fetchMessageIdsWhichFailedToStartExpiring:(YapDatabaseReadTransaction *_Nonnull)transaction | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     OWSAssert(transaction); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     NSMutableArray<NSString *> *messageIds = [NSMutableArray new]; | 
		
	
		
			
				|  |  |  |  |     NSString *formattedString = | 
		
	
		
			
				|  |  |  |  |         [NSString stringWithFormat:@"WHERE %@ = 0", OWSDisappearingMessageFinderExpiresAtColumn]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     YapDatabaseQuery *query = [YapDatabaseQuery queryWithFormat:formattedString]; | 
		
	
		
			
				|  |  |  |  |     [[transaction ext:OWSDisappearingMessageFinderExpiresAtIndex] | 
		
	
		
			
				|  |  |  |  |         enumerateKeysAndObjectsMatchingQuery:query | 
		
	
		
			
				|  |  |  |  |                                   usingBlock:^void(NSString *collection, NSString *key, id object, BOOL *stop) { | 
		
	
		
			
				|  |  |  |  |                                       if (![object isKindOfClass:[TSMessage class]]) { | 
		
	
		
			
				|  |  |  |  |                                           OWSFail(@"%@ in %s object was unexpected class: %@", | 
		
	
		
			
				|  |  |  |  |                                               self.logTag, | 
		
	
		
			
				|  |  |  |  |                                               __PRETTY_FUNCTION__, | 
		
	
		
			
				|  |  |  |  |                                               object); | 
		
	
		
			
				|  |  |  |  |                                           return; | 
		
	
		
			
				|  |  |  |  |                                       } | 
		
	
		
			
				|  |  |  |  |                                        | 
		
	
		
			
				|  |  |  |  |                                       // We'll need to update if we ever support expiring other message types | 
		
	
		
			
				|  |  |  |  |                                       OWSAssert([object isKindOfClass:[TSOutgoingMessage class]] || [object isKindOfClass:[TSIncomingMessage class]]); | 
		
	
		
			
				|  |  |  |  |                                        | 
		
	
		
			
				|  |  |  |  |                                       TSMessage *message = (TSMessage *)object; | 
		
	
		
			
				|  |  |  |  |                                       if ([message shouldStartExpireTimerWithTransaction:transaction]) { | 
		
	
		
			
				|  |  |  |  |                                           if ([message isKindOfClass:[TSIncomingMessage class]]) { | 
		
	
		
			
				|  |  |  |  |                                               TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message; | 
		
	
		
			
				|  |  |  |  |                                               if (!incomingMessage.wasRead) { | 
		
	
		
			
				|  |  |  |  |                                                   return; | 
		
	
		
			
				|  |  |  |  |                                               } | 
		
	
		
			
				|  |  |  |  |                                           } | 
		
	
		
			
				|  |  |  |  |                                           [messageIds addObject:key]; | 
		
	
		
			
				|  |  |  |  |                                       } | 
		
	
		
			
				|  |  |  |  |                                   }]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return [messageIds copy]; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | - (NSArray<NSString *> *)fetchExpiredMessageIdsWithTransaction:(YapDatabaseReadTransaction *_Nonnull)transaction | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     OWSAssert(transaction); | 
		
	
	
		
			
				
					|  |  |  | @ -99,11 +138,33 @@ static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_mess | 
		
	
		
			
				|  |  |  |  |         if ([message isKindOfClass:[TSMessage class]]) { | 
		
	
		
			
				|  |  |  |  |             block(message); | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |             DDLogError(@"%@ unexpected object: %@", self.logTag, message); | 
		
	
		
			
				|  |  |  |  |             OWSProdLogAndFail(@"%@ unexpected object: %@", self.logTag, message); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | - (void)enumerateMessagesWhichFailedToStartExpiringWithBlock:(void (^_Nonnull)(TSMessage *message))block | 
		
	
		
			
				|  |  |  |  |                                                  transaction:(YapDatabaseReadTransaction *)transaction | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     OWSAssert(transaction); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     for (NSString *expiringMessageId in [self fetchMessageIdsWhichFailedToStartExpiring:transaction]) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         TSMessage *_Nullable message = [TSMessage fetchObjectWithUniqueID:expiringMessageId transaction:transaction]; | 
		
	
		
			
				|  |  |  |  |         if (![message isKindOfClass:[TSMessage class]]) { | 
		
	
		
			
				|  |  |  |  |             OWSProdLogAndFail(@"%@ unexpected object: %@", self.logTag, message); | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (![message shouldStartExpireTimerWithTransaction:transaction]) { | 
		
	
		
			
				|  |  |  |  |             OWSProdLogAndFail(@"%@ object: %@ shouldn't expire.", self.logTag, message); | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         block(message); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /** | 
		
	
		
			
				|  |  |  |  |  * Don't use this in production. Useful for testing. | 
		
	
		
			
				|  |  |  |  |  * We don't want to instantiate potentially many messages at once. | 
		
	
	
		
			
				
					|  |  |  | @ -177,7 +238,7 @@ static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_mess | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             TSMessage *message = (TSMessage *)object; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (![message shouldStartExpireTimer:transaction]) { | 
		
	
		
			
				|  |  |  |  |             if (![message shouldStartExpireTimerWithTransaction:transaction]) { | 
		
	
		
			
				|  |  |  |  |                 return; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |