How to manage a separate data file while saving an NSPersistentDocument or during schema migration

2009-01-16 Thread Barry Wark
Following the advice in
http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html#//apple_ref/doc/uid/TP40003468-SW5
regarding storage of BLOBs, I've chosen to store binary data for my
NSPersistenDocument-based app (Leopard-only, if that makes a
difference) in an external file (separate from the document Core Data
data store) and keeping an archived NDAlias reference to that file in
my document's data store. Ultimately, I would like the external data
file to end up in the same directory as the document (data store)
file. Since I may need to write data to the external data file before
the document is saved (this is a scientific data acquisition app and
losing data due to a crash is to be avoided if possible), I've taken
the following approach:

I would like to encapsulate the management of this external file in
the model-related classes since I will need the same functionality
during schema migration. Thus managing the external data file in my
NSPersistentDocument's subclass seems wrong. Thus, in the object
model's root object, I create the external file in
NSTemporaryDirectory() in the root objects awakeFromInsert method and
store the NDAlias referencing the data file. I would then like to move
the external data file to the same directory as the saved data store,
when a save occurs. I thought didSave would be the appropriate place
to do it, but it looks like during invocation of the didSave method,
the persistent store is still in a temporary directory (presumably
before being FSExchangeObjects'd to create an atomic save operation).
I plan to factor the logic in awakeFromInsert and didSave into class
methods so that they can be called during schema migration in a custom
entity policy's
createDestinationInstancesForSourceInstance:entityMapping:manager:error:
and endInstanceCreationForEntityMapping:manager:error: respectively.

So, my question: when during NSPersistentDocument save and during
schema migration can I be assured that my root object's
objectID.persistentStore.URL is the 'final' URL of the save (e.g.
where the user chose to save the file for document save)?

thanks,
Barry
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to manage a separate data file while saving an NSPersistentDocument or during schema migration

2009-01-16 Thread Quincey Morris

On Jan 16, 2009, at 10:00, Barry Wark wrote:


I would like to encapsulate the management of this external file in
the model-related classes since I will need the same functionality
during schema migration. Thus managing the external data file in my
NSPersistentDocument's subclass seems wrong. Thus, in the object
model's root object, I create the external file in
NSTemporaryDirectory() in the root objects awakeFromInsert method and
store the NDAlias referencing the data file. I would then like to move
the external data file to the same directory as the saved data store,
when a save occurs. I thought didSave would be the appropriate place
to do it, but it looks like during invocation of the didSave method,
the persistent store is still in a temporary directory (presumably
before being FSExchangeObjects'd to create an atomic save operation).


FWIW, I spent quite some time trying to devise a way of getting  
something like this to work, and eventually came to this conclusion:


That Way Madness Lies

but YMMV (your madness may vary).

There are two sets of problems to deal with.

First, NSDocument doesn't guarantee any particular file handling  
behavior at Save time, and you can expect that the implementation may  
change in different versions of OS X. Also, the implementation may  
well be different on different file systems, so the sequence of events  
you observe on a local HFS+ volume may not apply to (say) network  
volumes. Anything you choose to rely on may break at any time, unless  
the documentation says otherwise.


Second, NSDocument is fundamentally invested in the concept of save-by- 
copying for reasons of data integrity. As soon as you try to  
*preserve* unchanged files across a save, the integrity of the save  
metaphor is thrown into doubt. I'm certain that it's solvable (though  
I'm also certain I'm not smart enough to do it myself), but only if  
you have a solution to the first problem. Think about  
NSPersistentDocument, and how it shoehorns Core Data into a NSDocument  
environment. This was done by people at Apple who were certainly smart  
enough, but even so there's no save-to (i.e. Save a Copy As ...), no  
autosave, and save-as is implemented (AFAIK) as a Core Data migration.


So I think you have four options:

1. Go ahead with your original plan and hope it doesn't break on  
future Mac OS releases or on different file systems.


2. Put the BLOBs in the Core Data object graph after all. (That's what  
I chose. However, since you can't fault out individual properties,  
instead of making each BLOB an attribute of its owning object, I made  
it an attribute of an object owned by the owning object. That way I  
could in effect fault out the BLOBs at will.)


3. Make your own NSDocument subclass that uses Core Data internally  
(but not NSPersistentDocument), and replace the entire saving  
mechanism by your own implementation.


4. Decide that your database is not really a document, and abandon the  
entire NSDocument metaphor. You can still have housekeeping functions  
for backing up versions of your database or snapshotting or cloning  
it, without following the document model exactly.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to manage a separate data file while saving an NSPersistentDocument or during schema migration

2009-01-16 Thread Barry Wark
On Fri, Jan 16, 2009 at 3:00 PM, Quincey Morris
quinceymor...@earthlink.net wrote:
 On Jan 16, 2009, at 10:00, Barry Wark wrote:

 I would like to encapsulate the management of this external file in
 the model-related classes since I will need the same functionality
 during schema migration. Thus managing the external data file in my
 NSPersistentDocument's subclass seems wrong. Thus, in the object
 model's root object, I create the external file in
 NSTemporaryDirectory() in the root objects awakeFromInsert method and
 store the NDAlias referencing the data file. I would then like to move
 the external data file to the same directory as the saved data store,
 when a save occurs. I thought didSave would be the appropriate place
 to do it, but it looks like during invocation of the didSave method,
 the persistent store is still in a temporary directory (presumably
 before being FSExchangeObjects'd to create an atomic save operation).

 FWIW, I spent quite some time trying to devise a way of getting something
 like this to work, and eventually came to this conclusion:

That Way Madness Lies

 but YMMV (your madness may vary).

 There are two sets of problems to deal with.

 First, NSDocument doesn't guarantee any particular file handling behavior at
 Save time, and you can expect that the implementation may change in
 different versions of OS X. Also, the implementation may well be different
 on different file systems, so the sequence of events you observe on a local
 HFS+ volume may not apply to (say) network volumes. Anything you choose to
 rely on may break at any time, unless the documentation says otherwise.

 Second, NSDocument is fundamentally invested in the concept of
 save-by-copying for reasons of data integrity. As soon as you try to
 *preserve* unchanged files across a save, the integrity of the save metaphor
 is thrown into doubt. I'm certain that it's solvable (though I'm also
 certain I'm not smart enough to do it myself), but only if you have a
 solution to the first problem. Think about NSPersistentDocument, and how it
 shoehorns Core Data into a NSDocument environment. This was done by people
 at Apple who were certainly smart enough, but even so there's no save-to
 (i.e. Save a Copy As ...), no autosave, and save-as is implemented (AFAIK)
 as a Core Data migration.

I was hoping that those same smart engineers (and they were very
smart) had come up with a solution for this use case as well. Ah,
well.


 So I think you have four options:

 1. Go ahead with your original plan and hope it doesn't break on future Mac
 OS releases or on different file systems.

I haven't even gotten this solution working on the current OS. Grr.


 2. Put the BLOBs in the Core Data object graph after all. (That's what I
 chose. However, since you can't fault out individual properties, instead of
 making each BLOB an attribute of its owning object, I made it an attribute
 of an object owned by the owning object. That way I could in effect fault
 out the BLOBs at will.)

In fact, that's how I started. It works fine (using a separate entity
for the data), and performance was fine. Unfortunately, the backup
system at the deployment site backs up entire changed files (rather
than binary diffs), so the continuous changes to flags and metadata in
the data model during analysis force a back up of all the original
BLOB data as well... order 100GB/day. Thus, we've decided to go with
the separate file solution. Since this is, in fact, the Apple
recommended approach, I was surprised it wasn't easier to implement.


 3. Make your own NSDocument subclass that uses Core Data internally (but not
 NSPersistentDocument), and replace the entire saving mechanism by your own
 implementation.

 4. Decide that your database is not really a document, and abandon the
 entire NSDocument metaphor. You can still have housekeeping functions for
 backing up versions of your database or snapshotting or cloning it, without
 following the document model exactly.

We considered both of these, but the application is well modeled by
the document architecture, so it seems a shame to throw all that out.

I guess it's time to file a ticket on this one...
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How to manage a separate data file while saving an NSPersistentDocument or during schema migration

2009-01-16 Thread Quincey Morris

On Jan 16, 2009, at 17:26, Barry Wark wrote:


In fact, that's how I started. It works fine (using a separate entity
for the data), and performance was fine. Unfortunately, the backup
system at the deployment site backs up entire changed files (rather
than binary diffs), so the continuous changes to flags and metadata in
the data model during analysis force a back up of all the original
BLOB data as well... order 100GB/day. Thus, we've decided to go with
the separate file solution. Since this is, in fact, the Apple
recommended approach, I was surprised it wasn't easier to implement.


If the BLOBs themselves are not being changed (at least by this  
application on a per-document basis), then you could keep a library  
of BLOB sets in the Application Support folder or somewhere shared.


Or, even if the BLOBs are changed sometimes, you could try putting  
them in a separate persistent store that you add to your managed  
object context, and use cross-store links. It's *possible* that a  
simple Save will not touch the BLOB store if the BLOBs haven't changed  
(though I have no idea if that's so or not). In that case, your backup  
system won't try to backup the unchanged store. You'd have to try this  
out for feasibility, and it means messing with cross-store links, but  
the big win is of course that you don't have to get your hands dirty  
in the save process at all (I think).



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com