Created
February 10, 2011 22:07
-
-
Save ddb/821456 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ObjCEntity.m | |
// Entity | |
// | |
// Created by dbrown on 2/10/11. | |
// Copyright 2011 __MyCompanyName__. All rights reserved. | |
// | |
#import "ObjCEntity.h" | |
@interface ObjCEntity (private) | |
+ (NSArray*)findFromContext:(NSManagedObjectContext*)moc | |
withEntity:(NSString*)ename | |
withPredicate:(NSPredicate*)pred | |
options:(NSDictionary*)opts; | |
+ (NSPredicate*)extractPredicate:(NSDictionary*)opts; | |
@end | |
@implementation ObjCEntity | |
NSString* entityName = @""; | |
+ (void)initialize { | |
entityName = NAMEOF([self class]); | |
} | |
+ (NSArray*)findFirstWithContext:(NSManagedObjectContext*)moc | |
options:(NSDictionary*)opts { | |
NSPredicate* pred = [self extractPredicate:opts]; | |
NSMutableDictionary* newOpts = [opts mutableCopy]; | |
[newOpts setValue:[NSNumber numberWithInt:1] forKey:@"limit"]; | |
return [self findFromContext:moc | |
withEntity:entityName | |
withPredicate:pred | |
options:newOpts]; | |
} | |
+ (NSArray*)findAllWithContext:(NSManagedObjectContext*)moc | |
options:(NSDictionary*)opts { | |
NSPredicate* pred = [self extractPredicate:opts]; | |
return [self findFromContext:moc | |
withEntity:entityName | |
withPredicate:pred | |
options:opts]; | |
} | |
+ (NSArray*)findFromContext:(NSManagedObjectContext*)moc | |
withEntity:(NSString*)ename | |
withPredicate:(NSPredicate*)pred | |
options:(NSDictionary*)opts { | |
NSFetchRequest* fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; | |
NSEntityDescription* entityDescription = [NSEntityDescription entityForName:ename | |
inManagedObjectContext:moc]; | |
[fetchRequest setEntity:entityDescription]; | |
[fetchRequest setPredicate:pred]; | |
NSNumber* offset = [opts objectForKey:@"offset"]; | |
NSNumber* limit = [opts objectForKey:@"limit"]; | |
if (offset) { | |
[fetchRequest setFetchOffset:[offset intValue]]; | |
} | |
if (limit) { | |
[fetchRequest setFetchLimit:[limit intValue]]; | |
} | |
NSError* error; | |
return [moc executeFetchRequest:fetchRequest error:&error]; | |
} | |
+ (NSPredicate*)extractPredicate:(NSDictionary*)opts { | |
NSMutableArray* preds = [NSMutableArray array]; | |
NSMutableArray* pred_opt = [NSMutableArray array]; | |
NSMutableArray* byLines = [NSMutableArray array]; | |
for (NSString* key in [opts allKeys]) { | |
if ([key hasPrefix:@"by_"]) { | |
NSString* searchKey = [key substringFromIndex:3]; | |
[preds addObject:[NSString stringWithFormat:@"%@ = %%@", searchKey]]; | |
[pred_opt addObject:[opts valueForKey:key]]; | |
[byLines addObject:key]; | |
} else if ([key isEqualToString:@"conditions"]) { | |
NSArray* cond = [opts objectForKey:key]; | |
[preds addObject:[cond objectAtIndex:0]]; | |
[pred_opt addObject:[cond subarrayWithRange:NSMakeRange(1, [cond count] - 1)]]; | |
[byLines addObject:key]; | |
} | |
} | |
if ([preds count] == 0) { | |
return nil; | |
} | |
NSString* predString = [preds componentsJoinedByString:@" AND "]; | |
NSPredicate* result = [NSPredicate predicateWithFormat:predString argumentArray:pred_opt]; | |
[opts removeObjectsInArray:byLines]; | |
return result; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I admit to being unsure how to translate from the original, so I ended up with the subArrayWithRange: stuff. Yes, I think your version would do the trick.
I think we've got a basic difference in preference here. I come from a Lisp and Smalltalk background -- the way that the arguments are distributed through the method name allows me to make complete sentences, rather than mapping everything into a prefix form. I can appreciate what you are saying, I know that I just tend to prefer my own code. Go figure. ;)
Thank you for the compliments. But remember to TEST THE CODE. I have not run this, it was a straightforward translation of your ruby code. I wanted to back up my "I don't see any reason this needed to be in Ruby" comment with an example.