added iOS source code
[wl-app.git] / iOS / Pods / Realm / Realm / RLMRealmConfiguration.mm
diff --git a/iOS/Pods/Realm/Realm/RLMRealmConfiguration.mm b/iOS/Pods/Realm/Realm/RLMRealmConfiguration.mm
new file mode 100644 (file)
index 0000000..f0cf4a0
--- /dev/null
@@ -0,0 +1,305 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2015 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 "RLMRealmConfiguration_Private.h"
+
+#import "RLMObjectSchema_Private.hpp"
+#import "RLMRealm_Private.h"
+#import "RLMSchema_Private.hpp"
+#import "RLMUtil.hpp"
+
+#import "schema.hpp"
+#import "shared_realm.hpp"
+#import "sync/sync_config.hpp"
+
+static NSString *const c_RLMRealmConfigurationProperties[] = {
+    @"fileURL",
+    @"inMemoryIdentifier",
+    @"encryptionKey",
+    @"readOnly",
+    @"schemaVersion",
+    @"migrationBlock",
+    @"deleteRealmIfMigrationNeeded",
+    @"shouldCompactOnLaunch",
+    @"dynamic",
+    @"customSchema",
+};
+
+static NSString *const c_defaultRealmFileName = @"default.realm";
+RLMRealmConfiguration *s_defaultConfiguration;
+
+NSString *RLMRealmPathForFileAndBundleIdentifier(NSString *fileName, NSString *bundleIdentifier) {
+    return [RLMDefaultDirectoryForBundleIdentifier(bundleIdentifier)
+            stringByAppendingPathComponent:fileName];
+}
+
+NSString *RLMRealmPathForFile(NSString *fileName) {
+    static NSString *directory = RLMDefaultDirectoryForBundleIdentifier(nil);
+    return [directory stringByAppendingPathComponent:fileName];
+}
+
+@implementation RLMRealmConfiguration {
+    realm::Realm::Config _config;
+}
+
+- (realm::Realm::Config&)config {
+    return _config;
+}
+
++ (instancetype)defaultConfiguration {
+    return [[self rawDefaultConfiguration] copy];
+}
+
++ (void)setDefaultConfiguration:(RLMRealmConfiguration *)configuration {
+    if (!configuration) {
+        @throw RLMException(@"Cannot set the default configuration to nil.");
+    }
+    @synchronized(c_defaultRealmFileName) {
+        s_defaultConfiguration = [configuration copy];
+    }
+}
+
++ (RLMRealmConfiguration *)rawDefaultConfiguration {
+    RLMRealmConfiguration *configuration;
+    @synchronized(c_defaultRealmFileName) {
+        if (!s_defaultConfiguration) {
+            s_defaultConfiguration = [[RLMRealmConfiguration alloc] init];
+        }
+        configuration = s_defaultConfiguration;
+    }
+    return configuration;
+}
+
++ (void)resetRealmConfigurationState {
+    @synchronized(c_defaultRealmFileName) {
+        s_defaultConfiguration = nil;
+    }
+}
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        static NSURL *defaultRealmURL = [NSURL fileURLWithPath:RLMRealmPathForFile(c_defaultRealmFileName)];
+        self.fileURL = defaultRealmURL;
+        self.schemaVersion = 0;
+        self.cache = YES;
+
+        // We have our own caching of RLMRealm instances, so the ObjectStore
+        // cache is at best pointless, and may result in broken behavior when
+        // a realm::Realm instance outlives the RLMRealm (due to collection
+        // notifiers being in the middle of running when the RLMRealm is
+        // dealloced) and then reused for a new RLMRealm
+        _config.cache = false;
+    }
+
+    return self;
+}
+
+- (instancetype)copyWithZone:(NSZone *)zone {
+    RLMRealmConfiguration *configuration = [[[self class] allocWithZone:zone] init];
+    configuration->_config = _config;
+    configuration->_cache = _cache;
+    configuration->_dynamic = _dynamic;
+    configuration->_migrationBlock = _migrationBlock;
+    configuration->_shouldCompactOnLaunch = _shouldCompactOnLaunch;
+    configuration->_customSchema = _customSchema;
+    return configuration;
+}
+
+- (NSString *)description {
+    NSMutableString *string = [NSMutableString stringWithFormat:@"%@ {\n", self.class];
+    for (NSString *key : c_RLMRealmConfigurationProperties) {
+        NSString *description = [[self valueForKey:key] description];
+        description = [description stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"];
+
+        [string appendFormat:@"\t%@ = %@;\n", key, description];
+    }
+    return [string stringByAppendingString:@"}"];
+}
+
+static void RLMNSStringToStdString(std::string &out, NSString *in) {
+    out.resize([in maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
+    if (out.empty()) {
+        return;
+    }
+
+    NSUInteger size = out.size();
+    [in getBytes:&out[0]
+       maxLength:size
+      usedLength:&size
+        encoding:NSUTF8StringEncoding
+         options:0 range:{0, in.length} remainingRange:nullptr];
+    out.resize(size);
+}
+
+- (NSURL *)fileURL {
+    if (_config.in_memory || _config.sync_config) {
+        return nil;
+    }
+    return [NSURL fileURLWithPath:@(_config.path.c_str())];
+}
+
+- (void)setFileURL:(NSURL *)fileURL {
+    NSString *path = fileURL.path;
+    if (path.length == 0) {
+        @throw RLMException(@"Realm path must not be empty");
+    }
+    _config.sync_config = nullptr;
+
+    RLMNSStringToStdString(_config.path, path);
+    _config.in_memory = false;
+}
+
+- (NSString *)inMemoryIdentifier {
+    if (!_config.in_memory) {
+        return nil;
+    }
+    return [@(_config.path.c_str()) lastPathComponent];
+}
+
+- (void)setInMemoryIdentifier:(NSString *)inMemoryIdentifier {
+    if (inMemoryIdentifier.length == 0) {
+        @throw RLMException(@"In-memory identifier must not be empty");
+    }
+    _config.sync_config = nullptr;
+
+    RLMNSStringToStdString(_config.path, [NSTemporaryDirectory() stringByAppendingPathComponent:inMemoryIdentifier]);
+    _config.in_memory = true;
+}
+
+- (NSData *)encryptionKey {
+    return _config.encryption_key.empty() ? nil : [NSData dataWithBytes:_config.encryption_key.data() length:_config.encryption_key.size()];
+}
+
+- (void)setEncryptionKey:(NSData * __nullable)encryptionKey {
+    if (NSData *key = RLMRealmValidatedEncryptionKey(encryptionKey)) {
+        auto bytes = static_cast<const char *>(key.bytes);
+        _config.encryption_key.assign(bytes, bytes + key.length);
+        if (_config.sync_config) {
+            auto& sync_encryption_key = self.config.sync_config->realm_encryption_key;
+            sync_encryption_key = std::array<char, 64>();
+            std::copy_n(_config.encryption_key.begin(), 64, sync_encryption_key->begin());
+        }
+    }
+    else {
+        _config.encryption_key.clear();
+        if (_config.sync_config)
+            _config.sync_config->realm_encryption_key = realm::util::none;
+    }
+}
+
+- (BOOL)readOnly {
+    return _config.immutable();
+}
+
+- (void)setReadOnly:(BOOL)readOnly {
+    if (readOnly) {
+        if (self.deleteRealmIfMigrationNeeded) {
+            @throw RLMException(@"Cannot set `readOnly` when `deleteRealmIfMigrationNeeded` is set.");
+        } else if (self.shouldCompactOnLaunch) {
+            @throw RLMException(@"Cannot set `readOnly` when `shouldCompactOnLaunch` is set.");
+        }
+        _config.schema_mode = realm::SchemaMode::Immutable;
+    }
+    else if (self.readOnly) {
+        _config.schema_mode = realm::SchemaMode::Automatic;
+    }
+}
+
+- (uint64_t)schemaVersion {
+    return _config.schema_version;
+}
+
+- (void)setSchemaVersion:(uint64_t)schemaVersion {
+    if (schemaVersion == RLMNotVersioned) {
+        @throw RLMException(@"Cannot set schema version to %llu (RLMNotVersioned)", RLMNotVersioned);
+    }
+    _config.schema_version = schemaVersion;
+}
+
+- (BOOL)deleteRealmIfMigrationNeeded {
+    return _config.schema_mode == realm::SchemaMode::ResetFile;
+}
+
+- (void)setDeleteRealmIfMigrationNeeded:(BOOL)deleteRealmIfMigrationNeeded {
+    if (deleteRealmIfMigrationNeeded) {
+        if (self.readOnly) {
+            @throw RLMException(@"Cannot set `deleteRealmIfMigrationNeeded` when `readOnly` is set.");
+        }
+        _config.schema_mode = realm::SchemaMode::ResetFile;
+    }
+    else if (self.deleteRealmIfMigrationNeeded) {
+        _config.schema_mode = realm::SchemaMode::Automatic;
+    }
+}
+
+- (NSArray *)objectClasses {
+    return [_customSchema.objectSchema valueForKeyPath:@"objectClass"];
+}
+
+- (void)setObjectClasses:(NSArray *)objectClasses {
+    self.customSchema = [RLMSchema schemaWithObjectClasses:objectClasses];
+}
+
+- (void)setDynamic:(bool)dynamic {
+    _dynamic = dynamic;
+    self.cache = !dynamic;
+}
+
+- (bool)disableFormatUpgrade {
+    return _config.disable_format_upgrade;
+}
+
+- (void)setDisableFormatUpgrade:(bool)disableFormatUpgrade {
+    _config.disable_format_upgrade = disableFormatUpgrade;
+}
+
+- (realm::SchemaMode)schemaMode {
+    return _config.schema_mode;
+}
+
+- (void)setSchemaMode:(realm::SchemaMode)mode {
+    _config.schema_mode = mode;
+}
+
+- (NSString *)pathOnDisk {
+    return @(_config.path.c_str());
+}
+
+- (void)setShouldCompactOnLaunch:(RLMShouldCompactOnLaunchBlock)shouldCompactOnLaunch {
+    if (shouldCompactOnLaunch) {
+        if (self.readOnly) {
+            @throw RLMException(@"Cannot set `shouldCompactOnLaunch` when `readOnly` is set.");
+        } else if (_config.sync_config) {
+            @throw RLMException(@"Cannot set `shouldCompactOnLaunch` when `syncConfiguration` is set.");
+        }
+        _config.should_compact_on_launch_function = [=](size_t totalBytes, size_t usedBytes) {
+            return shouldCompactOnLaunch(totalBytes, usedBytes);
+        };
+    }
+    else {
+        _config.should_compact_on_launch_function = nullptr;
+    }
+    _shouldCompactOnLaunch = shouldCompactOnLaunch;
+}
+
+- (void)setCustomSchemaWithoutCopying:(RLMSchema *)schema {
+    _customSchema = schema;
+}
+
+@end