Artikel getaggt mit CoreData

CoreData generic findManyByKey

The base for many of my SELECT-ish queries when querying by exact match is one generic method I created in some category methods on NSManagedObjectContext:

-(NSArray*)entityName:(NSString*)entityName findManyByRelation:(NSDictionary*)dict
{
//  TODO handle dict nil and emptyness
    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:dict.count];
    for(NSString *key in dict)
    {
        NSExpression *left = [NSExpression expressionForKeyPath:key];
        NSExpression *right = [NSExpression expressionForConstantValue:[dict objectForKey:key]];
        NSComparisonPredicate *cp = [[NSComparisonPredicate alloc] initWithLeftExpression:left
            rightExpression:right modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];
        [arr addObject:cp];
        [cp release];
    }
    NSPredicate *pred = nil;
    if(arr.count == 1)
        pred = [[arr objectAtIndex:0] retain];    // why do I have to retain here?
    else
        pred = [[NSCompoundPredicate alloc] initWithType:NSAndPredicateType subpredicates:arr];
 
    NSFetchRequest *fr = [[NSFetchRequest alloc] init];
    fr.entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
    fr.predicate = pred;
    [arr release];
    [pred release];
//	NSLog(@"predicate effective: %@", fr.predicate);
 
    NSError *err = nil;
    NSArray *ps = [self executeFetchRequest:fr error:&err];
    if(err != nil)
        [NSException raise:@"DB Error" format:@"Fetch problem %@", fr.predicate.predicateFormat];
    [fr release];
    return ps;
}

For example it serves under the hood of it’s sibling helpers

-(NSManagedObject*)entityName:(NSString*)entityName findByPrimaryKey:(NSDictionary*)dict
{
    NSArray *ps = [self entityName:entityName findManyByRelation:dict];
    if(ps == nil || ps.count == 0)
        return nil;
    if (ps.count == 1)
        return [ps objectAtIndex:0];
    [NSException raise:@"DB Error" format:@"Multiple hits for %@", dict];
    return (NSManagedObject*)1/0;
}

and

-(NSManagedObject*)entityName:(NSString*)entityName selectOrInsertWithKey:(NSDictionary*)dict
{
    NSManagedObject *o = [self entityName:entityName findByPrimaryKey:dict];
    if(o == nil)
    {
        NSEntityDescription *ed = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
        o = [[NSManagedObject alloc] initWithEntity:ed insertIntoManagedObjectContext:self];
        for(NSString *key in dict)
            [o setValue:[dict objectForKey:key] forKey:key];
        [o autorelease];
    }
    return o;
}

Those methods again are called by custom convenience wrappers in the model classes loosely following the ActiveRecord Pattern.

Tags: , , , , , , ,

CocoaTouch, CoreData and binary String Search

The query optimiser for NSPredicate queries ontop CoreData/SQLite on the iPhone is a bit rudimentary (cough) and so I had to optimise myself to get binary-search enabled quick results:

Den Rest des Eintrags lesen. »

Tags: , , , , , ,

CoreData – Hello World.

CoreData ist im iPhone OS 3.0 ganz frisch dazugekommen und riecht auch noch ein wenig nach Plastik.

Leider ist der Beispielcode auf den Apple auch im iPhone CoreData Tutorial immer wieder verweist (Locations Sample Project) dem Umzug der OS 3.0 beta um Opfer gefallen.

Also los geht’s zum ersten Schritt:

Den Rest des Eintrags lesen. »

Tags: , ,