// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "OWSResaveCollectionDBMigration.h" #import #import #import NS_ASSUME_NONNULL_BEGIN @implementation OWSResaveCollectionDBMigration - (void)resaveDBCollection:(NSString *)collection filter:(nullable DBRecordFilterBlock)filter dbConnection:(YapDatabaseConnection *)dbConnection completion:(OWSDatabaseMigrationCompletion)completion { OWSAssertDebug(collection.length > 0); OWSAssertDebug(dbConnection); OWSAssertDebug(completion); NSMutableArray *recordIds = [NSMutableArray new]; [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [recordIds addObjectsFromArray:[transaction allKeysInCollection:collection]]; OWSLogInfo(@"Migrating %lu records from: %@.", (unsigned long)recordIds.count, collection); } completion:^{ [self resaveBatch:recordIds collection:collection filter:filter dbConnection:dbConnection completion:completion]; }]; } - (void)resaveBatch:(NSMutableArray *)recordIds collection:(NSString *)collection filter:(nullable DBRecordFilterBlock)filter dbConnection:(YapDatabaseConnection *)dbConnection completion:(OWSDatabaseMigrationCompletion)completion { OWSAssertDebug(recordIds); OWSAssertDebug(collection.length > 0); OWSAssertDebug(dbConnection); OWSAssertDebug(completion); OWSLogVerbose(@"%lu", (unsigned long)recordIds.count); if (recordIds.count < 1) { completion(); return; } [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { const int kBatchSize = 1000; for (int i = 0; i < kBatchSize && recordIds.count > 0; i++) { NSString *messageId = [recordIds lastObject]; [recordIds removeLastObject]; id record = [transaction objectForKey:messageId inCollection:collection]; if (filter && !filter(record)) { continue; } TSYapDatabaseObject *entity = (TSYapDatabaseObject *)record; [entity saveWithTransaction:transaction]; } } completion:^{ // Process the next batch. [self resaveBatch:recordIds collection:collection filter:filter dbConnection:dbConnection completion:completion]; }]; } @end NS_ASSUME_NONNULL_END