Convert RLMRealmConfiguration to a wrapper around Realm::Config

This commit is contained in:
Thomas Goyne 2015-08-25 16:39:32 -07:00
parent 563a8374d0
commit 55e6cca243
2 changed files with 54 additions and 35 deletions

View File

@ -22,47 +22,57 @@
#include <realm/group_shared.hpp> #include <realm/group_shared.hpp>
#include <realm/lang_bind_helper.hpp> #include <realm/lang_bind_helper.hpp>
#include <memory>
#include <mutex> #include <mutex>
using namespace realm; using namespace realm;
RealmCache Realm::s_global_cache; RealmCache Realm::s_global_cache;
Realm::Config::Config(const Config& c) : path(c.path), read_only(c.read_only), in_memory(c.in_memory), cache(c.cache), schema_version(c.schema_version), migration_function(c.migration_function) Realm::Config::Config(const Config& c)
: path(c.path)
, read_only(c.read_only)
, in_memory(c.in_memory)
, cache(c.cache)
, encryption_key(c.encryption_key)
, schema_version(c.schema_version)
, migration_function(c.migration_function)
{ {
if (c.schema) { if (c.schema) {
schema = std::make_unique<Schema>(*c.schema); schema = std::make_unique<Schema>(*c.schema);
} }
if (c.encryption_key) {
encryption_key = std::make_unique<char[]>(64);
memcpy(encryption_key.get(), c.encryption_key.get(), 64);
}
} }
Realm::Realm(Config &config) : m_config(config) Realm::Config& Realm::Config::operator=(realm::Realm::Config const& c)
{
if (&c != this) {
*this = Config(c);
}
return *this;
}
Realm::Realm(Config config) : m_config(std::move(config))
{ {
try { try {
if (config.read_only) { if (m_config.read_only) {
m_read_only_group = std::make_unique<Group>(config.path, config.encryption_key.get(), Group::mode_ReadOnly); m_read_only_group = std::make_unique<Group>(m_config.path, m_config.encryption_key.data(), Group::mode_ReadOnly);
m_group = m_read_only_group.get(); m_group = m_read_only_group.get();
} }
else { else {
m_history = realm::make_client_history(config.path, config.encryption_key.get()); m_history = realm::make_client_history(m_config.path, m_config.encryption_key.data());
SharedGroup::DurabilityLevel durability = config.in_memory ? SharedGroup::durability_MemOnly : SharedGroup::DurabilityLevel durability = m_config.in_memory ? SharedGroup::durability_MemOnly :
SharedGroup::durability_Full; SharedGroup::durability_Full;
m_shared_group = std::make_unique<SharedGroup>(*m_history, durability, config.encryption_key.get()); m_shared_group = std::make_unique<SharedGroup>(*m_history, durability, m_config.encryption_key.data());
} }
} }
catch (util::File::PermissionDenied const& ex) { catch (util::File::PermissionDenied const& ex) {
throw RealmFileException(RealmFileException::Kind::PermissionDenied, "Unable to open a realm at path '" + config.path + throw RealmFileException(RealmFileException::Kind::PermissionDenied, "Unable to open a realm at path '" + m_config.path +
"'. Please use a path where your app has " + (config.read_only ? "read" : "read-write") + " permissions."); "'. Please use a path where your app has " + (m_config.read_only ? "read" : "read-write") + " permissions.");
} }
catch (util::File::Exists const& ex) { catch (util::File::Exists const& ex) {
throw RealmFileException(RealmFileException::Kind::Exists, "Unable to open a realm at path '" + config.path + "'"); throw RealmFileException(RealmFileException::Kind::Exists, "Unable to open a realm at path '" + m_config.path + "'");
} }
catch (util::File::AccessError const& ex) { catch (util::File::AccessError const& ex) {
throw RealmFileException(RealmFileException::Kind::AccessError, "Unable to open a realm at path '" + config.path + "'"); throw RealmFileException(RealmFileException::Kind::AccessError, "Unable to open a realm at path '" + m_config.path + "'");
} }
catch (IncompatibleLockFile const&) { catch (IncompatibleLockFile const&) {
throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, "Realm file is currently open in another process " throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, "Realm file is currently open in another process "
@ -78,7 +88,7 @@ Group *Realm::read_group()
return m_group; return m_group;
} }
SharedRealm Realm::get_shared_realm(Config &config) SharedRealm Realm::get_shared_realm(Config config)
{ {
SharedRealm realm = s_global_cache.get_realm(config.path); SharedRealm realm = s_global_cache.get_realm(config.path);
if (realm) { if (realm) {
@ -104,7 +114,7 @@ SharedRealm Realm::get_shared_realm(Config &config)
return realm; return realm;
} }
realm = SharedRealm(new Realm(config)); realm = SharedRealm(new Realm(std::move(config)));
// we want to ensure we are only initializing a single realm at a time // we want to ensure we are only initializing a single realm at a time
static std::mutex s_init_mutex; static std::mutex s_init_mutex;
@ -153,11 +163,15 @@ bool Realm::update_schema(Schema &schema, uint64_t version)
if (!m_config.read_only && ObjectStore::realm_requires_update(read_group(), version, schema)) { if (!m_config.read_only && ObjectStore::realm_requires_update(read_group(), version, schema)) {
// keep old copy to pass to migration function // keep old copy to pass to migration function
old_config.read_only = true; old_config.read_only = true;
SharedRealm old_realm = SharedRealm(new Realm(old_config)), updated_realm = shared_from_this(); old_config.schema_version = ObjectStore::get_schema_version(read_group());
old_config.schema = std::make_unique<Schema>(ObjectStore::schema_from_group(read_group()));
SharedRealm old_realm(new Realm(old_config));
auto updated_realm = shared_from_this();
// update and migrate // update and migrate
begin_transaction(); begin_transaction();
changed = ObjectStore::update_realm_with_schema(read_group(), version, *m_config.schema, [=](__unused Group *group, __unused Schema &target_schema) { changed = ObjectStore::update_realm_with_schema(read_group(), version, *m_config.schema,
[=](__unused Group *group, __unused Schema &target_schema) {
m_config.migration_function(old_realm, updated_realm); m_config.migration_function(old_realm, updated_realm);
}); });
commit_transaction(); commit_transaction();

View File

@ -19,11 +19,11 @@
#ifndef REALM_REALM_HPP #ifndef REALM_REALM_HPP
#define REALM_REALM_HPP #define REALM_REALM_HPP
#include <map>
#include <memory> #include <memory>
#include <set>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <set>
#include <map>
#include "object_store.hpp" #include "object_store.hpp"
@ -45,7 +45,7 @@ namespace realm {
bool read_only = false; bool read_only = false;
bool in_memory = false; bool in_memory = false;
bool cache = true; bool cache = true;
std::unique_ptr<char[]> encryption_key; std::vector<char> encryption_key;
std::unique_ptr<Schema> schema; std::unique_ptr<Schema> schema;
uint64_t schema_version = ObjectStore::NotVersioned; uint64_t schema_version = ObjectStore::NotVersioned;
@ -55,18 +55,23 @@ namespace realm {
Config() = default; Config() = default;
Config(Config&&) = default; Config(Config&&) = default;
Config(const Config& c); Config(const Config& c);
Config& operator=(Config const&);
Config& operator=(Config&&) = default;
}; };
// Get a cached Realm or create a new one if no cached copies exists // Get a cached Realm or create a new one if no cached copies exists
// Caching is done by path - mismatches for inMemory and readOnly Config properties // Caching is done by path - mismatches for in_memory and read_only
// will raise an exception // Config properties will raise an exception
// If schema/schema_version is specified, update_schema is called automatically on the realm // If schema/schema_version is specified, update_schema is called
// and a migration is performed. If not specified, the schema version and schema are dynamically // automatically on the realm and a migration is performed. If not
// read from the the existing Realm. // specified, the schema version and schema are dynamically read from
static SharedRealm get_shared_realm(Config &config); // the the existing Realm.
static SharedRealm get_shared_realm(Config config);
// Updates a Realm to a given target schema/version creating tables and updating indexes as necessary // Updates a Realm to a given target schema/version creating tables and
// Uses the existing migration function on the Config, and the resulting Schema and version with updated // updating indexes as necessary. Uses the existing migration function
// on the Config, and the resulting Schema and version with updated
// column mappings are set on the realms config upon success. // column mappings are set on the realms config upon success.
// returns if any changes were made // returns if any changes were made
bool update_schema(Schema &schema, uint64_t version); bool update_schema(Schema &schema, uint64_t version);
@ -98,7 +103,7 @@ namespace realm {
const std::string DidChangeNotification = "DidChangeNotification"; const std::string DidChangeNotification = "DidChangeNotification";
private: private:
Realm(Config &config); Realm(Config config);
Config m_config; Config m_config;
std::thread::id m_thread_id = std::this_thread::get_id(); std::thread::id m_thread_id = std::this_thread::get_id();