| Index: remoting/ios/data_store.mm
|
| diff --git a/remoting/ios/data_store.mm b/remoting/ios/data_store.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1cfbc3f9ac2bb85d571e835ebc6932cbb77f4ebf
|
| --- /dev/null
|
| +++ b/remoting/ios/data_store.mm
|
| @@ -0,0 +1,176 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#if !defined(__has_feature) || !__has_feature(objc_arc)
|
| +#error "This file requires ARC support."
|
| +#endif
|
| +
|
| +#import "remoting/ios/data_store.h"
|
| +
|
| +@interface DataStore (Private)
|
| +- (NSString*)itemArchivePath;
|
| +@end
|
| +
|
| +@implementation DataStore {
|
| + @private
|
| + NSMutableArray* _allHosts;
|
| + NSManagedObjectContext* _context;
|
| + NSManagedObjectModel* _model;
|
| +}
|
| +
|
| +// Create or Get a static data store
|
| ++ (DataStore*)sharedStore {
|
| + static DataStore* sharedStore = nil;
|
| + static dispatch_once_t onceToken;
|
| + dispatch_once(&onceToken,
|
| + ^{ sharedStore = [[super allocWithZone:nil] init]; });
|
| +
|
| + return sharedStore;
|
| +}
|
| +
|
| +// General methods
|
| ++ (id)allocWithZone:(NSZone*)zone {
|
| + return [self sharedStore];
|
| +}
|
| +
|
| +// Load data store from SQLLite backing store
|
| +- (id)init {
|
| + self = [super init];
|
| +
|
| + if (self) {
|
| + // Read in ChromotingModel.xdatamodeld
|
| + _model = [NSManagedObjectModel mergedModelFromBundles:nil];
|
| +
|
| + NSPersistentStoreCoordinator* psc = [[NSPersistentStoreCoordinator alloc]
|
| + initWithManagedObjectModel:_model];
|
| +
|
| + NSString* path = [self itemArchivePath];
|
| + NSURL* storeUrl = [NSURL fileURLWithPath:path];
|
| +
|
| + NSError* error = nil;
|
| +
|
| + NSDictionary* tryOptions = @{
|
| + NSMigratePersistentStoresAutomaticallyOption : @YES,
|
| + NSInferMappingModelAutomaticallyOption : @YES
|
| + };
|
| + NSDictionary* makeOptions =
|
| + @{NSMigratePersistentStoresAutomaticallyOption : @YES};
|
| +
|
| + if (![psc addPersistentStoreWithType:NSSQLiteStoreType
|
| + configuration:nil
|
| + URL:storeUrl
|
| + options:tryOptions
|
| + error:&error]) {
|
| + // An incompatible version of the store exists, delete it and start over
|
| + [[NSFileManager defaultManager] removeItemAtURL:storeUrl error:nil];
|
| +
|
| + [psc addPersistentStoreWithType:NSSQLiteStoreType
|
| + configuration:nil
|
| + URL:storeUrl
|
| + options:makeOptions
|
| + error:&error];
|
| + [NSException raise:@"Open failed"
|
| + format:@"Reason: %@", [error localizedDescription]];
|
| + }
|
| +
|
| + // Create the managed object context
|
| + _context = [[NSManagedObjectContext alloc] init];
|
| + [_context setPersistentStoreCoordinator:psc];
|
| +
|
| + // The managed object context can manage undo, but we don't need it
|
| + [_context setUndoManager:nil];
|
| +
|
| + _allHosts = nil;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +// Committing to backing store
|
| +- (BOOL)saveChanges {
|
| + NSError* err = nil;
|
| + BOOL successful = [_context save:&err];
|
| + return successful;
|
| +}
|
| +
|
| +// Looking up the backing store path
|
| +- (NSString*)itemArchivePath {
|
| + NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(
|
| + NSDocumentDirectory, NSUserDomainMask, YES);
|
| +
|
| + // Get one and only document directory from that list
|
| + NSString* documentDirectory = [documentDirectories objectAtIndex:0];
|
| +
|
| + return [documentDirectory stringByAppendingPathComponent:@"store.data"];
|
| +}
|
| +
|
| +// Return an array of all known hosts, if the list hasn't been loaded yet, then
|
| +// load it now
|
| +- (NSArray*)allHosts {
|
| + if (!_allHosts) {
|
| + NSFetchRequest* request = [[NSFetchRequest alloc] init];
|
| +
|
| + NSEntityDescription* e =
|
| + [[_model entitiesByName] objectForKey:@"HostPreferences"];
|
| +
|
| + [request setEntity:e];
|
| +
|
| + NSError* error;
|
| + NSArray* result = [_context executeFetchRequest:request error:&error];
|
| + if (!result) {
|
| + [NSException raise:@"Fetch failed"
|
| + format:@"Reason: %@", [error localizedDescription]];
|
| + }
|
| + _allHosts = [result mutableCopy];
|
| + }
|
| +
|
| + return _allHosts;
|
| +}
|
| +
|
| +// Return a HostPreferences if it already exists, otherwise create a new
|
| +// HostPreferences to use
|
| +- (const HostPreferences*)createHost:(NSString*)hostId {
|
| +
|
| + const HostPreferences* p = [self getHostForId:hostId];
|
| +
|
| + if (p == nil) {
|
| + p = [NSEntityDescription insertNewObjectForEntityForName:@"HostPreferences"
|
| + inManagedObjectContext:_context];
|
| + p.hostId = hostId;
|
| + [_allHosts addObject:p];
|
| + }
|
| + return p;
|
| +}
|
| +
|
| +- (void)removeHost:(HostPreferences*)p {
|
| + [_context deleteObject:p];
|
| + [_allHosts removeObjectIdenticalTo:p];
|
| +}
|
| +
|
| +// Search the store for any matching HostPreferences
|
| +// return the 1st match or nil
|
| +- (const HostPreferences*)getHostForId:(NSString*)hostId {
|
| + NSFetchRequest* request = [[NSFetchRequest alloc] init];
|
| +
|
| + NSEntityDescription* e =
|
| + [[_model entitiesByName] objectForKey:@"HostPreferences"];
|
| + [request setEntity:e];
|
| +
|
| + NSPredicate* predicate =
|
| + [NSPredicate predicateWithFormat:@"(hostId = %@)", hostId];
|
| + [request setPredicate:predicate];
|
| +
|
| + NSError* error;
|
| + NSArray* result = [_context executeFetchRequest:request error:&error];
|
| + if (!result) {
|
| + [NSException raise:@"Fetch failed"
|
| + format:@"Reason: %@", [error localizedDescription]];
|
| + }
|
| +
|
| + for (HostPreferences* curHost in result) {
|
| + return curHost;
|
| + }
|
| + return nil;
|
| +}
|
| +
|
| +@end
|
|
|