GNUstep Core Data
0.1
|
00001 /* Implementation of the GSPersistentStore class for the GNUstep 00002 Core Data framework. 00003 Copyright (C) 2005 Free Software Foundation, Inc. 00004 00005 Written by: Saso Kiselkov <diablos@manga.sk> 00006 Date: August 2005 00007 00008 This file is part of the GNUstep Core Data framework. 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2.1 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library; if not, write to the Free 00022 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. 00023 */ 00024 00025 #import "CoreDataHeaders.h" 00026 #import "GSPersistentStore.h" 00027 00028 #include <stdlib.h> 00029 #include <time.h> 00030 00031 #ifdef HAVE_NATIVE_OBJC_EXCEPTIONS 00032 # define SUBCLASS_OVERRIDE_ERROR \ 00033 @throw [NSException exceptionWithName: NSInternalInconsistencyException \ 00034 reason: [NSString stringWithFormat: \ 00035 _(@"Subclass %@ didn't override `%@'."), [self className], \ 00036 NSStringFromSelector(_cmd)] \ 00037 userInfo: nil] 00038 #else 00039 # define SUBCLASS_OVERRIDE_ERROR \ 00040 [NSException raise: NSInternalInconsistencyException \ 00041 format: _(@"Subclass %@ didn't override `%@'."), \ 00042 [self className], NSStringFromSelector(_cmd)] 00043 #endif 00044 00045 // the lock with which we protect access to the randomizer's 00046 // state setup. 00047 static NSRecursiveLock * randomizerLock = nil; 00048 static struct drand48_data randomizerSetup; 00049 00050 // store UUIDs are 256-bits long 00051 #define STORE_UUID_SIZE (256 / 8) /* bits */ 00052 00059 static NSString * 00060 GenerateNewRandomUUID (void) 00061 { 00062 NSString * hexaValue = @""; 00063 unsigned int i; 00064 00065 [randomizerLock lock]; 00066 00067 // Generate a random number which may be up to 256-bits (i.e. up to 00068 // 64 hexa-digits) long. 00069 for (i = 0; i < (STORE_UUID_SIZE / sizeof(long int)); i++) 00070 { 00071 long int result; 00072 lrand48_r (&randomizerSetup, &result); 00073 hexaValue = [NSString stringWithFormat: @"%@%X", hexaValue, result]; 00074 } 00075 00076 [randomizerLock unlock]; 00077 00078 return hexaValue; 00079 } 00080 00123 @implementation GSPersistentStore 00124 00125 + (void) initialize 00126 { 00127 if (randomizerLock == nil) 00128 { 00129 // initialize the randomizerSetup protection lock 00130 randomizerLock = [NSRecursiveLock new]; 00131 00132 // setup the randomizer 00133 srand48_r(time(NULL), &randomizerSetup); 00134 } 00135 } 00136 00137 - (void) dealloc 00138 { 00139 TEST_RELEASE(_URL); 00140 TEST_RELEASE(_model); 00141 TEST_RELEASE(_configuration); 00142 TEST_RELEASE(_metadata); 00143 TEST_RELEASE(_versionNumbers); 00144 00145 [super dealloc]; 00146 } 00147 00156 - initWithURL: (NSURL *) URL 00157 managedObjectModel: (NSManagedObjectModel *) model 00158 configuration: (NSString *) configuration 00159 options: (NSDictionary *) options 00160 { 00161 if ([self init]) 00162 { 00163 ASSIGN(_URL, URL); 00164 ASSIGN(_model, model); 00165 ASSIGN(_configuration, configuration); 00166 00167 _metadata = [[NSDictionary alloc] 00168 initWithObjectsAndKeys: 00169 GenerateNewRandomUUID(), NSStoreUUIDKey, 00170 [self storeType], NSStoreTypeKey, 00171 nil]; 00172 00173 _versionNumbers = [NSMutableDictionary new]; 00174 00175 return self; 00176 } 00177 else 00178 { 00179 return nil; 00180 } 00181 } 00182 00188 - (NSURL *) URL 00189 { 00190 return _URL; 00191 } 00192 00198 - (NSString *) configuration 00199 { 00200 return _configuration; 00201 } 00202 00208 - (void) setUUID: (NSString *) UUID 00209 { 00210 NSMutableDictionary * metadata; 00211 00212 metadata = [[_metadata mutableCopy] autorelease]; 00213 [metadata setObject: UUID 00214 forKey: NSStoreUUIDKey]; 00215 ASSIGN(_metadata, [[metadata copy] autorelease]); 00216 } 00217 00225 - (void) setMetadata: (NSDictionary *) metadata 00226 { 00227 NSMutableDictionary * newMetadata = [[metadata mutableCopy] autorelease]; 00228 00229 // copy the old values 00230 [newMetadata setObject: [_metadata objectForKey: NSStoreUUIDKey] 00231 forKey: NSStoreUUIDKey]; 00232 [newMetadata setObject: [self storeType] forKey: NSStoreTypeKey]; 00233 00234 ASSIGN(_metadata, [[newMetadata copy] autorelease]); 00235 } 00236 00243 - (NSDictionary *) metadata 00244 { 00245 return _metadata; 00246 } 00247 00248 - (BOOL) saveObjects: (NSSet *) objects 00249 error: (NSError **) error 00250 { 00251 NSEnumerator * e = [objects objectEnumerator]; 00252 NSManagedObject * managedObject; 00253 00254 // increment the storage number for non-fault objects 00255 while ((managedObject = [e nextObject]) != nil) 00256 { 00257 if (![managedObject isFault]) 00258 { 00259 unsigned long long version; 00260 NSManagedObjectID * objectID = [managedObject objectID]; 00261 00262 NSAssert([objectID persistentStore] == self, _(@"Tried to store " 00263 @"a managed object in a different persistent store than where " 00264 @"it belongs.")); 00265 00266 version = [[_versionNumbers objectForKey: objectID] 00267 unsignedLongLongValue]; 00268 version++; 00269 [_versionNumbers 00270 setObject: [NSNumber numberWithUnsignedLongLong: version] 00271 forKey: objectID]; 00272 } 00273 } 00274 00275 // and write the objects 00276 // return [self writeWithObjects: objects error: error]; 00277 return NO; 00278 } 00279 00280 - (unsigned long long) storageNumberForObjectID: (NSManagedObjectID *) objectID 00281 { 00282 return [[_versionNumbers objectForKey: objectID] unsignedLongLongValue]; 00283 } 00284 00292 - (NSString *) storeType 00293 { 00294 SUBCLASS_OVERRIDE_ERROR; 00295 00296 return nil; 00297 } 00298 00343 - (NSDictionary *) fetchObjectsWithEntity: (NSEntityDescription *) entity 00344 predicate: (NSPredicate *) predicate 00345 error: (NSError **) error 00346 { 00347 SUBCLASS_OVERRIDE_ERROR; 00348 00349 return nil; 00350 } 00351 00367 - (NSDictionary *) fetchObjectWithID: (NSManagedObjectID *) objectID 00368 fetchProperties: (NSSet *) properties 00369 error: (NSError **) error 00370 { 00371 SUBCLASS_OVERRIDE_ERROR; 00372 00373 return nil; 00374 } 00375 00406 - (BOOL) writeSavingObjects: (NSSet *) objectsToWrite 00407 deletingObjects: (NSSet *) objectIDsToDelete 00408 error: (NSError **) error 00409 { 00410 SUBCLASS_OVERRIDE_ERROR; 00411 00412 return NO; 00413 } 00414 00415 @end