|
// |
|
// VSTagAuthority.m |
|
// Vesper |
|
// |
|
// Created by Brent Simmons on 2/28/14. |
|
// Copyright (c) 2014 Q Branch LLC. All rights reserved. |
|
// |
|
|
|
#import "VSTagAuthority.h" |
|
#import "VSTag.h" |
|
|
|
|
|
@interface VSTagAuthority () |
|
|
|
@property (nonatomic, readonly) NSManagedObjectContext *context; |
|
@property (nonatomic, readonly) NSMutableDictionary *tagIDs; |
|
|
|
@end |
|
|
|
|
|
@implementation VSTagAuthority |
|
|
|
|
|
#pragma mark - Init |
|
|
|
- (instancetype)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)storeCoordinator { |
|
|
|
NSParameterAssert(storeCoordinator != nil); |
|
|
|
self = [super init]; |
|
if (!self) { |
|
return nil; |
|
} |
|
|
|
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; |
|
[_context setPersistentStoreCoordinator:storeCoordinator]; |
|
[_context setUndoManager:nil]; |
|
NSAssert(_context != nil, nil); |
|
|
|
_tagIDs = [NSMutableDictionary new]; |
|
[self fetchTags]; |
|
|
|
return self; |
|
} |
|
|
|
|
|
#pragma mark - Tag Cache |
|
|
|
- (void)fetchTags { |
|
|
|
[self.context performBlock:^{ |
|
|
|
NSArray *allTags = [VSTag allObjects:self.context]; |
|
|
|
for (VSTag *oneTag in allTags) { |
|
|
|
NSString *oneClientID = oneTag.clientID; /*clientID is the unique ID for tag.*/ |
|
NSAssert(oneClientID != nil, nil); |
|
|
|
self.tagIDs[oneClientID] = [oneTag objectID]; |
|
} |
|
}]; |
|
} |
|
|
|
|
|
#pragma mark - API |
|
|
|
- (VSTag *)existingTagWithName:(NSString *)name context:(NSManagedObjectContext *)context { |
|
|
|
NSParameterAssert(name != nil && [name length] > 0); |
|
NSParameterAssert(context != nil); |
|
|
|
__block NSManagedObjectID *objectID = nil; |
|
|
|
[self.context performBlockAndWait:^{ |
|
|
|
NSString *clientID = [VSTag clientIDForTagName:name]; |
|
objectID = self.tagIDs[clientID]; |
|
NSAssert(![objectID isTemporaryID], nil); |
|
|
|
}]; |
|
|
|
if (objectID) { |
|
return (VSTag *)[context objectWithID:objectID]; |
|
} |
|
|
|
return nil; |
|
} |
|
|
|
|
|
- (VSTag *)tagWithName:(NSString *)name context:(NSManagedObjectContext *)context error:(NSError **)error { |
|
|
|
NSParameterAssert(name != nil && [name length] > 0); |
|
NSParameterAssert(context != nil); |
|
|
|
__block NSManagedObjectID *objectID = nil; |
|
|
|
[self.context performBlockAndWait:^{ |
|
|
|
NSString *clientID = [VSTag clientIDForTagName:name]; |
|
objectID = self.tagIDs[clientID]; |
|
|
|
if (!objectID) { |
|
VSTag *tag = [VSTag insertObject:self.context]; |
|
tag.name = name; |
|
tag.clientID = clientID; |
|
|
|
if ([self.context save:error]) { |
|
|
|
objectID = [tag objectID]; |
|
NSAssert(![objectID isTemporaryID], nil); /*Just saved -- should be permanent.*/ |
|
|
|
self.tagIDs[clientID] = objectID; |
|
} |
|
|
|
else { |
|
NSLog(@"Error inserting tag: %@", *error); |
|
} |
|
} |
|
}]; |
|
|
|
if (objectID) { |
|
return (VSTag *)[context objectWithID:objectID]; |
|
} |
|
|
|
return nil; |
|
} |
|
|
|
@end |