Instantly share code, notes, and snippets.

Embed
What would you like to do?
//
// VSTagAuthoritySQL.m
// Vesper
//
// Created by Brent Simmons on 2/28/14.
// Copyright (c) 2014 Q Branch LLC. All rights reserved.
//
#import <libkern/OSAtomic.h>
#import "VSTagAuthoritySQL.h"
#import "QSDatabaseQueue.h"
#import "FMDatabase.h"
@interface VSTagAuthoritySQL ()
@property (nonatomic, readonly) QSDatabaseQueue *databaseQueue;
@property (nonatomic, readonly) NSMutableDictionary *tags;
@end
static OSSpinLock tagsLock = OS_SPINLOCK_INIT;
@implementation VSTagAuthoritySQL
#pragma mark - Init
- (instancetype)initWithDatabaseQueue:(QSDatabaseQueue *)databaseQueue {
self = [super init];
if (self == nil) {
return self;
}
_databaseQueue = databaseQueue;
_tags = [NSMutableDictionary new];
[self fetchTags];
return self;
}
#pragma mark - Database
static NSString *VSTagNameKey = @"name";
static NSString *VSTagClientIDKey = @"clientID";
- (void)fetchTags {
OSSpinLockLock(&tagsLock);
[self.databaseQueue fetch:^(FMDatabase *database) {
FMResultSet *rs = [database executeQuery:@"select name, clientID from tags;"];
while ([rs next]) {
/*In real life there would be a +VSTag tagWithResultSet: method.
This is just to illustrate.*/
VSTag *oneTag = [VSTag new];
oneTag.name = [rs stringForColumn:VSTagNameKey];
oneTag.clientID = [rs stringForColumn:VSTagClientIDKey];
self.tags[oneTag.clientID] = oneTag;
}
OSSpinLockUnlock(&tagsLock);
}];
}
- (void)insertTagInDatabase:(VSTag *)tag {
/*In real life there would be a
-[VSTag insertInDatabase:(QSDatabaseQueue *)queue] method.*/
NSString *name = tag.name;
NSString *clientID = tag.clientID;
[self.databaseQueue update:^(FMDatabase *database) {
[database executeUpdate:@"insert into tags (name, clientID) values (?, ?);", name, clientID];
}];
}
#pragma mark - API
- (VSTag *)existingTagWithName:(NSString *)name {
NSParameterAssert(name != nil && [name length] > 0);
NSString *clientID = [VSTag clientIDForTagName:name];
OSSpinLockLock(&tagsLock);
VSTag *tag = self.tags[clientID];
OSSpinLockUnlock(&tagsLock);
return tag;
}
- (VSTag *)tagWithName:(NSString *)name {
NSParameterAssert(name != nil && [name length] > 0);
NSString *clientID = [VSTag clientIDForTagName:name];
OSSpinLockLock(&tagsLock);
VSTag *tag = self.tags[clientID];
if (!tag) {
tag = [VSTag new];
tag.name = name;
tag.clientID = clientID;
self.tags[clientID] = tag;
[self insertTagInDatabase:tag];
}
OSSpinLockUnlock(&tagsLock);
return tag;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment