Skip to content

Instantly share code, notes, and snippets.

@ddb
Created February 10, 2011 22:07
Show Gist options
  • Save ddb/821456 to your computer and use it in GitHub Desktop.
Save ddb/821456 to your computer and use it in GitHub Desktop.
//
// 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
@ddb
Copy link
Author

ddb commented Feb 11, 2011

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment