GNUstep Core Data 0.1
NSPersistentStoreCoordinator.m
1/* Implementation of the NSPersistentStoreCoordinator class for the GNUstep
2 Core Data framework.
3 Copyright (C) 2005 Free Software Foundation, Inc.
4
5 Written by: Saso Kiselkov <diablos@manga.sk>
6 Date: August 2005
7
8 This file is part of the GNUstep Core Data framework.
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free
22 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
23 */
24
25#import "CoreDataHeaders.h"
26#import "GSPersistentStore.h"
27#import "GSSQLitePersistentStore.h"
28
29NSString
30 * const NSSQLiteStoreType = @"NSSQLiteStoreType",
31 * const NSXMLStoreType = @"NSXMLStoreType",
32 * const NSBinaryStoreType = @"NSBinaryStoreType",
33 * const NSInMemoryStoreType = @"NSInMemoryStoreType";
34
35NSString
36 * const NSReadOnlyPersistentStoreOption = @"NSReadOnlyPersistentStoreOption",
37 * const NSValidateXMLStoreOption = @"NSValidateXMLStoreOption";
38
39NSString
40 * const NSStoreTypeKey = @"NSStoreTypeKey",
41 * const NSStoreUUIDKey = @"NSStoreUUIDKey";
42
43@implementation NSPersistentStoreCoordinator
44
52static NSMutableDictionary * persistentStoreTypes = nil;
53
54// Add the basic store types to our knowledge base.
55+ (void) initialize
56{
57 if (persistentStoreTypes == nil)
58 {
59 persistentStoreTypes = [[NSMutableDictionary alloc]
60 initWithObjectsAndKeys:
61 NSSQLiteStoreType, [GSSQLitePersistentStore class],
62/*
63 NSXMLStoreType, [GSXMLPersistentStore class],
64 NSBinaryStoreType, [GSBinaryPersistentStore class],
65 NSInMemoryStoreType, [GSInMemoryPersistentStore class],*/
66 nil];
67 }
68}
69
70+ (void) addPersistentStoreType: (NSString *) type
71 handledByClass: (Class) newClass
72{
73 Class oldClass;
74
75 if ([newClass isKindOfClass: [GSPersistentStore class]] == NO)
76 {
77 [NSException raise: NSInvalidArgumentException
78 format: _(@"When adding a new store type, you must "
79 @"do so by subclassing GSPersistentStore "
80 @"and implementing it's abstract methods."),
81 [newClass className]];
82 }
83
84 // warn about redefinition of already defined store types.
85 oldClass = [persistentStoreTypes objectForKey: type];
86 if (oldClass != nil && oldClass != newClass)
87 {
88 NSLog(_(@"WARNING: Replacing persistent store type %@, "
89 @"originally handled by class %@, with class %@."),
90 type, [oldClass className], [newClass className]);
91 }
92
93 [persistentStoreTypes setObject: newClass forKey: type];
94}
95
96+ (NSArray *) supportedPersistentStoreTypes
97{
98 return [persistentStoreTypes allKeys];
99}
100
101- (void) dealloc
102{
103 if (_acquiredModel)
104 {
105 [_model _decrementUseCount];
106 }
107 TEST_RELEASE(_model);
108
109 TEST_RELEASE(_persistentStores);
110 TEST_RELEASE(_lock);
111
112 [super dealloc];
113}
114
115- (id) initWithManagedObjectModel: (NSManagedObjectModel *) model
116{
117 if ((self = [self init]))
118 {
119 ASSIGN(_model, model);
120
121 _persistentStores = [NSMutableDictionary new];
122 _lock = [NSRecursiveLock new];
123
124 }
125 return self;
126}
127
128- (NSManagedObjectModel *) managedObjectModel
129{
130 return _model;
131}
132
133- (id) addPersistentStoreWithType: (NSString *) storeType
134 configuration: (NSString *) configuration
135 URL: (NSURL *) aURL
136 options: (NSDictionary *) options
137 error: (NSError **) error
138{
139 GSPersistentStore * store;
140 Class storeClass;
141
142 storeClass = [persistentStoreTypes objectForKey: storeType];
143 if (storeClass == Nil)
144 {
145 SetNonNullError(error, [NSError
146 errorWithDomain: NSCoreDataErrorDomain
147 code: NSPersistentStoreInvalidTypeError
148 userInfo: nil]);
149
150 return nil;
151 }
152
153 // define what configurations are allowed
154 if (_configurationSet == NO)
155 {
156 _multipleConfigurationsAllowed = (configuration != nil);
157 _configurationSet = YES;
158 }
159 else if (_multipleConfigurationsAllowed == NO && configuration != nil)
160 {
161 SetNonNullError(error, [NSError
162 errorWithDomain: NSCoreDataErrorDomain
163 code: NSPersistentStoreIncompatibleSchemaError
164 userInfo: nil]);
165
166 return nil;
167 }
168
169 store = [[[storeClass alloc]
170 initWithURL: aURL
171 managedObjectModel: _model
172 configuration: configuration
173 options: options]
174 autorelease];
175 if (store == nil)
176 {
177 SetNonNullError(error, [NSError
178 errorWithDomain: NSCoreDataErrorDomain
179 code: NSPersistentStoreInitializationError
180 userInfo: nil]);
181
182 return nil;
183 }
184
185 [_persistentStores setObject: store forKey: aURL];
186
187 return store;
188}
189
190- (BOOL) removePersistentStore: (id) persistentStore
191 error: (NSError **) error
192{
193 GSPersistentStore * store = persistentStore;
194
195 // FIXME: what errors could occur here?
196 [_persistentStores removeObjectForKey: [store URL]];
197
198 return YES;
199}
200
201- (NSArray *) persistentStores
202{
203 return [_persistentStores allValues];
204}
205
206- (id) persistentStoreForURL: (NSURL *) aURL
207{
208 return [_persistentStores objectForKey: aURL];
209}
210
211- (NSURL *) URLForPersistentStore: (id) persistentStore
212{
213 return [persistentStore URL];
214}
215
216- (void) lock
217{
218 [_lock lock];
219}
220
221- (BOOL) tryLock
222{
223 return [_lock tryLock];
224}
225
226- (void) unlock
227{
228 [_lock unlock];
229}
230
231- (NSDictionary *) metadataForPersistentStore: (id) store
232{
233 return [store metadata];
234}
235
236- (NSManagedObjectID *) managedObjectIDForURIRepresentation: (NSURL *) uri
237{
238 GSPersistentStore * store;
239 NSString * UUID;
240 unsigned long long uuid, idValue;
241 NSString * entityName;
242 NSEntityDescription * entity;
243 NSEnumerator * e;
244 NSArray * pathComponents;
245
246 pathComponents = [[uri path] pathComponents];
247 if ([pathComponents count] != 3)
248 {
249 return nil;
250 }
251
252 // find the persistent store with the ID's UUID
253 UUID = [pathComponents objectAtIndex: 0];
254 e = [[_persistentStores allValues] objectEnumerator];
255 while ((store = [e nextObject]) != nil)
256 {
257 if ([[[store metadata] objectForKey: NSStoreUUIDKey] isEqual: UUID])
258 {
259 break;
260 }
261 }
262 if (store == nil)
263 {
264 // store not found
265 return nil;
266 }
267
268 // find the ID's entity
269 entityName = [pathComponents objectAtIndex: 1];
270 if ([store configuration] == nil)
271 {
272 entity = [[_model entitiesByName] objectForKey: entityName];
273 }
274 else
275 {
276 entity = [[_model _entitiesByNameForConfiguration: [store configuration]]
277 objectForKey: entityName];
278 }
279
280 if (entity == nil)
281 {
282 // entity not found
283 return nil;
284 }
285
286 if (sscanf([[pathComponents objectAtIndex: 2] cString], "%llX",
287 &idValue) != 1)
288 {
289 // malformed or no id value
290 return nil;
291 }
292
293 return [[[NSManagedObjectID alloc]
294 _initWithEntity: entity
295 persistentStore: store
296 value: idValue]
297 autorelease];
298}
299
300@end
NSURL * URL()
Getting the store's URL.
NSString * configuration()
Getting the store's configuration.
For implementation notes see "Documentation/NSManagedObjectID.txt" in the source distribution of the ...