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
 |