OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
6 #error "This file requires ARC support." | |
7 #endif | |
8 | |
9 #import "remoting/ios/data_store.h" | |
10 | |
11 @interface DataStore (Private) | |
12 - (NSString*)itemArchivePath; | |
13 @end | |
14 | |
15 @implementation DataStore { | |
16 @private | |
17 NSMutableArray* _allHosts; | |
18 NSManagedObjectContext* _context; | |
19 NSManagedObjectModel* _model; | |
20 } | |
21 | |
22 // Create or Get a static data store | |
23 + (DataStore*)sharedStore { | |
24 static DataStore* sharedStore = nil; | |
25 static dispatch_once_t onceToken; | |
26 dispatch_once(&onceToken, | |
27 ^{ sharedStore = [[super allocWithZone:nil] init]; }); | |
dcaiafa
2014/03/19 01:14:15
Why allocWithZone instead of just alloc?
aboone
2014/03/21 16:42:07
allocWithZone has been overridden to always return
| |
28 | |
29 return sharedStore; | |
30 } | |
31 | |
32 // General methods | |
33 + (id)allocWithZone:(NSZone*)zone { | |
34 return [self sharedStore]; | |
35 } | |
36 | |
37 // Load data store from SQLLite backing store | |
38 - (id)init { | |
39 self = [super init]; | |
40 | |
41 if (self) { | |
42 // Read in ChromotingModel.xdatamodeld | |
43 _model = [NSManagedObjectModel mergedModelFromBundles:nil]; | |
44 | |
45 NSPersistentStoreCoordinator* psc = [[NSPersistentStoreCoordinator alloc] | |
46 initWithManagedObjectModel:_model]; | |
47 | |
48 NSString* path = [self itemArchivePath]; | |
49 NSURL* storeUrl = [NSURL fileURLWithPath:path]; | |
50 | |
51 NSError* error = nil; | |
52 | |
53 if (![psc | |
54 addPersistentStoreWithType:NSSQLiteStoreType | |
55 configuration:nil | |
56 URL:storeUrl | |
57 options: | |
58 @{ | |
dcaiafa
2014/03/19 01:14:15
Maybe use a intermediate local variable for this N
aboone
2014/03/21 16:42:07
Done.
| |
59 NSMigratePersistentStoresAutomaticallyOpti on : | |
60 @YES, | |
61 NSInferMappingModelAutomaticallyOption : | |
62 @YES | |
63 } | |
64 error:&error]) { | |
65 // An incompatiable version of the store exists, delete it and start over | |
66 [[NSFileManager defaultManager] removeItemAtURL:storeUrl error:nil]; | |
67 | |
68 [psc | |
69 addPersistentStoreWithType:NSSQLiteStoreType | |
70 configuration:nil | |
71 URL:storeUrl | |
72 options: | |
73 @{ | |
74 NSMigratePersistentStoresAutomaticallyOption : | |
75 @YES | |
76 } | |
77 error:&error]; | |
78 [NSException raise:@"Open failed" | |
79 format:@"Reason: %@", [error localizedDescription]]; | |
80 } | |
81 | |
82 // Create the managed object context | |
83 _context = [[NSManagedObjectContext alloc] init]; | |
84 [_context setPersistentStoreCoordinator:psc]; | |
85 | |
86 // The managed object context can manage undo, but we don't need it | |
87 [_context setUndoManager:nil]; | |
88 | |
89 _allHosts = nil; | |
90 } | |
91 return self; | |
92 } | |
93 | |
94 // Commiting to backing store | |
95 - (BOOL)saveChanges { | |
96 NSError* err = nil; | |
97 BOOL successful = [_context save:&err]; | |
98 return successful; | |
99 } | |
100 | |
101 // Looking up the backing store path | |
102 - (NSString*)itemArchivePath { | |
103 NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains( | |
104 NSDocumentDirectory, NSUserDomainMask, YES); | |
105 | |
106 // Get one and only document directory from that list | |
107 NSString* documentDirectory = [documentDirectories objectAtIndex:0]; | |
108 | |
109 return [documentDirectory stringByAppendingPathComponent:@"store.data"]; | |
110 } | |
111 | |
112 // Return an array of all known hosts, if the list hasn't been loaded yet, then | |
113 // load it now | |
114 - (NSArray*)allHosts { | |
115 if (!_allHosts) { | |
116 NSFetchRequest* request = [[NSFetchRequest alloc] init]; | |
117 | |
118 NSEntityDescription* e = | |
119 [[_model entitiesByName] objectForKey:@"HostPreferences"]; | |
120 | |
121 [request setEntity:e]; | |
122 | |
123 NSError* error; | |
124 NSArray* result = [_context executeFetchRequest:request error:&error]; | |
125 if (!result) { | |
126 [NSException raise:@"Fetch failed" | |
127 format:@"Reason: %@", [error localizedDescription]]; | |
128 } | |
129 _allHosts = [result mutableCopy]; | |
130 } | |
131 | |
132 return _allHosts; | |
133 } | |
134 | |
135 // Return a HostPreferences if it already exists, otherwise create a new | |
136 // HostPreferences to use | |
137 - (const HostPreferences*)createHost:(NSString*)hostId { | |
138 | |
139 const HostPreferences* p = [self getHostForId:hostId]; | |
140 | |
141 if (p == nil) { | |
142 p = [NSEntityDescription insertNewObjectForEntityForName:@"HostPreferences" | |
143 inManagedObjectContext:_context]; | |
144 p.hostId = hostId; | |
145 [_allHosts addObject:p]; | |
146 } | |
147 return p; | |
148 } | |
149 | |
150 - (void)removeHost:(HostPreferences*)p { | |
151 [_context deleteObject:p]; | |
152 [_allHosts removeObjectIdenticalTo:p]; | |
153 } | |
154 | |
155 // Search the store for any matching HostPreferences | |
156 // return the 1st match or nil | |
157 - (const HostPreferences*)getHostForId:(NSString*)hostId { | |
158 NSFetchRequest* request = [[NSFetchRequest alloc] init]; | |
159 | |
160 NSEntityDescription* e = | |
161 [[_model entitiesByName] objectForKey:@"HostPreferences"]; | |
162 [request setEntity:e]; | |
163 | |
164 NSPredicate* predicate = | |
165 [NSPredicate predicateWithFormat:@"(hostId = %@)", hostId]; | |
166 [request setPredicate:predicate]; | |
167 | |
168 NSError* error; | |
169 NSArray* result = [_context executeFetchRequest:request error:&error]; | |
170 if (!result) { | |
171 [NSException raise:@"Fetch failed" | |
172 format:@"Reason: %@", [error localizedDescription]]; | |
173 } | |
174 | |
175 for (HostPreferences* curHost in result) { | |
176 return curHost; | |
177 } | |
178 return nil; | |
179 } | |
180 | |
181 @end | |
OLD | NEW |