mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			230 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			230 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Objective-C
		
	
| //
 | |
| //  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | |
| //
 | |
| 
 | |
| #import "TSYapDatabaseObject.h"
 | |
| #import <YapDatabase/YapDatabaseTransaction.h>
 | |
| #import <SessionUtilitiesKit/SessionUtilitiesKit-Swift.h>
 | |
| 
 | |
| NS_ASSUME_NONNULL_BEGIN
 | |
| 
 | |
| @implementation TSYapDatabaseObject
 | |
| 
 | |
| - (instancetype)init
 | |
| {
 | |
|     return [self initWithUniqueId:[[NSUUID UUID] UUIDString]];
 | |
| }
 | |
| 
 | |
| - (instancetype)initWithUniqueId:(NSString *_Nullable)aUniqueId
 | |
| {
 | |
|     self = [super init];
 | |
|     if (!self) {
 | |
|         return self;
 | |
|     }
 | |
| 
 | |
|     _uniqueId = aUniqueId;
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| - (nullable instancetype)initWithCoder:(NSCoder *)coder
 | |
| {
 | |
|     self = [super initWithCoder:coder];
 | |
|     if (!self) {
 | |
|         return self;
 | |
|     }
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
 | |
| {
 | |
|     [transaction setObject:self forKey:self.uniqueId inCollection:[[self class] collection]];
 | |
| }
 | |
| 
 | |
| - (void)save
 | |
| {
 | |
|     [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
 | |
|         [self saveWithTransaction:transaction];
 | |
|     }];
 | |
| }
 | |
| 
 | |
| - (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock
 | |
| {
 | |
|     [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
 | |
|         [self saveWithTransaction:transaction];
 | |
|     } completion:completionBlock];
 | |
| }
 | |
| 
 | |
| - (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
 | |
| {
 | |
|     [transaction touchObjectForKey:self.uniqueId inCollection:[self.class collection]];
 | |
| }
 | |
| 
 | |
| - (void)touch
 | |
| {
 | |
|     [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
 | |
|         [self touchWithTransaction:transaction];
 | |
|     }];
 | |
| }
 | |
| 
 | |
| - (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
 | |
| {
 | |
|     [transaction removeObjectForKey:self.uniqueId inCollection:[[self class] collection]];
 | |
| }
 | |
| 
 | |
| - (void)remove
 | |
| {
 | |
|     [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
 | |
|         [self removeWithTransaction:transaction];
 | |
|     }];
 | |
| }
 | |
| 
 | |
| - (YapDatabaseConnection *)dbReadConnection
 | |
| {
 | |
|     return [[self class] dbReadConnection];
 | |
| }
 | |
| 
 | |
| - (YapDatabaseConnection *)dbReadWriteConnection
 | |
| {
 | |
|     return [[self class] dbReadWriteConnection];
 | |
| }
 | |
| 
 | |
| #pragma mark Class Methods
 | |
| 
 | |
| + (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey
 | |
| {
 | |
|     if ([propertyKey isEqualToString:@"TAG"]) {
 | |
|         return MTLPropertyStorageNone;
 | |
|     } else {
 | |
|         return [super storageBehaviorForPropertyWithKey:propertyKey];
 | |
|     }
 | |
| }
 | |
| 
 | |
| + (YapDatabaseConnection *)dbReadConnection
 | |
| {
 | |
|     // We use TSYapDatabaseObject's dbReadWriteConnection (not OWSPrimaryStorage's
 | |
|     // dbReadConnection) for consistency, since we tend to [TSYapDatabaseObject
 | |
|     // save] and want to write to the same connection we read from.  To get true
 | |
|     // consistency, we'd want to update entities by reading & writing from within
 | |
|     // the same transaction, but that'll be a big refactor.
 | |
|     return self.dbReadWriteConnection;
 | |
| }
 | |
| 
 | |
| + (YapDatabaseConnection *)dbReadWriteConnection
 | |
| {
 | |
|     return SNUtilitiesKitConfiguration.shared.owsPrimaryStorage.dbReadWriteConnection;
 | |
| }
 | |
| 
 | |
| + (NSString *)collection
 | |
| {
 | |
|     return NSStringFromClass([self class]);
 | |
| }
 | |
| 
 | |
| + (NSUInteger)numberOfKeysInCollection
 | |
| {
 | |
|     __block NSUInteger count;
 | |
|     [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) {
 | |
|         count = [self numberOfKeysInCollectionWithTransaction:transaction];
 | |
|     }];
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| + (NSUInteger)numberOfKeysInCollectionWithTransaction:(YapDatabaseReadTransaction *)transaction
 | |
| {
 | |
|     return [transaction numberOfKeysInCollection:[self collection]];
 | |
| }
 | |
| 
 | |
| + (NSArray *)allObjectsInCollection
 | |
| {
 | |
|     __block NSMutableArray *all = [[NSMutableArray alloc] initWithCapacity:[self numberOfKeysInCollection]];
 | |
|     [self enumerateCollectionObjectsUsingBlock:^(id object, BOOL *stop) {
 | |
|         [all addObject:object];
 | |
|     }];
 | |
|     return [all copy];
 | |
| }
 | |
| 
 | |
| + (void)enumerateCollectionObjectsUsingBlock:(void (^)(id object, BOOL *stop))block
 | |
| {
 | |
|     [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) {
 | |
|         [self enumerateCollectionObjectsWithTransaction:transaction usingBlock:block];
 | |
|     }];
 | |
| }
 | |
| 
 | |
| + (void)enumerateCollectionObjectsWithTransaction:(YapDatabaseReadTransaction *)transaction
 | |
|                                        usingBlock:(void (^)(id object, BOOL *stop))block
 | |
| {
 | |
|     // Ignoring most of the YapDB parameters, and just passing through the ones we usually use.
 | |
|     void (^yapBlock)(NSString *key, id object, id metadata, BOOL *stop)
 | |
|         = ^void(NSString *key, id object, id metadata, BOOL *stop) {
 | |
|               block(object, stop);
 | |
|           };
 | |
| 
 | |
|     [transaction enumerateRowsInCollection:[self collection] usingBlock:yapBlock];
 | |
| }
 | |
| 
 | |
| + (void)removeAllObjectsInCollection
 | |
| {
 | |
|     [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
 | |
|         [transaction removeAllObjectsInCollection:[self collection]];
 | |
|     }];
 | |
| }
 | |
| 
 | |
| + (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID
 | |
|                                      transaction:(YapDatabaseReadTransaction *)transaction
 | |
| {
 | |
|     return [transaction objectForKey:uniqueID inCollection:[self collection]];
 | |
| }
 | |
| 
 | |
| + (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID
 | |
| {
 | |
|     __block id _Nullable object = nil;
 | |
|     [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) {
 | |
|         object = [transaction objectForKey:uniqueID inCollection:[self collection]];
 | |
|     }];
 | |
|     return object;
 | |
| }
 | |
| 
 | |
| #pragma mark - Update With...
 | |
| 
 | |
| - (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction
 | |
|                            changeBlock:(void (^)(id))changeBlock
 | |
| {
 | |
|     changeBlock(self);
 | |
| 
 | |
|     NSString *collection = [[self class] collection];
 | |
|     id latestInstance = [transaction objectForKey:self.uniqueId inCollection:collection];
 | |
|     if (latestInstance) {
 | |
|         changeBlock(latestInstance);
 | |
|         [latestInstance saveWithTransaction:transaction];
 | |
|     }
 | |
| }
 | |
| 
 | |
| #pragma mark Reload
 | |
| 
 | |
| - (void)reload
 | |
| {
 | |
|     [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
 | |
|         [self reloadWithTransaction:transaction];
 | |
|     }];
 | |
| }
 | |
| 
 | |
| - (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction
 | |
| {
 | |
|     [self reloadWithTransaction:transaction ignoreMissing:NO];
 | |
| }
 | |
| 
 | |
| - (void)reloadWithTransaction:(YapDatabaseReadTransaction *)transaction ignoreMissing:(BOOL)ignoreMissing
 | |
| {
 | |
|     TSYapDatabaseObject *latest = [[self class] fetchObjectWithUniqueID:self.uniqueId transaction:transaction];
 | |
|     if (!latest) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     [self setValuesForKeysWithDictionary:latest.dictionaryValue];
 | |
| }
 | |
| 
 | |
| @end
 | |
| 
 | |
| NS_ASSUME_NONNULL_END
 |