#import "SoulSeek.h" @implementation SoulSeek(DataMethods) - (NSString *)applicationSupportFolder { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory(); return [basePath stringByAppendingPathComponent:@"SolarSeek"]; } /** Creates, retains, and returns the managed object model for the application by merging all of the models found in the application bundle and all of the framework bundles. */ - (NSManagedObjectModel *)managedObjectModel { if (managedObjectModel != nil) { return managedObjectModel; } NSMutableSet *allBundles = [[NSMutableSet alloc] init]; [allBundles addObject: [NSBundle mainBundle]]; [allBundles addObjectsFromArray: [NSBundle allFrameworks]]; managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: [allBundles allObjects]] retain]; [allBundles release]; return managedObjectModel; } /** Returns the persistent store coordinator for the application. This implementation will create and return a coordinator, having added the store for the application to it. (The folder for the store is created, if necessary.) */ - (NSPersistentStoreCoordinator *) persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSFileManager *fileManager; NSString *applicationSupportFolder = nil; NSURL *url; NSError *error; fileManager = [NSFileManager defaultManager]; applicationSupportFolder = [self applicationSupportFolder]; if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) { [fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil]; } url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"SolarSeek.data"]]; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; // if u need to debug, use NSSQLXMLStoreType if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]){ [[NSApplication sharedApplication] presentError:error]; } return persistentStoreCoordinator; } /** Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) */ - (NSManagedObjectContext *) exclusiveManagedObjectContext { id moc = nil; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { moc = [[NSManagedObjectContext alloc] init]; [moc setPersistentStoreCoordinator: coordinator]; } return [moc autorelease]; } -(NSManagedObjectContext *)managedObjectContext { when_foreground { return managedObjectContextForForegroundThread; } when_background { return managedObjectContextForBackgroundThread; } return nil; } -(void) refreshObject:(NSManagedObjectID *)objectID { [[self managedObjectContext] objectWithID:objectID]; } -(void) saveNotification:(NSNotification *)notification { id moc = [notification object]; if (moc == managedObjectContextForBackgroundThread) { when_foreground{ NSLog(@"[FOREGROUND] time to merge... "); } when_background{ NSLog(@"[BACKGROUND] time to merge... "); } NSArray* deleted = [[notification userInfo] valueForKey:NSDeletedObjectsKey]; NSArray* modified = [[notification userInfo] valueForKey:NSDeletedObjectsKey]; NSEnumerator *e = [deleted objectEnumerator]; NSManagedObject *o; while (o = [e nextObject]) { NSManagedObject *o2 = [managedObjectContextForForegroundThread objectWithID:[o objectID]]; } [managedObjectContextForForegroundThread processPendingChanges]; } } -(void) prepareManagedObjectContexts { managedObjectContextForBackgroundThread = [[self exclusiveManagedObjectContext] retain]; //managedObjectContextForForegroundThread = managedObjectContextForBackgroundThread; managedObjectContextForForegroundThread = [[self exclusiveManagedObjectContext] retain]; [managedObjectContextForForegroundThread setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; // [[NSNotificationCenter defaultCenter] addObserver:self // selector:@selector(saveNotification:) // name:NSManagedObjectContextDidSaveNotification object:nil]; // cleanup... // removing all rooms you are not in // removing all peers // removing all messages // removing all files // creating the basic rooms NSManagedObjectContext *moc = [self managedObjectContext]; NSManagedObject *allRooms = [self update:@"SidebarItem" withName:@"ALL ROOMS"]; NSManagedObject *talk = [self update:@"SidebarItem" withName:@"TALK"]; NSManagedObject *network = [self update:@"SidebarItem" withName:@"NETWORK"]; NSManagedObject *search = [self update:@"SidebarItem" withName:@"SEARCH"]; NSManagedObject *friends = [self update:@"SidebarItem" withName:@"FRIENDS"]; // this is hidden NSManagedObject *networkDownloads = [self update:@"SidebarItem" withName:@"Downloads"]; NSManagedObject *networkUploads = [self update:@"SidebarItem" withName:@"Uploads"]; NSManagedObject *networkFriends = [self update:@"SidebarItem" withName:@"Friends"]; NSMutableSet *children = [network mutableSetValueForKey:@"children"]; [children addObjectsFromArray:[NSArray arrayWithObjects:networkDownloads, networkUploads, networkFriends, nil]]; /* sidebar organization : ALL ROOMS -> (not selectable, hidden) all rooms available in SoulSeek network, but hidden NETWORK -> (not selectable) dumb item Downloads Uploads Friends -> display the FriendsContentView TALKS -> (not selectable) user has joined these rooms ... -> display the ChatRoomContentView SEARCH -> (not selectable) add searches here ... -> display the SearchResultsContentView FRIENDS -> (not selectable, hidden) add users here, FriendsContentView use it */ int i = 0; [allRooms setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [friends setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [network setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [networkDownloads setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [networkUploads setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [networkFriends setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [talk setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [search setValue:[NSNumber numberWithInt:i++] forKey:@"order"]; [allRooms setValue:[NSNumber numberWithBool:YES] forKey:@"hidden"]; [friends setValue:[NSNumber numberWithBool:YES] forKey:@"hidden"]; [moc save:nil]; } /** Implementation of dealloc, to release the retained variables. */ - (void) dealloc { [managedObjectContextForBackgroundThread release], managedObjectContextForBackgroundThread = nil; [managedObjectContextForForegroundThread release], managedObjectContextForForegroundThread = nil; [persistentStoreCoordinator release], persistentStoreCoordinator = nil; [managedObjectModel release], managedObjectModel = nil; [super dealloc]; } -(NSManagedObject *) find:(NSString *)entity withName:(NSString *)name { NSManagedObjectContext *moc = [self managedObjectContext]; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:entity inManagedObjectContext:moc]; NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; [request setEntity:entityDescription]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", name]; [request setPredicate:predicate]; NSError *error = nil; NSArray *array = [moc executeFetchRequest:request error:&error]; if (array != nil) { if ([array count] == 0) { return nil; } if ([array count] > 1) { NSLog(@"Warning : more than one %@ with the name '%@'", entity, name); } return [array objectAtIndex:0]; } return nil; } -(NSManagedObject *)new:(NSString *)entity withName:(NSString *)name { NSManagedObjectContext *moc = [self managedObjectContext]; NSManagedObject *item = [NSEntityDescription insertNewObjectForEntityForName:entity inManagedObjectContext:moc]; [item setValue:name forKey:@"name"]; return item; } -(NSManagedObject *)update:(NSString *)entity withName:(NSString *)name { id obj = [self find:entity withName:name]; if (!obj) obj = [self new:entity withName:name]; //else [[self managedObjectContext] refreshObject:obj mergeChanges:YES]; return obj; } @end