added iOS source code
[wl-app.git] / iOS / Pods / Realm / Realm / RLMSyncPermissionResults.mm
diff --git a/iOS/Pods/Realm/Realm/RLMSyncPermissionResults.mm b/iOS/Pods/Realm/Realm/RLMSyncPermissionResults.mm
new file mode 100644 (file)
index 0000000..39354f1
--- /dev/null
@@ -0,0 +1,262 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2017 Realm Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////
+
+#import "RLMSyncPermissionResults.h"
+
+#import "RLMCollection_Private.hpp"
+#import "RLMObjectSchema_Private.hpp"
+#import "RLMQueryUtil.hpp"
+#import "RLMResults_Private.hpp"
+#import "RLMSchema_Private.hpp"
+#import "RLMSyncPermission_Private.hpp"
+#import "RLMSyncUtil_Private.hpp"
+#import "RLMUtil.hpp"
+
+#import "object.hpp"
+
+using namespace realm;
+
+namespace {
+
+bool keypath_is_valid(NSString *keypath)
+{
+    static NSSet<NSString *> *valid = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        valid = [NSSet setWithArray:@[RLMSyncPermissionSortPropertyPath,
+                                      RLMSyncPermissionSortPropertyUserID,
+                                      RLMSyncPermissionSortPropertyUpdated]];
+    });
+    return [valid containsObject:keypath];
+}
+
+}
+
+/// Sort by the Realm Object Server path to the Realm to which the permission applies.
+RLMSyncPermissionSortProperty const RLMSyncPermissionSortPropertyPath       = @"path";
+/// Sort by the identity of the user to whom the permission applies.
+RLMSyncPermissionSortProperty const RLMSyncPermissionSortPropertyUserID     = @"userId";
+/// Sort by the date the permissions were last updated.
+RLMSyncPermissionSortProperty const RLMSyncPermissionSortPropertyUpdated    = @"updatedAt";
+
+@interface RLMSyncPermissionResults ()
+@property (nonatomic, strong) RLMSchema *schema;
+@property (nonatomic, strong) RLMObjectSchema *objectSchema;
+@end
+
+@implementation RLMSyncPermissionResults
+
+#pragma mark - Public API
+
+- (RLMPropertyType)type {
+    return RLMPropertyTypeObject;
+}
+
+- (NSString *)objectClassName {
+    return NSStringFromClass([RLMSyncPermission class]);
+}
+
+- (RLMRealm *)realm {
+    return nil;
+}
+
+- (RLMSyncPermission *)objectAtIndex:(NSUInteger)index {
+    return translateRLMResultsErrors([&] {
+        Object permission(_results.get_realm(), _results.get_object_schema(), _results.get(index));
+        return [[RLMSyncPermission alloc] initWithPermission:Permission(permission)];
+    });
+}
+
+- (RLMSyncPermission *)firstObject {
+    return self.count == 0 ? nil : [self objectAtIndex:0];
+}
+
+- (RLMSyncPermission *)lastObject {
+    return self.count == 0 ? nil : [self objectAtIndex:(self.count - 1)];
+}
+
+- (NSUInteger)indexOfObject:(RLMSyncPermission *)object {
+    if (object.key) {
+        // Key-value permissions are only used for setting; they are never returned.
+        return NSNotFound;
+    }
+    // Canonicalize the path.
+    NSString *path = object.path;
+    if ([path rangeOfString:@"~"].location != NSNotFound) {
+        path = [path stringByReplacingOccurrencesOfString:@"~" withString:object.identity];
+    }
+    NSString *topPrivilege;
+    switch (object.accessLevel) {
+        case RLMSyncAccessLevelNone:
+            // Deleted permissions are removed from the permissions Realm by ROS.
+            return NSNotFound;
+        case RLMSyncAccessLevelRead:
+            topPrivilege = @"mayRead";
+            break;
+        case RLMSyncAccessLevelWrite:
+            topPrivilege = @"mayWrite";
+            break;
+        case RLMSyncAccessLevelAdmin:
+            topPrivilege = @"mayManage";
+            break;
+    }
+    // Build the predicate.
+    NSPredicate *p = [NSPredicate predicateWithFormat:@"%K = %@ AND %K = %@ AND %K == YES",
+                      RLMSyncPermissionSortPropertyPath, path,
+                      RLMSyncPermissionSortPropertyUserID, object.identity,
+                      topPrivilege];
+    return [self indexOfObjectWithPredicate:p];
+}
+
+- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate {
+    return translateRLMResultsErrors([&] {
+        auto& group = _results.get_realm()->read_group();
+        auto query = RLMPredicateToQuery(predicate, self.objectSchema, self.schema, group);
+        return RLMConvertNotFound(_results.index_of(std::move(query)));
+    });
+}
+
+- (RLMResults<RLMSyncPermission *> *)objectsWithPredicate:(NSPredicate *)predicate {
+    return translateRLMResultsErrors([&] {
+        auto query = RLMPredicateToQuery(predicate, self.objectSchema, self.schema, _results.get_realm()->read_group());
+        return [[RLMSyncPermissionResults alloc] initWithResults:_results.filter(std::move(query))];
+    });
+}
+
+- (RLMResults<RLMSyncPermission *> *)sortedResultsUsingDescriptors:(NSArray<RLMSortDescriptor *> *)properties {
+    if (properties.count == 0) {
+        return self;
+    }
+    for (RLMSortDescriptor *descriptor in properties) {
+        if (!keypath_is_valid(descriptor.keyPath)) {
+            @throw RLMException(@"Invalid keypath specified. Use one of the constants defined in "
+                                @" `RLMSyncPermissionSortProperty`.");
+        }
+    }
+    return translateRLMResultsErrors([&] {
+        auto sorted = _results.sort(RLMSortDescriptorsToKeypathArray(properties));
+        return [[RLMSyncPermissionResults alloc] initWithResults:std::move(sorted)];
+    });
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmismatched-parameter-types"
+- (RLMNotificationToken *)addNotificationBlock:(void(^)(RLMSyncPermissionResults *results,
+                                                        RLMCollectionChange *change,
+                                                        NSError *error))block {
+    auto cb = [=](const realm::CollectionChangeSet& changes, std::exception_ptr ptr) {
+        if (ptr) {
+            NSError *error = translateSyncExceptionPtrToError(std::move(ptr), RLMPermissionActionTypeGet);
+            REALM_ASSERT(error);
+            block(nil, nil, error);
+        } else {
+            // Finished successfully
+            block(self, [[RLMCollectionChange alloc] initWithChanges:changes], nil);
+        }
+    };
+    return [[RLMCancellationToken alloc] initWithToken:_results.add_notification_callback(std::move(cb)) realm:nil];
+}
+#pragma clang diagnostic pop
+
+- (id)aggregate:(__unused NSString *)property
+         method:(__unused util::Optional<Mixed> (Results::*)(size_t))method
+     methodName:(__unused NSString *)methodName returnNilForEmpty:(__unused BOOL)returnNilForEmpty {
+    // We don't support any of the min/max/average/sum APIs; they don't make sense for this collection type.
+    return nil;
+}
+
+- (id)valueForKey:(NSString *)key {
+    size_t count = self.count;
+    if (count == 0) {
+        return @[];
+    }
+    NSMutableArray *results = [NSMutableArray arrayWithCapacity:count];
+    if ([key isEqualToString:@"self"]) {
+        for (size_t i = 0; i < count; i++) {
+            [results addObject:[self objectAtIndex:i]];
+        }
+    } else {
+        for (size_t i = 0; i < count; i++) {
+            [results addObject:[[self objectAtIndex:i] valueForKey:key] ?: NSNull.null];
+        }
+    }
+    return results;
+}
+
+- (void)setValue:(__unused id)value forKey:(__unused NSString *)key {
+    @throw RLMException(@"Cannot set values for the read-only type `RLMSyncPermission`.");
+}
+
+#pragma mark - System
+
+- (RLMSchema *)schema {
+    if (!_schema) {
+        _schema = [RLMSchema dynamicSchemaFromObjectStoreSchema:_results.get_realm()->schema()];
+    }
+    return _schema;
+}
+
+- (RLMObjectSchema *)objectSchema {
+    if (!_objectSchema) {
+        _objectSchema = [RLMObjectSchema objectSchemaForObjectStoreSchema:_results.get_object_schema()];
+    }
+    return _objectSchema;
+}
+
+- (NSString *)description {
+    return RLMDescriptionWithMaxDepth(@"RLMSyncPermissionResults", self, 1);
+}
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
+                                  objects:(id __unsafe_unretained [])buffer
+                                    count:(NSUInteger)len {
+    // FIXME: It would be nice to have a shared fast enumeration implementation for `realm::Results`-only RLMResults.
+    NSUInteger thisSize = self.count;
+    if (state->state == 0) {
+        state->extra[0] = 0;
+        state->extra[1] = (long)thisSize;
+        state->state = 1;
+    }
+    NSUInteger objectsInBuffer = 0;
+    long idx = state->extra[0];
+    if ((unsigned long)idx == thisSize) {
+        // finished
+        return 0;
+    }
+    state->itemsPtr = buffer;
+    state->mutationsPtr = state->extra + 1;
+    while (true) {
+        if (objectsInBuffer == len) {
+            // Buffer is full.
+            state->extra[0] = idx;
+            return objectsInBuffer;
+        }
+        if ((unsigned long)idx == thisSize) {
+            // finished
+            state->extra[0] = idx;
+            return objectsInBuffer;
+        }
+        // Otherwise, add an object and advance the index pointer.
+        RLMSyncPermission * __autoreleasing thisPermission = [self objectAtIndex:idx];
+        buffer[objectsInBuffer] = thisPermission;
+        idx++;
+        objectsInBuffer++;
+    }
+}
+
+@end