Repository: realm/realm-swift
File: Realm/RLMQueryUtil.mm (Objective-C++)

Code before:

void validate_value_for_query(id value, RLMProperty *prop, BOOL betweenOperation) {
    if (betweenOperation) {
        if ([value isKindOfClass:[NSArray class]]) {
            NSArray *array = value;
            if (array.count == 2) {
                if (!RLMIsObjectValidForProperty(array.firstObject, prop) ||
                    !RLMIsObjectValidForProperty(array.lastObject, prop)) {
                    @throw RLMPredicateException(@"Invalid value",
                                                [NSString stringWithFormat:@"NSArray objects must be of type %@ for BETWEEN operations", RLMTypeToString(prop.type)]);
                }
            } else {
                @throw RLMPredicateException(@"Invalid value", @"NSArray object must contain exactly two objects for BETWEEN operations");
            }
        } else {
            @throw RLMPredicateException(@"Invalid value", @"object must be of type NSArray for BETWEEN operations");
        }
    } else {
        if (!RLMIsObjectValidForProperty(value, prop)) {
            @throw RLMPredicateException(@"Invalid value", [NSString stringWithFormat:@"object must be of type %@", RLMTypeToString(prop.type)]);
        }
    }
}

void update_query_with_value_expression(RLMSchema *schema,
                                        RLMObjectSchema *desc,
                                        tightdb::Query &query,
                                        NSString *columnName,
                                        id value,
                                        NSPredicateOperatorType operatorType,
                                        NSComparisonPredicateOptions predicateOptions)
{
    // validate object type
    NSArray *arr = [columnName componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"."]];
    NSString *firstColumnName = [arr objectAtIndex:0];
    NSString *secondColumnName;

    BOOL isLinkQuery = NO;
    NSUInteger firstIndex, secondIndex = 0;
    RLMPropertyType secondType = RLMPropertyTypeAny;

    firstIndex = RLMValidatedColumnIndex(desc, firstColumnName);
    RLMProperty *firstProp = desc[firstColumnName];

    // FIXME: when core support multiple levels of link queries, change == to >=
    //        and loop through the elements of arr to build up link query
    if ([arr count] == 2) {
        isLinkQuery = YES;
        if (firstProp.type != RLMPropertyTypeObject && firstProp.type != RLMPropertyTypeArray) {
            throw RLMPredicateException(@"Invalid value", [NSString stringWithFormat:@"column name '%@' is not a link", firstColumnName]);
        }

Review comment (suggestion):
Please consider to call the function `add_link_constraint_to_query`.


Code after:
                                    NSData *value) {
    tightdb::BinaryData binData = RLMBinaryDataForNSData(value);
    switch (operatorType) {
        case NSBeginsWithPredicateOperatorType:
            query.begins_with(index, binData);
            break;
        case NSEndsWithPredicateOperatorType:
            query.ends_with(index, binData);
            break;
        case NSContainsPredicateOperatorType:
            query.contains(index, binData);
            break;
        case NSEqualToPredicateOperatorType:
            query.equal(index, binData);
            break;
        case NSNotEqualToPredicateOperatorType:
            query.not_equal(index, binData);
            break;
        default:
            @throw RLMPredicateException(@"Invalid operator type",
                                           [NSString stringWithFormat:@"Operator type %lu not supported for binary type", (unsigned long)operatorType]);
            break;
    }
}
    
void add_link_contraint_to_query(tightdb::Query & query,
                                 NSPredicateOperatorType operatorType,
                                 NSUInteger column,
                                 RLMObject *obj) {
    if (operatorType != NSEqualToPredicateOperatorType) {
        @throw RLMPredicateException(@"Invalid operator type", @"Only 'Equal' operator supported for object comparison");
    }
    query.links_to(column, obj->_row.get_index());
}
 
void update_link_query_with_value_expression(RLMSchema *schema,
                                             RLMObjectSchema *desc,
                                             tightdb::Query &query,
                                             NSArray *paths,
                                             id value,
                                             NSComparisonPredicate *pred)
{
    if (pred.predicateOperatorType == NSBetweenPredicateOperatorType) {
        @throw RLMPredicateException(@"Invalid predicate", @"BETWEEN operator not supported for KeyPath queries.");
    }

    // FIXME: when core support multiple levels of link queries, change == to >=
    //        and loop through the elements of arr to build up link query
    if (paths.count != 2) {
        @throw RLMPredicateException(@"Invalid predicate", @"Only KeyPaths one level deep are currently supported");
    }