Re: Versioning and CoreData
Re: Versioning and CoreData
- Subject: Re: Versioning and CoreData
- From: Ryan Britton <email@hidden>
- Date: Mon, 1 May 2006 12:48:55 -0700
I'm assuming by "model formats" you mean model versions and not
persistent store formats?
I've done this a few times now, so the last time I did it I embedded
the code into a reusable framework that I expand on as needed. It's
still pretty early in its development, but so far it has accomplished
the job fairly well.
The basic approach used by the process is this:
Check the store version (stored in the metadata) prior to the
NSApplicationMain() function being called. If it's an older version,
then instantiate a data migrator object. This is initialized to the
project's needs, such as in the following snippet.
//Build the migrator
MSDataMigrator *migrator = [MSDataMigrator dataMigrator];
[migrator setTarget:nil];
[migrator setCopiesOldAttributes:YES];
[migrator setStoreType:NSSQLiteStoreType];
[migrator setStoreLocation:persistentStorePath()];
[migrator setCurrentVersion:STORE_VERSION];
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
[migrator addModelAtPath:[resourcePath
stringByAppendingPathComponent:@"Version0_Model.mom"] forVersion:
[NSNumber numberWithInt:0]];
[migrator addModelAtPath:[resourcePath
stringByAppendingPathComponent:@"Version3_Model.mom"] forVersion:
[NSNumber numberWithInt:3]];
[migrator addPreviousStoreAtPath:[applicationSupportFolder()
stringByAppendingPathComponent:@"APreviousStore.sqlite"] forVersion:
[NSNumber numberWithInt:0]];
if (![migrator migrate])
{
if ([migrator error] != MSDataMigratorNoError)
{
NSLog(@"Migrator encountered error: %d", [migrator error]);
}
}
When the migrator runs, it steps through each entity type. A new
object for each object of this entity type is created in the new
context. If it's set to copy old attributes, it does so. Every
attribute that exists in the same form in both the old and new models
is copied directly.
While creating the new objects, it also builds an (old object id) ->
(new object id) mapping. A second stage rebuilds relationships using
this mapping.
The final stage iterates over a series of callbacks, which are set
prior to migration using this method:
- (void)setCallback:(SEL)aSelector forEntityName:(NSString *)
anEntityName withVersionChange:(MSVersionChange *)aVersionChange
For each object of the specified entity, the selector will be called
if the version change matches. The selector takes an old and new
object and returns a BOOL indicating success or failure.
This currently has a few limitations. Namely, it does not support an
entity type disappearing. If that happens, it will ignore the old
objects of that entity type and will not attempt to migrate them. If
you're at all interested, I'm more than willing to share the code
though it is still a work in progress and not necessarily ready for
every scenario.
On May 1, 2006, at 12:24 PM, Uli Kusterer wrote:
Hi,
I just created a CoreData project and a test document, then added
some fields to the model, and then opened the document again. This
worked, which goes completely against what the CoreData docs on
versioning say. Is this a quirk of the XML store, or did I overlook
something in the docs and adding optional attributes to a store
doesn't cause versioning problems? This would be very handy because
it's the most common update to a file format.
If it isn't, does anyone have any suggestion on the most painless
way of migrating between model formats? Basically I'd only want to
add stuff and write code once that migrates the old format to the
newer, richer format, and then just add to my model as I please.
Cheers,
-- M. Uli Kusterer
http://www.zathras.de
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden