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.
47 static NSRecursiveLock * randomizerLock = nil;
48 static struct drand48_data randomizerSetup;
49 
50 // store UUIDs are 256-bits long
51 #define STORE_UUID_SIZE (256 / 8) /* bits */
52 
59 static NSString *
60 GenerateNewRandomUUID (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 
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.