Switch back to flat file format

This commit is contained in:
Matthias Neeracher 2011-08-12 17:54:10 +02:00
parent e6ea5922d6
commit 333ab0dace
3 changed files with 5 additions and 176 deletions

View File

@ -9,7 +9,7 @@
#import <Cocoa/Cocoa.h>
@interface MADocument : NSPersistentDocument {
NSFileWrapper * mediaWrapper;
}
- (void)addMediaURL:(NSURL *)url name:(NSString *)name date:(NSDate *)date copying:(BOOL)copying;

View File

@ -11,36 +11,9 @@
#import "MAFolder.h"
#import "MAMedia.h"
#pragma mark NSPersistentDocument file URL hook
/* Adapted from NSPersistentDocumentFileWrappers */
/*
We need to bypass what NSPersistentDocument does in setFileURL:, but we do want to use the functionality provided by NSDocument's implementation of that method. To achieve this, we create a simple category on NSPersistentDocument with methods that will call the NSDocument version of the method. Then, our subclass will call the category method where it would normally simply call the super implementation.
*/
@interface NSPersistentDocument (FileWrapperSuport)
- (void)simpleSetFileURL:(NSURL *)fileURL;
@end
@implementation NSPersistentDocument (FileWrapperSuport)
// Forwards the message to NSDocument's setFileURL: (skips NSPersistentDocument's implementation).
- (void)simpleSetFileURL:(NSURL *)fileURL {
[super setFileURL:fileURL];
}
@end
#pragma mark -
#pragma mark MADocument
/*
This is the name of the Core Data store file contained within the document package.
You can change this whatever you want -- the user will not see this file.
*/
static NSString *StoreFileName = @"MediannoDB.sql";
@implementation MADocument
- (id)initWithType:(NSString *)typeName error:(NSError **)outError
@ -52,13 +25,9 @@ static NSString *StoreFileName = @"MediannoDB.sql";
*/
NSManagedObjectContext *moc = [self managedObjectContext];
[[moc undoManager] disableUndoRegistration];
MAFolder * rootFolder = [NSEntityDescription insertNewObjectForEntityForName:@"MAFolder"
inManagedObjectContext:moc];
[rootFolder setName:@""];
MAFolder * inboxFolder = [NSEntityDescription insertNewObjectForEntityForName:@"MAFolder"
inManagedObjectContext:moc];
[inboxFolder setName:@"Inbox"];
[inboxFolder setParent:rootFolder];
[moc processPendingChanges];
[[moc undoManager] enableUndoRegistration];
@ -68,8 +37,6 @@ static NSString *StoreFileName = @"MediannoDB.sql";
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"MADocument";
}
@ -80,150 +47,11 @@ static NSString *StoreFileName = @"MediannoDB.sql";
[windowController release];
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
// Add any code here that needs to be executed once the windowController has loaded the document's window.
}
+ (BOOL)autosavesInPlace
{
return YES;
}
#pragma mark -
#pragma mark URL management
/*
Returns the URL for the wrapped Core Data store file. This appends the StoreFileName to the document's path.
*/
- (NSURL *)storeURLFromPath:(NSString *)filePath {
filePath = [filePath stringByAppendingPathComponent:StoreFileName];
if (filePath != nil) {
return [NSURL fileURLWithPath:filePath];
}
return nil;
}
/*
Sets the on-disk location. NSPersistentDocument's implementation is bypassed using the FileWrapperSupport category. The persistent store coordinator is directed to use an internal URL rather than NSPersistentDocument's default (the main file URL).
*/
- (void)setFileURL:(NSURL *)fileURL {
NSURL *originalFileURL = [self storeURLFromPath:[[self fileURL] path]];
if (originalFileURL != nil) {
NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
id store = [psc persistentStoreForURL:originalFileURL];
if (store != nil) {
// Switch the coordinator to an internal URL.
[psc setURL:[self storeURLFromPath:[fileURL path]] forPersistentStore:store];
}
}
[self simpleSetFileURL:fileURL];
}
#pragma mark -
#pragma mark Reading / Writing
/*
Overridden NSDocument/NSPersistentDocument method to open existing documents.
*/
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)error {
BOOL success = NO;
// Create a file wrapper for the document package.
NSFileWrapper *directoryFileWrapper = [[NSFileWrapper alloc] initWithPath:[absoluteURL path]];
// File wrapper for the Core Data store within the document package.
NSFileWrapper *dataStore = [[directoryFileWrapper fileWrappers] objectForKey:StoreFileName];
if (dataStore != nil) {
NSString *path = [[absoluteURL path] stringByAppendingPathComponent:[dataStore filename]];
NSURL *storeURL = [NSURL fileURLWithPath:path];
// Set the document persistent store coordinator to use the internal Core Data store.
success = [self configurePersistentStoreCoordinatorForURL:storeURL ofType:typeName
modelConfiguration:nil storeOptions:nil error:error];
}
[directoryFileWrapper release];
return success;
}
/*
Overridden NSDocument/NSPersistentDocument method to save documents.
*/
- (BOOL)writeSafelyToURL:(NSURL *)inAbsoluteURL ofType:(NSString *)inTypeName forSaveOperation:(NSSaveOperationType)inSaveOperation error:(NSError **)outError {
BOOL success = YES;
NSFileWrapper *filewrapper = nil;
NSURL *originalURL = [self fileURL];
NSString *filePath = [inAbsoluteURL path];
// Depending on the type of save operation:
if (inSaveOperation == NSSaveAsOperation || inSaveOperation == NSAutosaveElsewhereOperation) {
// Nothing exists at the URL: set up the directory and migrate the Core Data store.
filewrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
// Need to write once so there's somewhere for the store file to go.
[filewrapper writeToFile:filePath atomically:NO updateFilenames:NO];
// Now, the Core Data store...
NSURL *storeURL = [self storeURLFromPath:filePath];
NSURL *originalStoreURL = [self storeURLFromPath:[originalURL path]];
if (originalStoreURL != nil) {
// This is a "Save As", so migrate the store to the new URL.
NSPersistentStoreCoordinator *coordinator = [[self managedObjectContext] persistentStoreCoordinator];
id originalStore = [coordinator persistentStoreForURL:originalStoreURL];
success = ([coordinator migratePersistentStore:originalStore toURL:storeURL options:nil withType:[self persistentStoreTypeForFileType:inTypeName] error:outError] != nil);
}
else {
// This is the first Save of a new document, so configure the store.
success = [self configurePersistentStoreCoordinatorForURL:storeURL ofType:inTypeName modelConfiguration:nil storeOptions:nil error:nil];
}
[filewrapper addFileWithPath:[storeURL path]];
}
else { // This is not a Save-As operation.
// Just create a file wrapper pointing to the existing URL.
filewrapper = [[NSFileWrapper alloc] initWithPath:[inAbsoluteURL path]];
}
/*
* Important *
Atomicity during write is a problem that is not addressed in this sample.
See the ReadMe for discussion.
*/
if (success == YES) {
// Save the Core Data portion of the document.
success = [[self managedObjectContext] save:outError];
}
if (success == YES) {
// Set the appropriate file attributes (such as "Hide File Extension")
NSDictionary *fileAttributes = [self fileAttributesToWriteToURL:inAbsoluteURL ofType:inTypeName forSaveOperation:inSaveOperation originalContentsURL:originalURL error:outError];
[[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:[inAbsoluteURL path] error:outError];
}
[filewrapper release];
return success;
}
/*
The revert method needs to completely tear down the object graph assembled by the document. In this case, you also want to remove the persistent store manually, because NSPersistentDocument will expect the store for its coordinator to be located at the document URL (instead of inside that URL as part of the file wrapper).
*/
- (BOOL)revertToContentsOfURL:(NSURL *)inAbsoluteURL ofType:(NSString *)inTypeName error:(NSError **)outError {
NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
id store = [psc persistentStoreForURL:[self storeURLFromPath:[inAbsoluteURL path]]];
if (store) {
[psc removePersistentStore:store error:outError];
}
return [super revertToContentsOfURL:inAbsoluteURL ofType:inTypeName error:outError];
}
#pragma mark -
#pragma mark Media management
@ -231,8 +59,10 @@ static NSString *StoreFileName = @"MediannoDB.sql";
{
NSManagedObjectContext *moc = [self managedObjectContext];
MAMedia * media = [NSEntityDescription insertNewObjectForEntityForName:@"MAMedia" inManagedObjectContext:moc];
media.media = [url path];
NSString * path = [url path];
media.media = path;
media.date = [date timeIntervalSince1970];
media.name = name;
[moc processPendingChanges];
}

View File

@ -24,7 +24,7 @@
<string>org.aereperennius.medianno-database</string>
</array>
<key>LSTypeIsPackage</key>
<true/>
<false/>
<key>NSDocumentClass</key>
<string>MADocument</string>
<key>NSPersistentStoreTypeKey</key>
@ -67,7 +67,6 @@
<key>UTTypeConformsTo</key>
<array>
<string>public.content</string>
<string>com.apple.package</string>
</array>
<key>UTTypeDescription</key>
<string>Medianno Database</string>