The BDControl Framework

Qualifiers
Sort Orderings
Known Issues

The BDControl Framework supplies some of the useful functionality that used to be provided as part of EOF's EOControl framework. Specifically, in version 1.0, BDControl provides qualifiers and sort orderings.

No other EOF functionality is provided at this time.

The BDControl Framework is released as Open Source under a BSD license by bDistributed.com, Inc. Please see http://bdistributed.com/Projects/BDControl.html for the latest source code and binary release.

Qualifiers

Qualifiers are predicates that can be applied to arbitrary objects. They use Key-Value Coding (KVC) to inspect an object, and can be formed into arbitrarily complex expressions.

Qualifiers can be created programmatically by either instantiating the various concrete subclasses of BDQualifier or by specifying a format string that is parsed into a hierarchy of qualifier objects. Qualifier format strings use identical metacharacters (%@ etc.) to the format strings used by -[NSString stringWithFormat:]. For additional information on the syntax of qualifier strings, see the BDQualifier class documentation.

Concrete qualifier subclasses exist to:

Additional qualifier subclasses can be added, though they will not be parsed by the qualifier format string parser.

Key-value qualifiers may use qualifier variables (represented by instances of BDQualifierVariable) in place of concrete values. A qualifier that contains a variable may not be evaluated against an object directly; instead, it must be sent -qualifierWithBindings:requiresAllVariables: and the resulting new qualifier evaluated against an object. This message takes a dictionary of bindings that are used to replace variables within the qualifier, and a boolean value indicating whether all variables must be replaced with bindigns in the dictionary. If this value is YES and not all variables are replaced, a BDQualifierVariableSubstitutionException exception is raised. If this value is NO and not all variables are replaced, any expressions containing unreplaced variables are "pruned" from the resulting qualifier.

NSArray (BDQualifierAdditions)

The utility method -filteredArrayUsingQualifier: is added to NSArray via the category BDQualifierAdditions. When this message is sent to an array with a qualifier as its argument, it returns a new array containing only the values in the array that match the qualifier.

For example, to find all of the red, recent-model cars in a collection of cars, one could write:

- (NSArray *)redCarsReleasedAfterYear:(int)year
                               inCars:(NSArray *)cars
{
    BDQualifier *q = [BDQualifier qualifierWithQualifierFormat:
                         @"(modelYear >= %d) and (color = 'red')", year];

    return [cars filteredArrayUsingQualifier:q];
}

Sort Orderings

Sort orderings specify a way to sort arbitrary objects in a collection. A sort ordering, represented by an instance of BDSortOrdering, contains a key in the objects to sort on and a selector with which to order the sort.

NSObject (BDSortOrderingAdditions)

Additional support for object comparison is added to all objects via the category BDSortOrderingAdditions on NSObject.

NSArray (BDSortOrderingAdditions)

The utility method -sortedArrayUsingKeyOrderArray: is added to NSArray via the category BDSortOrderingAdditions. When this message is sent to an array with an array of sort orderings as its argument, it returns a new array sorted according to the given sort orderings. The sort orderings in the array are in order of importance; thus, to sort an array of Person objects by last name and then first name, one could write the following:

- (NSArray *)sortPeopleByLastNameThenFirstName:(NSArray *)people
{
    BDSortOrdering *lastNameOrdering, *firstNameOrdering;
    NSArray *orderings;
    
    lastNameOrdering = [BDSortOrdering sortOrderingWithKey:@"lastName"
                            selector:BDCompareCaseInsensitiveAscending];
    firstNameOrdering = [BDSortOrdering sortOrderingWithKey:@"firstName"
                            selector:BDCompareCaseInsensitiveAscending];
    
    orderings = [NSArray arrayWithObjects:lastNameOrdering, firstNameOrdering, nil];
    
    return [people sortedArrayUsingKeyOrderArray:orderings];
}

NSMutableArray (BDSortOrderingAdditions)

The utility method -sortUsingKeyOrderArray: is added to NSMutableArray via the category BDSortOrderingAdditions. When this message is sent to a mutable array with an array of sort orderings as its argument, it sorts the array according to the given sort orderings.

Known Issues

The qualifier parser is implemented with lex and yacc, and is therefore not reentrant. It is protected with a lock, but may as a result be slow in a multithreaded application that attempts to create qualifiers from several threads.

The qualifier parser treats numbers as C double values before converting them to instances of NSNumber. Be careful with precision.

Qualifier evaluation is recursive, which could potentially result in significant stack usage for very large qualifiers.

Strings within qualifiers created from format strings may contain UTF-8, but all keys, selectors, etc. must be identifier characters in the set [A-Za-z0-9_].

When parsing a qualifier from a string, no optimization is performed on the resulting parse tree. In other words, the qualifier string "foo = 'foo' and bar = 'bar' and baz = 'baz'" will not be parsed into one BDAndQualifier instance containing three BDKeyValueQualifier instances. Instead, it will be parsed into two BDAndQualifier instances, one containing a BDKeyValueQualifier instance and the second BDAndQualifier instance, and the other containing two BDKeyValueQualifier instances.


Copyright © 2002, 2003, bDistributed.com, Inc. All rights reserved worldwide.