Re: [Leopard] Core Data model versioning vs. NSPersistentDocument
Re: [Leopard] Core Data model versioning vs. NSPersistentDocument
- Subject: Re: [Leopard] Core Data model versioning vs. NSPersistentDocument
- From: Pierre Bernard <email@hidden>
- Date: Fri, 2 Nov 2007 16:53:05 +0100
Hi Malcom!
Thanks a bunch. This really helped a lot!
There however seems to be a problem with my 1.0 files created under
Tiger. These files have no versioning information in their metadata.
Thus I had to resort to manual migration for those files. Guess that
ought to be documented.
The only remaining problem I have is that for an odd reason the
migrated file is opened as "File.hspt~" rather than just "File.hspt"
which causes unwanted behavior on save later on. Any ideas how this
comes about?
Best,
Pierre
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url
ofType:(NSString *)fileType
modelConfiguration:(NSString *)configuration
storeOptions:(NSDictionary *)storeOptions
error:(NSError **)error
{
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator
metadataForPersistentStoreOfType:NSSQLiteStoreType URL:url error:error];
if (sourceMetadata == nil)
{
return NO;
}
id versionHashes = [sourceMetadata
objectForKey:@"NSStoreModelVersionHashes"];
BOOL ok = NO;
if (versionHashes != nil) {
NSMutableDictionary *newStoreOptions;
if (storeOptions == nil)
{
newStoreOptions = [NSMutableDictionary dictionary];
}
else
{
newStoreOptions = [[storeOptions mutableCopy] autorelease];
}
[newStoreOptions setObject:[NSNumber numberWithBool:YES]
forKey:NSMigratePersistentStoresAutomaticallyOption];
ok = [super configurePersistentStoreCoordinatorForURL:url
ofType:fileType
modelConfiguration:configuration
storeOptions:newStoreOptions
error:error];
}
else {
NSURL *modelURL = [NSURL fileURLWithPath:[Document
pathForModelNamed:@"HoudahSpot"]];
NSManagedObjectModel *sourceModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:modelURL];
NSManagedObjectModel *destinationModel = [self managedObjectModel];
/*
To perform the migration, we also need a mapping model.
We have the source and destination model; NSMapping model provides
a convenience method to find the correct mapping model from a given
array of bundles.
*/
NSArray *bundles = [NSArray arrayWithObject:[NSBundle mainBundle]];
NSMappingModel *mappingModel = [NSMappingModel
mappingModelFromBundles:bundles forSourceModel:sourceModel
destinationModel:destinationModel];
if (mappingModel == nil)
{
// should create a suitable NSError and set in 'error'
return NO;
}
/*
Move the legacy file out of the way
*/
NSString *originalPath = [url path];
NSString *legacyPath = [NSString stringWithFormat:@"%@~",
originalPath];
BOOL success = [[NSFileManager defaultManager] movePath:originalPath
toPath:legacyPath handler:nil];
if (!success) {
return NO;
}
NSURL *sourceURL = [NSURL fileURLWithPath:legacyPath isDirectory:NO];
NSURL *destinationURL = [NSURL fileURLWithPath:originalPath
isDirectory:NO];
/*
Create the migration manager and perform the migration
*/
NSMigrationManager *migrationManager = [[NSMigrationManager alloc]
initWithSourceModel:sourceModel destinationModel:destinationModel];
ok = [migrationManager migrateStoreFromURL:sourceURL
type:NSSQLiteStoreType options:storeOptions
withMappingModel:mappingModel toDestinationURL:destinationURL
destinationType:NSSQLiteStoreType destinationOptions:storeOptions
error:error];
[migrationManager release];
if (!ok)
{
return NO;
}
/*
Add the new store to the store coordinator and set the file URL
*/
NSPersistentStoreCoordinator *psc = [[self managedObjectContext]
persistentStoreCoordinator];
NSPersistentStore *destinationStore = [psc
addPersistentStoreWithType:NSSQLiteStoreType
configuration:configuration URL:destinationURL options:storeOptions
error:error];
if (destinationStore == nil)
{
return NO;
}
[self setFileURL:destinationURL];
}
if (ok)
{
/*
If all went well, update the metadata
*/
NSPersistentStoreCoordinator *psc = [[self managedObjectContext]
persistentStoreCoordinator];
id pStore = [psc persistentStoreForURL:[self fileURL]];
/*
configurePersistentStoreCoordinatorForURL is called when document
reopened
Check for existing metadata to avoid overwriting unnecessarily
*/
id existingMetadata = [[psc metadataForPersistentStore:pStore]
objectForKey:(NSString *)kMDItemKeywords];
if (existingMetadata == nil)
{
if (![self setMetadataForStoreAtURL:[self fileURL]])
{
return NO;
}
}
}
return ok;
}
On Nov 2, 2007, at 6:53 AM, mmalc crawford wrote:
For an example, see <http://homepage.mac.com/mmalc/CocoaExamples/controllers.html
>.
mmalc
---
Pierre Bernard
http://www.bernard-web.com/pierre
http://www.houdah.com
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden