Skip to content

Commit

Permalink
Solve PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
dianaafanador3 committed May 14, 2024
1 parent 26d3366 commit 760f3e5
Show file tree
Hide file tree
Showing 19 changed files with 241 additions and 184 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ x.y.z Release notes (yyyy-MM-dd)
realm.objects(MixedObject.self).where { $0.anyValue[0][0][1] == .double(76.54) }
```

The `.all` operator allows looking up in all keys or indexes.
The `.all` operator allows looking up in all keys or indexes, which is the same that using a wildcard as a subscript `["*"]`.
```swift
realm.objects(MixedObject.self).where { $0.anyValue["key"].all == .bool(false) }
```
Expand Down
18 changes: 5 additions & 13 deletions Realm/RLMCollection.mm
Original file line number Diff line number Diff line change
Expand Up @@ -156,19 +156,11 @@ - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
NSUInteger batchCount = 0, count = state->extra[1];

@autoreleasepool {
if (!_parentInfo) {
RLMAccessorContext ctx = RLMAccessorContext(*_info);
for (NSUInteger index = state->state; index < count && batchCount < len; ++index) {
_strongBuffer[batchCount] = _results->get(ctx, index);
batchCount++;
}
} else {
// This is used by Dicitonary and List for nested collections.
RLMAccessorContext ctx = RLMAccessorContext(*_parentInfo, *_info, _property);
for (NSUInteger index = state->state; index < count && batchCount < len; ++index) {
_strongBuffer[batchCount] = _results->get(ctx, index);
batchCount++;
}
auto ctx = _parentInfo ? RLMAccessorContext(*_parentInfo, *_info, _property) :
RLMAccessorContext(*_info);
for (NSUInteger index = state->state; index < count && batchCount < len; ++index) {
_strongBuffer[batchCount] = _results->get(ctx, index);
batchCount++;
}
}

Expand Down
14 changes: 2 additions & 12 deletions Realm/RLMManagedArray.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#import "RLMAccessor.hpp"
#import "RLMCollection_Private.hpp"
#import "RLMDictionary_Private.hpp"
#import "RLMObjectSchema_Private.hpp"
#import "RLMObjectStore.h"
#import "RLMObject_Private.hpp"
Expand Down Expand Up @@ -199,17 +198,8 @@ - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state

- (id)objectAtIndex:(NSUInteger)index {
return translateErrors([&]() -> id {
realm::Mixed value = _backingList.get_any(index);
RLMAccessorContext context(*_ownerInfo, *_objectInfo, _property);
if (value.is_type(realm::type_Dictionary)) {
return context.box(_backingList.get_dictionary(realm::PathElement{(int)index}));
}
else if (value.is_type(realm::type_List)) {
return context.box(_backingList.get_list(realm::PathElement{(int)index}));
}
else {
return _backingList.get(context, index);
}
return _backingList.get(context, index);
});
}

Expand Down Expand Up @@ -507,7 +497,7 @@ - (BOOL)isFrozen {
- (instancetype)resolveInRealm:(RLMRealm *)realm {
auto& parentInfo = _ownerInfo->resolve(realm);
return translateErrors([&] {
return [[RLMManagedArray alloc] initWithBackingCollection:_backingList.freeze(realm->_realm)
return [[self.class alloc] initWithBackingCollection:_backingList.freeze(realm->_realm)
parentInfo:&parentInfo
property:parentInfo.rlmObjectSchema[_property.name]];
});
Expand Down
15 changes: 2 additions & 13 deletions Realm/RLMManagedDictionary.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#import "RLMDictionary_Private.hpp"

#import "RLMAccessor.hpp"
#import "RLMArray_Private.hpp"
#import "RLMCollection_Private.hpp"
#import "RLMObjectSchema_Private.hpp"
#import "RLMObjectStore.h"
Expand Down Expand Up @@ -302,17 +301,7 @@ - (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))
BOOL stop = false;
@autoreleasepool {
for (auto&& [key, value] : _backingCollection) {
id nestedValue;
if (value.is_type(realm::type_Dictionary)) {
nestedValue = context.box(_backingCollection.get_dictionary(key.get_string()));
}
else if (value.is_type(realm::type_List)) {
nestedValue = context.box(_backingCollection.get_list(key.get_string()));
}
else {
nestedValue = context.box(value);
}
block(context.box(key), nestedValue, &stop);
block(context.box(key), _backingCollection.get(context, key.get_string()), &stop);
if (stop) {
break;
}
Expand Down Expand Up @@ -483,7 +472,7 @@ - (BOOL)isFrozen {
- (instancetype)resolveInRealm:(RLMRealm *)realm {
auto& parentInfo = _ownerInfo->resolve(realm);
return translateErrors([&] {
return [[RLMManagedDictionary alloc] initWithBackingCollection:_backingCollection.freeze(realm->_realm)
return [[self.class alloc] initWithBackingCollection:_backingCollection.freeze(realm->_realm)
parentInfo:&parentInfo
property:parentInfo.rlmObjectSchema[_property.name]];
});
Expand Down
65 changes: 36 additions & 29 deletions Realm/RLMQueryUtil.mm
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ void add_collection_operation_constraint(NSPredicateOperatorType operatorType,

CollectionOperation collection_operation_from_key_path(KeyPath&& kp);
ColumnReference column_reference_from_key_path(KeyPath&& kp, bool isAggregate);
void get_path_elements(std::vector<PathElement> &paths, NSExpression *expression);
NSString* get_path_elements(std::vector<PathElement> &paths, NSExpression *expression);

private:
Query& m_query;
Expand Down Expand Up @@ -1684,26 +1684,19 @@ bool is_self_value_for_key_path_function_expression(NSExpression *expression)
NSComparisonPredicateOptions options, NSPredicateOperatorType operatorType,
NSExpression *right) {
std::vector<PathElement> pathElements;
get_path_elements(pathElements, functionExpression);
NSString *keyPath = get_path_elements(pathElements, functionExpression);

NSString *keyPath;
NSExpression *keyPathExpression = functionExpression;

// We consider only `NSKeyPathExpressionType` values to build the keypath.
for (unsigned long i = 0; i < pathElements.size(); i++) {
if (keyPathExpression.arguments[0].expressionType == NSKeyPathExpressionType) {
keyPath = [NSString stringWithFormat:@"%@", keyPathExpression.arguments[0]];
} else {
keyPathExpression = keyPathExpression.arguments[0];
}
}
ColumnReference collectionColumn = column_reference_from_key_path(key_path_from_string(m_schema, objectSchema, keyPath), true);

if (collectionColumn.property().type == RLMPropertyTypeAny && !collectionColumn.property().dictionary) {
add_mixed_constraint(operatorType, options, std::move(collectionColumn.resolve<realm::Mixed>().path(pathElements)), right.constantValue);
} else {
RLMPrecondition(collectionColumn.property().dictionary, @"Invalid predicate",
@"Invalid keypath '%@': only dictionaries and mixed support subscript predicates.", functionExpression);
RLMPrecondition(pathElements.size() == 1, @"Invalid subscript size",
@"Invalid subscript size '%@': nested dictionaries queries are only allowed in mixed properties.", functionExpression);
RLMPrecondition(pathElements[0].is_key(), @"Invalid subscript type",
@"Invalid subscript type '%@'; only string keys are allowed as subscripts in dictionary queries.", functionExpression);
add_mixed_constraint(operatorType, options, std::move(collectionColumn.resolve<Dictionary>().key(pathElements[0].get_key())), right.constantValue);
}
}
Expand Down Expand Up @@ -1857,28 +1850,42 @@ bool is_self_value_for_key_path_function_expression(NSExpression *expression)
}

// This function returns the nested subscripts from a NSPredicate with the following format `anyCol[0]['key']['all']`
// This will iterate each argument of the NSExpression and its nested NSExpression's and take the constant value
// and create a PathElement for the query.
void QueryBuilder::get_path_elements(std::vector<PathElement> &paths, NSExpression *expression) {
// and its respective keypath (including any linked keypath)
// This will iterate each argument of the NSExpression and its nested NSExpressions, takes the constant subscript
// and creates a PathElement to be used in the query.
NSString* QueryBuilder::get_path_elements(std::vector<PathElement> &paths, NSExpression *expression) {
NSString *keyPath = @"";
for (NSUInteger i = 0; i < expression.arguments.count; i++) {
NSString *nestedKeyPath = @"";
if (expression.arguments[i].expressionType == NSFunctionExpressionType) {
get_path_elements(paths, expression.arguments[i]);
} else {
if (expression.arguments[i].expressionType == NSConstantValueExpressionType) {
id value = [expression.arguments[i] constantValue];
if ([value isKindOfClass:[NSNumber class]]) {
paths.push_back(PathElement{[(NSNumber *)value intValue]});
} else if ([value isKindOfClass:[NSString class]]) {
NSString *key = (NSString *)value;
if ([key isEqual:@"all"]) {
paths.push_back(PathElement{});
} else {
paths.push_back(PathElement{key.UTF8String});
}
nestedKeyPath = get_path_elements(paths, expression.arguments[i]);
} else if (expression.arguments[i].expressionType == NSConstantValueExpressionType) {
id value = [expression.arguments[i] constantValue];
if ([value isKindOfClass:[NSNumber class]]) {
paths.push_back(PathElement{[(NSNumber *)value intValue]});
} else if ([value isKindOfClass:[NSString class]]) {
NSString *key = (NSString *)value;
if ([key isEqual:@"*"]) {
paths.push_back(PathElement{});
} else {
paths.push_back(PathElement{key.UTF8String});
}
} else {
throwException(@"Invalid subscript type",
@"Only `Strings` or index are allowed subscripts");
}
} else if (expression.arguments[i].expressionType == NSKeyPathExpressionType) {
nestedKeyPath = expression.arguments[i].keyPath;
} else {
throwException(@"Invalid expression type",
@"Subscripts queries don't allow any other expression types");
}
if ([nestedKeyPath length] > 0) {
keyPath = ([keyPath length] > 0) ? [NSString stringWithFormat:@"%@.%@", keyPath, nestedKeyPath] : [NSString stringWithFormat:@"%@", nestedKeyPath];
}
}

return keyPath;
}
} // namespace

Expand Down
4 changes: 0 additions & 4 deletions Realm/RLMUtil.mm
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,6 @@ void RLMValidateValueForProperty(__unsafe_unretained id const obj,
if (prop.type == RLMPropertyTypeObject && !validateObjects) {
return;
}

if (prop.type == RLMPropertyTypeAny) {
return;
}

if (RLMIsObjectValidForProperty(obj, prop)) {
return;
Expand Down
8 changes: 8 additions & 0 deletions Realm/RLMValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,11 @@
/// :nodoc:
@interface NSArray (RLMValue)<RLMValue>
@end

/// :nodoc:
@interface RLMArray (RLMValue)<RLMValue>
@end

/// :nodoc:
@interface RLMDictionary (RLMValue)<RLMValue>
@end
51 changes: 32 additions & 19 deletions Realm/RLMValue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
@implementation NSData (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeData;
}
Expand All @@ -41,7 +41,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSDate (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeDate;
}
Expand All @@ -58,7 +58,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSNumber (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
if ([self objCType][0] == 'c' && (self.intValue == 0 || self.intValue == 1)) {
return RLMPropertyTypeBool;
Expand All @@ -79,10 +79,21 @@ - (RLMPropertyType)rlm_valueType {
#pragma clang diagnostic pop

- (RLMAnyValueType)rlm_anyValueType {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return (RLMAnyValueType)self.rlm_valueType;
#pragma clang diagnostic pop
if ([self objCType][0] == 'c' && (self.intValue == 0 || self.intValue == 1)) {
return RLMAnyValueTypeBool;
}
else if (numberIsInteger(self)) {
return RLMAnyValueTypeInt;
}
else if (*@encode(float) == [self objCType][0]) {
return RLMAnyValueTypeFloat;
}
else if (*@encode(double) == [self objCType][0]) {
return RLMAnyValueTypeDouble;
}
else {
@throw RLMException(@"Unknown numeric type on type RLMValue.");
}
}

@end
Expand All @@ -92,7 +103,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSNull (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeAny;
}
Expand All @@ -109,7 +120,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSString (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeString;
}
Expand All @@ -126,7 +137,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSUUID (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeUUID;
}
Expand All @@ -143,7 +154,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation RLMDecimal128 (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeDecimal128;
}
Expand All @@ -160,7 +171,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation RLMObjectBase (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeObject;
}
Expand All @@ -177,7 +188,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation RLMObjectId (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
return RLMPropertyTypeObjectId;
}
Expand All @@ -194,7 +205,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSDictionary (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
REALM_UNREACHABLE();
}
Expand All @@ -209,7 +220,7 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation RLMDictionary (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
REALM_UNREACHABLE();
}
Expand All @@ -226,10 +237,11 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation NSArray (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
REALM_UNREACHABLE();
return RLMPropertyTypeAny;
}
#pragma clang diagnostic pop

- (RLMAnyValueType)rlm_anyValueType {
return RLMAnyValueTypeList;
Expand All @@ -240,10 +252,11 @@ - (RLMAnyValueType)rlm_anyValueType {
@implementation RLMArray (RLMValue)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (RLMPropertyType)rlm_valueType {
REALM_UNREACHABLE();
return RLMPropertyTypeAny;
}
#pragma clang diagnostic pop

- (RLMAnyValueType)rlm_anyValueType {
return RLMAnyValueTypeList;
Expand Down
3 changes: 1 addition & 2 deletions Realm/Tests/ObjectTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,7 @@ - (void)testCreateInRealmValidationForDictionary {
}

if ([keyToInvalidate isEqualToString:@"anyCol"]) {
// Mixed properties now can accept dictionary or list, so we are skipping testing invalid values for this.
continue;
obj = self;
}

invalidInput[keyToInvalidate] = obj;
Expand Down

0 comments on commit 760f3e5

Please sign in to comment.