GNUstep Core Data 0.1
GSPersistentStore.m
1/* Implementation of the GSPersistentStore 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
28#include <stdlib.h>
29#include <time.h>
30
31#ifdef HAVE_NATIVE_OBJC_EXCEPTIONS
32# define SUBCLASS_OVERRIDE_ERROR \
33 @throw [NSException exceptionWithName: NSInternalInconsistencyException \
34 reason: [NSString stringWithFormat: \
35 _(@"Subclass %@ didn't override `%@'."), [self className], \
36 NSStringFromSelector(_cmd)] \
37 userInfo: nil]
38#else
39# define SUBCLASS_OVERRIDE_ERROR \
40 [NSException raise: NSInternalInconsistencyException \
41 format: _(@"Subclass %@ didn't override `%@'."), \
42 [self className], NSStringFromSelector(_cmd)]
43#endif
44
45// the lock with which we protect access to the randomizer's
46// state setup.
47static NSRecursiveLock * randomizerLock = nil;
48static struct drand48_data randomizerSetup;
49
50// store UUIDs are 256-bits long
51#define STORE_UUID_SIZE (256 / 8) /* bits */
52
59static NSString *
60GenerateNewRandomUUID (void)
61{
62 NSString * hexaValue = @"";
63 unsigned int i;
64
65 [randomizerLock lock];
66
67 // Generate a random number which may be up to 256-bits (i.e. up to
68 // 64 hexa-digits) long.
69 for (i = 0; i < (STORE_UUID_SIZE / sizeof(long int)); i++)
70 {
71 long int result;
72 lrand48_r (&randomizerSetup, &result);
73 hexaValue = [NSString stringWithFormat: @"%@%X", hexaValue, result];
74 }
75
76 [randomizerLock unlock];
77
78 return hexaValue;
79}
80
122
123@implementation GSPersistentStore
124
125+ (void) initialize
126{
127 if (randomizerLock == nil)
128 {
129 // initialize the randomizerSetup protection lock
130 randomizerLock = [NSRecursiveLock new];
131
132 // setup the randomizer
133 srand48_r(time(NULL), &randomizerSetup);
134 }
135}
136
137- (void) dealloc
138{
139 TEST_RELEASE(_URL);
140 TEST_RELEASE(_model);
141 TEST_RELEASE(_configuration);
142 TEST_RELEASE(_metadata);
143 TEST_RELEASE(_versionNumbers);
144
145 [super dealloc];
146}
147
156- initWithURL: (NSURL *) URL
157 managedObjectModel: (NSManagedObjectModel *) model
158 configuration: (NSString *) configuration
159 options: (NSDictionary *) options
160{
161 if ([self init])
162 {
163 ASSIGN(_URL, URL);
164 ASSIGN(_model, model);
165 ASSIGN(_configuration, configuration);
166
167 _metadata = [[NSDictionary alloc]
168 initWithObjectsAndKeys:
169 GenerateNewRandomUUID(), NSStoreUUIDKey,
170 [self storeType], NSStoreTypeKey,
171 nil];
172
173 _versionNumbers = [NSMutableDictionary new];
174
175 return self;
176 }
177 else
178 {
179 return nil;
180 }
181}
182
188- (NSURL *) URL
189{
190 return _URL;
191}
192
198- (NSString *) configuration
199{
200 return _configuration;
201}
202
208- (void) setUUID: (NSString *) UUID
209{
210 NSMutableDictionary * metadata;
211
212 metadata = [[_metadata mutableCopy] autorelease];
213 [metadata setObject: UUID
214 forKey: NSStoreUUIDKey];
215 ASSIGN(_metadata, [[metadata copy] autorelease]);
216}
217
225- (void) setMetadata: (NSDictionary *) metadata
226{
227 NSMutableDictionary * newMetadata = [[metadata mutableCopy] autorelease];
228
229 // copy the old values
230 [newMetadata setObject: [_metadata objectForKey: NSStoreUUIDKey]
231 forKey: NSStoreUUIDKey];
232 [newMetadata setObject: [self storeType] forKey: NSStoreTypeKey];
233
234 ASSIGN(_metadata, [[newMetadata copy] autorelease]);
235}
236
243- (NSDictionary *) metadata
244{
245 return _metadata;
246}
247
248- (BOOL) saveObjects: (NSSet *) objects
249 error: (NSError **) error
250{
251 NSEnumerator * e = [objects objectEnumerator];
252 NSManagedObject * managedObject;
253
254 // increment the storage number for non-fault objects
255 while ((managedObject = [e nextObject]) != nil)
256 {
257 if (![managedObject isFault])
258 {
259 unsigned long long version;
260 NSManagedObjectID * objectID = [managedObject objectID];
261
262 NSAssert([objectID persistentStore] == self, _(@"Tried to store "
263 @"a managed object in a different persistent store than where "
264 @"it belongs."));
265
266 version = [[_versionNumbers objectForKey: objectID]
267 unsignedLongLongValue];
268 version++;
269 [_versionNumbers
270 setObject: [NSNumber numberWithUnsignedLongLong: version]
271 forKey: objectID];
272 }
273 }
274
275 // and write the objects
276// return [self writeWithObjects: objects error: error];
277 return NO;
278}
279
280- (unsigned long long) storageNumberForObjectID: (NSManagedObjectID *) objectID
281{
282 return [[_versionNumbers objectForKey: objectID] unsignedLongLongValue];
283}
284
292- (NSString *) storeType
293{
294 SUBCLASS_OVERRIDE_ERROR;
295
296 return nil;
297}
298
343- (NSDictionary *) fetchObjectsWithEntity: (NSEntityDescription *) entity
344 predicate: (NSPredicate *) predicate
345 error: (NSError **) error
346{
347 SUBCLASS_OVERRIDE_ERROR;
348
349 return nil;
350}
351
367- (NSDictionary *) fetchObjectWithID: (NSManagedObjectID *) objectID
368 fetchProperties: (NSSet *) properties
369 error: (NSError **) error
370{
371 SUBCLASS_OVERRIDE_ERROR;
372
373 return nil;
374}
375
406- (BOOL) writeSavingObjects: (NSSet *) objectsToWrite
407 deletingObjects: (NSSet *) objectIDsToDelete
408 error: (NSError **) error
409{
410 SUBCLASS_OVERRIDE_ERROR;
411
412 return NO;
413}
414
415@end
Nn abstract superclass from which concrete implementations of various persistent store types are subc...
NSDictionary * metadata()
Returns the store's metadata.
NSURL * URL()
Getting the store's URL.
NSString * storeType()
Subclasses must override this to return the store's type as a string.
NSString * configuration()
Getting the store's configuration.
For implementation notes see "Documentation/NSManagedObjectID.txt" in the source distribution of the ...
Validates whether value'' is a valid value forattribute'', returning YES if it is,...
NSManagedObjectID * objectID()
Returns the object ID of the receiver.