From 183f051bb1439484f7584703973522d1ee1a0cfd Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Mon, 18 Sep 2017 17:44:17 +0200 Subject: [PATCH] v1 -> v2 upgrade path --- CHANGELOG.md | 2 +- src/js_realm.hpp | 32 ++++++++++++++++++++++++++++++-- src/js_types.hpp | 25 +++++++++++++++++++++++++ src/object-store | 2 +- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90e10f62..543e5e6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * Updating core, sync, object store. ### Enhancements -* None +* Throw exception with recovery configuration for V1 to V2 upgrade. ### Bug fixes * None diff --git a/src/js_realm.hpp b/src/js_realm.hpp index 5f22c677..df58a3ac 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -253,6 +253,21 @@ public: }; private: + static void translateSharedGroupOpenException(ContextType ctx, realm::Realm::Config& originalConfiguration) { + try { + throw; + } + catch (RealmFileException const& ex) { + switch (ex.kind()) { + case RealmFileException::Kind::IncompatibleSyncedRealm: { + throw IncompatibleSyncedRealmException(ctx, ex.path(), originalConfiguration.encryption_key); + default: + throw; + } + } + } + } + static std::string validated_notification_name(ContextType ctx, const ValueType &value) { std::string name = Value::validated_to_string(ctx, value, "notification name"); if (name != "change") { @@ -483,7 +498,13 @@ SharedRealm RealmClass::create_shared_realm(ContextType ctx, realm::Realm::Co ObjectDefaultsMap && defaults, ConstructorMap && constructors) { config.execution_context = Context::get_execution_context_id(ctx); - SharedRealm realm = realm::Realm::get_shared_realm(config); + SharedRealm realm; + try { + realm = realm::Realm::get_shared_realm(config); + } + catch (...) { + translateSharedGroupOpenException(ctx, config); + } GlobalContextType global_context = Context::get_global_context(ctx); if (!realm->m_binding_context) { @@ -693,7 +714,14 @@ void RealmClass::wait_for_download_completion(ContextType ctx, FunctionType, std::function progressFunc; - auto realm = realm::Realm::get_shared_realm(config); + SharedRealm realm; + try { + realm = realm::Realm::get_shared_realm(config); + } + catch (...) { + translateSharedGroupOpenException(ctx, config); + } + if (auto sync_config = config.sync_config) { static const String progressFuncName = "_onDownloadProgress"; diff --git a/src/js_types.hpp b/src/js_types.hpp index e1cf6459..4ce626c6 100644 --- a/src/js_types.hpp +++ b/src/js_types.hpp @@ -318,6 +318,31 @@ struct Exception : public std::runtime_error { } }; +template +struct IncompatibleSyncedRealmException : public std::runtime_error { + using ContextType = typename T::Context; + using ObjectType = typename T::Object; + + std::string m_path; + std::vector m_encryption_key; + + IncompatibleSyncedRealmException(ContextType ctx, const std::string &path) + : std::runtime_error(std::string("Incompatible Synced Realm")), m_path(path) {} + IncompatibleSyncedRealmException(ContextType ctx, const std::string &path, const std::vector &key) + : std::runtime_error(std::string("Incompatible Synced Realm")), m_path(path), m_encryption_key(key) {} + + + ObjectType config(ContextType ctx) { + ObjectType configuration = ObjectType::create_empty(ctx); + ObjectType::set_property(ctx, configuration, "path", m_path); + ObjectType::set_property(ctx, configuration, "schema_mode", to_string(ctx, "readOnly")); + if (!m_encryption_key.empty()) { + ObjectType::set_property(ctx, configuration, "encryption_key", to_binary(ctx, m_encryption_key)); + } + return configuration; + } +}; + template struct ReturnValue { using ValueType = typename T::Value; diff --git a/src/object-store b/src/object-store index d1a101fd..317dc9b3 160000 --- a/src/object-store +++ b/src/object-store @@ -1 +1 @@ -Subproject commit d1a101fda6999e070c1e73cc5aff002c3de7c129 +Subproject commit 317dc9b3d9ef1b5de5ace72e05ac6d58e443bef5