mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
250 lines
6.9 KiB
Objective-C
250 lines
6.9 KiB
Objective-C
//
|
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
#import "TSYapDatabaseObject.h"
|
|
#import "OWSPrimaryStorage.h"
|
|
#import "SSKEnvironment.h"
|
|
#import <YapDatabase/YapDatabaseTransaction.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
|
|
{
|
|
[[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
[self saveWithTransaction:transaction];
|
|
}];
|
|
}
|
|
|
|
- (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock
|
|
{
|
|
[[self dbReadWriteConnection] asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
|
[self saveWithTransaction:transaction];
|
|
}
|
|
completionBlock:completionBlock];
|
|
}
|
|
|
|
- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
{
|
|
[transaction touchObjectForKey:self.uniqueId inCollection:[self.class collection]];
|
|
}
|
|
|
|
- (void)touch
|
|
{
|
|
[[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
[self touchWithTransaction:transaction];
|
|
}];
|
|
}
|
|
|
|
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
{
|
|
[transaction removeObjectForKey:self.uniqueId inCollection:[[self class] collection]];
|
|
}
|
|
|
|
- (void)remove
|
|
{
|
|
[[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
[self removeWithTransaction:transaction];
|
|
}];
|
|
}
|
|
|
|
- (YapDatabaseConnection *)dbReadConnection
|
|
{
|
|
return [[self class] dbReadConnection];
|
|
}
|
|
|
|
- (YapDatabaseConnection *)dbReadWriteConnection
|
|
{
|
|
return [[self class] dbReadWriteConnection];
|
|
}
|
|
|
|
- (OWSPrimaryStorage *)primaryStorage
|
|
{
|
|
return [[self class] primaryStorage];
|
|
}
|
|
|
|
#pragma mark Class Methods
|
|
|
|
+ (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey
|
|
{
|
|
if ([propertyKey isEqualToString:@"TAG"]) {
|
|
return MTLPropertyStorageNone;
|
|
} else {
|
|
return [super storageBehaviorForPropertyWithKey:propertyKey];
|
|
}
|
|
}
|
|
|
|
+ (YapDatabaseConnection *)dbReadConnection
|
|
{
|
|
OWSJanksUI();
|
|
|
|
// 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
|
|
{
|
|
OWSJanksUI();
|
|
|
|
return SSKEnvironment.shared.objectReadWriteConnection;
|
|
}
|
|
|
|
+ (OWSPrimaryStorage *)primaryStorage
|
|
{
|
|
return [OWSPrimaryStorage sharedManager];
|
|
}
|
|
|
|
+ (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
|
|
{
|
|
[[self dbReadWriteConnection] readWriteWithBlock:^(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
|
|
{
|
|
OWSAssertDebug(transaction);
|
|
|
|
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) {
|
|
if (!ignoreMissing) {
|
|
OWSFailDebug(@"`latest` was unexpectedly nil");
|
|
}
|
|
return;
|
|
}
|
|
|
|
[self setValuesForKeysWithDictionary:latest.dictionaryValue];
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|