From 49738275312e441b092e5f19a53b538e432d033e Mon Sep 17 00:00:00 2001 From: Kristian Dupont Date: Thu, 29 Oct 2015 10:42:56 +0100 Subject: [PATCH 1/7] Rename RealmDelegate to RealmBindingContext --- ..._delegate.hpp => realm_binding_context.hpp | 20 +++++++++---------- shared_realm.cpp | 20 +++++++++---------- shared_realm.hpp | 4 ++-- 3 files changed, 22 insertions(+), 22 deletions(-) rename realm_delegate.hpp => realm_binding_context.hpp (90%) diff --git a/realm_delegate.hpp b/realm_binding_context.hpp similarity index 90% rename from realm_delegate.hpp rename to realm_binding_context.hpp index 0d9e9dfe..1e82e1e2 100644 --- a/realm_delegate.hpp +++ b/realm_binding_context.hpp @@ -16,8 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -#ifndef REALM_DELEGATE_HPP -#define REALM_DELEGATE_HPP +#ifndef REALM_BINDING_CONTEXT_HPP +#define REALM_BINDING_CONTEXT_HPP #include "index_set.hpp" @@ -25,15 +25,15 @@ #include namespace realm { -// RealmDelegate is the extension point for adding binding-specific behavior to +// RealmBindingContext is the extension point for adding binding-specific behavior to // a SharedRealm. It can be used to store additonal data associated with the // Realm which is needed by the binding, and there are several methods which // can be overridden to receive notifications of state changes within the Realm. // -// A simple delegate implementation which lets the user register functions to be +// A simple implementation which lets the user register functions to be // called on refresh could look like the following: // -// class DelegateImplementation : public RealmDelegate { +// class BindingContextImplementation : public RealmBindingContext { // public: // // A token returned from add_notification that can be used to remove the // // notification later @@ -66,9 +66,9 @@ namespace realm { // private: // std::list> m_registered_notifications; // }; -class RealmDelegate { +class RealmBindingContext { public: - virtual ~RealmDelegate() = default; + virtual ~RealmBindingContext() = default; // Called by the Realm when a write transaction is committed to the file by // a different Realm instance (possibly in a different process) @@ -147,8 +147,8 @@ public: }; }; -inline void RealmDelegate::will_change(std::vector const&, std::vector const&) { } -inline void RealmDelegate::did_change(std::vector const&, std::vector const&) { } +inline void RealmBindingContext::will_change(std::vector const&, std::vector const&) { } +inline void RealmBindingContext::did_change(std::vector const&, std::vector const&) { } } // namespace realm -#endif /* REALM_DELEGATE_HPP */ +#endif /* REALM_BINDING_CONTEXT_HPP */ diff --git a/shared_realm.cpp b/shared_realm.cpp index 2ca84649..5eeb57da 100644 --- a/shared_realm.cpp +++ b/shared_realm.cpp @@ -19,7 +19,7 @@ #include "shared_realm.hpp" #include "external_commit_helper.hpp" -#include "realm_delegate.hpp" +#include "realm_binding_context.hpp" #include "schema.hpp" #include "transact_log_handler.hpp" @@ -247,7 +247,7 @@ void Realm::begin_transaction() // make sure we have a read transaction read_group(); - transaction::begin(*m_shared_group, *m_history, m_delegate.get()); + transaction::begin(*m_shared_group, *m_history, m_binding_context.get()); m_in_transaction = true; } @@ -261,7 +261,7 @@ void Realm::commit_transaction() } m_in_transaction = false; - transaction::commit(*m_shared_group, *m_history, m_delegate.get()); + transaction::commit(*m_shared_group, *m_history, m_binding_context.get()); m_notifier->notify_others(); } @@ -275,7 +275,7 @@ void Realm::cancel_transaction() } m_in_transaction = false; - transaction::cancel(*m_shared_group, *m_history, m_delegate.get()); + transaction::cancel(*m_shared_group, *m_history, m_binding_context.get()); } void Realm::invalidate() @@ -320,15 +320,15 @@ void Realm::notify() verify_thread(); if (m_shared_group->has_changed()) { // Throws - if (m_delegate) { - m_delegate->changes_available(); + if (m_binding_context) { + m_binding_context->changes_available(); } if (m_auto_refresh) { if (m_group) { - transaction::advance(*m_shared_group, *m_history, m_delegate.get()); + transaction::advance(*m_shared_group, *m_history, m_binding_context.get()); } - else if (m_delegate) { - m_delegate->did_change({}, {}); + else if (m_binding_context) { + m_binding_context->did_change({}, {}); } } } @@ -351,7 +351,7 @@ bool Realm::refresh() } if (m_group) { - transaction::advance(*m_shared_group, *m_history, m_delegate.get()); + transaction::advance(*m_shared_group, *m_history, m_binding_context.get()); } else { // Create the read transaction diff --git a/shared_realm.hpp b/shared_realm.hpp index dc5c4b92..bc078fba 100644 --- a/shared_realm.hpp +++ b/shared_realm.hpp @@ -30,7 +30,7 @@ namespace realm { class ClientHistory; class Realm; class RealmCache; - class RealmDelegate; + class RealmBindingContext; typedef std::shared_ptr SharedRealm; typedef std::weak_ptr WeakRealm; @@ -120,7 +120,7 @@ namespace realm { std::shared_ptr<_impl::ExternalCommitHelper> m_notifier; public: - std::unique_ptr m_delegate; + std::unique_ptr m_binding_context; // FIXME private Group *read_group(); From 70e1967782c78ce6a936d13f063fe77437659a98 Mon Sep 17 00:00:00 2001 From: Kristian Dupont Date: Thu, 29 Oct 2015 13:16:36 +0100 Subject: [PATCH 2/7] Rename realm delegate in transact_log_handler as well --- impl/transact_log_handler.cpp | 40 +++++++++++++++++------------------ impl/transact_log_handler.hpp | 10 ++++----- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/impl/transact_log_handler.cpp b/impl/transact_log_handler.cpp index e1b95405..685dbd38 100644 --- a/impl/transact_log_handler.cpp +++ b/impl/transact_log_handler.cpp @@ -18,7 +18,7 @@ #include "transact_log_handler.hpp" -#include "realm_delegate.hpp" +#include "../realm_binding_context.hpp" #include #include @@ -28,15 +28,15 @@ using namespace realm; namespace { class TransactLogHandler { - using ColumnInfo = RealmDelegate::ColumnInfo; - using ObserverState = RealmDelegate::ObserverState; + using ColumnInfo = RealmBindingContext::ColumnInfo; + using ObserverState = RealmBindingContext::ObserverState; // Observed table rows which need change information std::vector m_observers; // Userdata pointers for rows which have been deleted std::vector invalidated; // Delegate to send change information to - RealmDelegate* m_delegate; + RealmBindingContext* m_binding_context; // Index of currently selected table size_t m_current_table = 0; @@ -84,33 +84,33 @@ class TransactLogHandler { public: template - TransactLogHandler(RealmDelegate* delegate, SharedGroup& sg, Func&& func) - : m_delegate(delegate) + TransactLogHandler(RealmBindingContext* binding_context, SharedGroup& sg, Func&& func) + : m_binding_context(binding_context) { - if (!delegate) { + if (!binding_context) { func(); return; } - m_observers = delegate->get_observed_rows(); + m_observers = binding_context->get_observed_rows(); if (m_observers.empty()) { auto old_version = sg.get_version_of_current_transaction(); func(); if (old_version != sg.get_version_of_current_transaction()) { - delegate->did_change({}, {}); + binding_context->did_change({}, {}); } return; } func(*this); - delegate->did_change(m_observers, invalidated); + binding_context->did_change(m_observers, invalidated); } // Called at the end of the transaction log immediately before the version // is advanced void parse_complete() { - m_delegate->will_change(m_observers, invalidated); + m_binding_context->will_change(m_observers, invalidated); } // These would require having an observer before schema init @@ -318,28 +318,28 @@ public: namespace realm { namespace _impl { namespace transaction { -void advance(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate) { - TransactLogHandler(delegate, sg, [&](auto&&... args) { +void advance(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context) { + TransactLogHandler(binding_context, sg, [&](auto&&... args) { LangBindHelper::advance_read(sg, history, std::move(args)...); }); } -void begin(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate) { - TransactLogHandler(delegate, sg, [&](auto&&... args) { +void begin(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context) { + TransactLogHandler(binding_context, sg, [&](auto&&... args) { LangBindHelper::promote_to_write(sg, history, std::move(args)...); }); } -void commit(SharedGroup& sg, ClientHistory&, RealmDelegate* delegate) { +void commit(SharedGroup& sg, ClientHistory&, RealmBindingContext* binding_context) { LangBindHelper::commit_and_continue_as_read(sg); - if (delegate) { - delegate->did_change({}, {}); + if (binding_context) { + binding_context->did_change({}, {}); } } -void cancel(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate) { - TransactLogHandler(delegate, sg, [&](auto&&... args) { +void cancel(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context) { + TransactLogHandler(binding_context, sg, [&](auto&&... args) { LangBindHelper::rollback_and_continue_as_read(sg, history, std::move(args)...); }); } diff --git a/impl/transact_log_handler.hpp b/impl/transact_log_handler.hpp index dbb54a53..321a67c9 100644 --- a/impl/transact_log_handler.hpp +++ b/impl/transact_log_handler.hpp @@ -20,7 +20,7 @@ #define REALM_TRANSACT_LOG_HANDLER_HPP namespace realm { -class RealmDelegate; +class RealmBindingContext; class SharedGroup; class ClientHistory; @@ -28,19 +28,19 @@ namespace _impl { namespace transaction { // Advance the read transaction version, with change notifications sent to delegate // Must not be called from within a write transaction. -void advance(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate); +void advance(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context); // Begin a write transaction // If the read transaction version is not up to date, will first advance to the // most recent read transaction and sent notifications to delegate -void begin(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate); +void begin(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context); // Commit a write transaction -void commit(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate); +void commit(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context); // Cancel a write transaction and roll back all changes, with change notifications // for reverting to the old values sent to delegate -void cancel(SharedGroup& sg, ClientHistory& history, RealmDelegate* delegate); +void cancel(SharedGroup& sg, ClientHistory& history, RealmBindingContext* binding_context); } // namespace transaction } // namespace _impl } // namespace realm From db36ca5b9c551aa396130bea5f183ef53af82222 Mon Sep 17 00:00:00 2001 From: Kristian Dupont Date: Tue, 3 Nov 2015 08:37:54 +0100 Subject: [PATCH 3/7] Remove Realm suffix --- ..._binding_context.hpp => binding_context.hpp | 18 +++++++++--------- shared_realm.cpp | 2 +- shared_realm.hpp | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) rename realm_binding_context.hpp => binding_context.hpp (91%) diff --git a/realm_binding_context.hpp b/binding_context.hpp similarity index 91% rename from realm_binding_context.hpp rename to binding_context.hpp index 1e82e1e2..4aa6dd94 100644 --- a/realm_binding_context.hpp +++ b/binding_context.hpp @@ -16,8 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -#ifndef REALM_BINDING_CONTEXT_HPP -#define REALM_BINDING_CONTEXT_HPP +#ifndef BINDING_CONTEXT_HPP +#define BINDING_CONTEXT_HPP #include "index_set.hpp" @@ -25,7 +25,7 @@ #include namespace realm { -// RealmBindingContext is the extension point for adding binding-specific behavior to +// BindingContext is the extension point for adding binding-specific behavior to // a SharedRealm. It can be used to store additonal data associated with the // Realm which is needed by the binding, and there are several methods which // can be overridden to receive notifications of state changes within the Realm. @@ -33,7 +33,7 @@ namespace realm { // A simple implementation which lets the user register functions to be // called on refresh could look like the following: // -// class BindingContextImplementation : public RealmBindingContext { +// class BindingContextImplementation : public BindingContext { // public: // // A token returned from add_notification that can be used to remove the // // notification later @@ -66,9 +66,9 @@ namespace realm { // private: // std::list> m_registered_notifications; // }; -class RealmBindingContext { +class BindingContext { public: - virtual ~RealmBindingContext() = default; + virtual ~BindingContext() = default; // Called by the Realm when a write transaction is committed to the file by // a different Realm instance (possibly in a different process) @@ -147,8 +147,8 @@ public: }; }; -inline void RealmBindingContext::will_change(std::vector const&, std::vector const&) { } -inline void RealmBindingContext::did_change(std::vector const&, std::vector const&) { } +inline void BindingContext::will_change(std::vector const&, std::vector const&) { } +inline void BindingContext::did_change(std::vector const&, std::vector const&) { } } // namespace realm -#endif /* REALM_BINDING_CONTEXT_HPP */ +#endif /* BINDING_CONTEXT_HPP */ diff --git a/shared_realm.cpp b/shared_realm.cpp index 5eeb57da..861b9d6d 100644 --- a/shared_realm.cpp +++ b/shared_realm.cpp @@ -19,7 +19,7 @@ #include "shared_realm.hpp" #include "external_commit_helper.hpp" -#include "realm_binding_context.hpp" +#include "binding_context.hpp" #include "schema.hpp" #include "transact_log_handler.hpp" diff --git a/shared_realm.hpp b/shared_realm.hpp index bc078fba..7aedb3c5 100644 --- a/shared_realm.hpp +++ b/shared_realm.hpp @@ -30,7 +30,7 @@ namespace realm { class ClientHistory; class Realm; class RealmCache; - class RealmBindingContext; + class BindingContext; typedef std::shared_ptr SharedRealm; typedef std::weak_ptr WeakRealm; @@ -120,7 +120,7 @@ namespace realm { std::shared_ptr<_impl::ExternalCommitHelper> m_notifier; public: - std::unique_ptr m_binding_context; + std::unique_ptr m_binding_context; // FIXME private Group *read_group(); From 52e7e6168b5bd8dfcce1a9162b289e8869e1daaa Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 4 Nov 2015 15:24:29 -0800 Subject: [PATCH 4/7] Update for core 0.94.4 --- impl/transact_log_handler.cpp | 13 ++++++++++--- object_schema.hpp | 2 +- object_store.cpp | 4 ---- schema.cpp | 4 ---- schema.hpp | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/impl/transact_log_handler.cpp b/impl/transact_log_handler.cpp index 685dbd38..fba97129 100644 --- a/impl/transact_log_handler.cpp +++ b/impl/transact_log_handler.cpp @@ -175,7 +175,7 @@ public: return true; } - bool select_link_list(size_t col, size_t row) + bool select_link_list(size_t col, size_t row, size_t) { m_active_linklist = nullptr; for (auto& o : m_observers) { @@ -303,15 +303,22 @@ public: bool set_date_time(size_t col, size_t row, DateTime) { return mark_dirty(row, col); } bool set_table(size_t col, size_t row) { return mark_dirty(row, col); } bool set_mixed(size_t col, size_t row, const Mixed&) { return mark_dirty(row, col); } - bool set_link(size_t col, size_t row, size_t) { return mark_dirty(row, col); } + bool set_link(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); } bool set_null(size_t col, size_t row) { return mark_dirty(row, col); } - bool nullify_link(size_t col, size_t row) { return mark_dirty(row, col); } + bool nullify_link(size_t col, size_t row, size_t) { return mark_dirty(row, col); } // Doesn't change any data bool optimize_table() { return true; } // Used for subtables, which we currently don't support bool select_descriptor(int, const size_t*) { return false; } + + // Not implemented + bool insert_substring(size_t, size_t, size_t, StringData) { return false; } + bool erase_substring(size_t, size_t, size_t, size_t) { return false; } + bool swap_rows(size_t, size_t) { return false; } + bool move_column(size_t, size_t) { return false; } + bool move_group_level_table(size_t, size_t) { return false; } }; } // anonymous namespace diff --git a/object_schema.hpp b/object_schema.hpp index aca4af31..4ede6ce5 100644 --- a/object_schema.hpp +++ b/object_schema.hpp @@ -25,8 +25,8 @@ #include namespace realm { - class Property; class Group; + struct Property; class ObjectSchema { public: diff --git a/object_store.cpp b/object_store.cpp index ba7a868b..2cd4a077 100644 --- a/object_store.cpp +++ b/object_store.cpp @@ -550,11 +550,7 @@ InvalidNullabilityException::InvalidNullabilityException(std::string const& obje m_what = "'Object' property '" + property.name + "' must be nullable."; } else { -#if REALM_NULL_STRINGS == 1 m_what = "Array or Mixed property '" + property.name + "' cannot be nullable"; -#else - m_what = "Only 'Object' property types are nullable"; -#endif } } diff --git a/schema.cpp b/schema.cpp index bf7a6181..911dc4e5 100644 --- a/schema.cpp +++ b/schema.cpp @@ -71,11 +71,7 @@ void Schema::validate() const // check nullablity if (prop.is_nullable) { -#if REALM_NULL_STRINGS == 1 if (prop.type == PropertyTypeArray || prop.type == PropertyTypeAny) { -#else - if (prop.type != PropertyTypeObject) { -#endif exceptions.emplace_back(InvalidNullabilityException(object.name, prop)); } } diff --git a/schema.hpp b/schema.hpp index 0a7fa425..4d9c7bed 100644 --- a/schema.hpp +++ b/schema.hpp @@ -52,4 +52,4 @@ public: }; } -#endif /* defined(REALM_SCHEMA_HPP) */ \ No newline at end of file +#endif /* defined(REALM_SCHEMA_HPP) */ From e1e9cd8cd706b78ffdc8118c6b4b2cbde60cb22b Mon Sep 17 00:00:00 2001 From: JP Simard Date: Sun, 13 Sep 2015 15:11:54 +0200 Subject: [PATCH 5/7] Add ObjectStore::is_empty() --- object_store.cpp | 14 +++++++++++++- object_store.hpp | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/object_store.cpp b/object_store.cpp index ba7a868b..d4ef716c 100644 --- a/object_store.cpp +++ b/object_store.cpp @@ -501,7 +501,19 @@ void ObjectStore::delete_data_for_object(Group *group, const StringData &object_ } } - +bool ObjectStore::is_empty(const Group *group) { + for (size_t i = 0; i < group->size(); i++) { + ConstTableRef table = group->get_table(i); + std::string object_type = object_type_for_table_name(table->get_name()); + if (!object_type.length()) { + continue; + } + if (!table->is_empty()) { + return false; + } + } + return true; +} InvalidSchemaVersionException::InvalidSchemaVersionException(uint64_t old_version, uint64_t new_version) : m_old_version(old_version), m_new_version(new_version) diff --git a/object_store.hpp b/object_store.hpp index f38524f8..3da680fb 100644 --- a/object_store.hpp +++ b/object_store.hpp @@ -70,7 +70,10 @@ namespace realm { // deletes the table for the given type static void delete_data_for_object(Group *group, const StringData &object_type); - private: + // indicates if this group contains any objects + static bool is_empty(const Group *group); + + private: // set a new schema version static void set_schema_version(Group *group, uint64_t version); From b93e5cedff7a0dfc562e281806e31998887f2a24 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 3 Nov 2015 17:00:06 -0800 Subject: [PATCH 6/7] Include the path of the file which actually failed to open in exceptions When the user (or our tests...) do dumb things it's sometimes not actually the realm file itself that failed to open. --- shared_realm.cpp | 18 +++++++++++------- shared_realm.hpp | 7 +++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/shared_realm.cpp b/shared_realm.cpp index 861b9d6d..6d57f111 100644 --- a/shared_realm.cpp +++ b/shared_realm.cpp @@ -73,18 +73,22 @@ Realm::Realm(Config config) } } catch (util::File::PermissionDenied const& ex) { - throw RealmFileException(RealmFileException::Kind::PermissionDenied, "Unable to open a realm at path '" + m_config.path + - "'. Please use a path where your app has " + (m_config.read_only ? "read" : "read-write") + " permissions."); + throw RealmFileException(RealmFileException::Kind::PermissionDenied, ex.get_path(), + "Unable to open a realm at path '" + ex.get_path() + + "'. Please use a path where your app has " + (m_config.read_only ? "read" : "read-write") + " permissions."); } catch (util::File::Exists const& ex) { - throw RealmFileException(RealmFileException::Kind::Exists, "Unable to open a realm at path '" + m_config.path + "'"); + throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(), + "File at path '" + ex.get_path() + "' already exists."); } catch (util::File::AccessError const& ex) { - throw RealmFileException(RealmFileException::Kind::AccessError, "Unable to open a realm at path '" + m_config.path + "'"); + throw RealmFileException(RealmFileException::Kind::AccessError, ex.get_path(), + "Unable to open a realm at path '" + ex.get_path() + "'"); } - catch (IncompatibleLockFile const&) { - throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, "Realm file is currently open in another process " - "which cannot share access with this process. All processes sharing a single file must be the same architecture."); + catch (IncompatibleLockFile const& ex) { + throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, m_config.path, + "Realm file is currently open in another process " + "which cannot share access with this process. All processes sharing a single file must be the same architecture."); } } diff --git a/shared_realm.hpp b/shared_realm.hpp index 7aedb3c5..e6c94fc2 100644 --- a/shared_realm.hpp +++ b/shared_realm.hpp @@ -151,7 +151,7 @@ namespace realm { /** Thrown if the user does not have permission to open or create the specified file in the specified access mode when the realm is opened. */ PermissionDenied, - /** Thrown if no_create was specified and the file did already exist when the realm is opened. */ + /** Thrown if create_Always was specified and the file did already exist when the realm is opened. */ Exists, /** Thrown if no_create was specified and the file was not found when the realm is opened. */ NotFound, @@ -160,11 +160,14 @@ namespace realm { architecture mismatch. */ IncompatibleLockFile, }; - RealmFileException(Kind kind, std::string message) : std::runtime_error(message), m_kind(kind) {} + RealmFileException(Kind kind, std::string path, std::string message) : + std::runtime_error(std::move(message)), m_kind(kind), m_path(std::move(path)) {} Kind kind() const { return m_kind; } + const std::string& path() const { return m_path; } private: Kind m_kind; + std::string m_path; }; class MismatchedConfigException : public std::runtime_error From 883ef12c7f377cf2f134a2659349a08500a395a2 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sat, 1 Aug 2015 15:31:45 -0700 Subject: [PATCH 7/7] Add Realm::close() and call it in RealmCache::clear() This is needed for the Swift tests due to that throwing an exception over Swift code unavoidably results in objects being leaked. --- shared_realm.cpp | 23 +++++++++++++++++++++++ shared_realm.hpp | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/shared_realm.cpp b/shared_realm.cpp index 6d57f111..c87dd5d4 100644 --- a/shared_realm.cpp +++ b/shared_realm.cpp @@ -374,6 +374,22 @@ uint64_t Realm::get_schema_version(const realm::Realm::Config &config) return ObjectStore::get_schema_version(Realm(config).read_group()); } +void Realm::close() +{ + invalidate(); + + if (m_notifier) { + m_notifier->remove_realm(this); + } + + m_group = nullptr; + m_shared_group = nullptr; + m_history = nullptr; + m_read_only_group = nullptr; + m_notifier = nullptr; + m_binding_context = nullptr; +} + SharedRealm RealmCache::get_realm(const std::string &path, std::thread::id thread_id) { std::lock_guard lock(m_mutex); @@ -446,6 +462,13 @@ void RealmCache::cache_realm(SharedRealm &realm, std::thread::id thread_id) void RealmCache::clear() { std::lock_guard lock(m_mutex); + for (auto const& path : m_cache) { + for (auto const& thread : path.second) { + if (auto realm = thread.second.lock()) { + realm->close(); + } + } + } m_cache.clear(); } diff --git a/shared_realm.hpp b/shared_realm.hpp index e6c94fc2..81b14bf7 100644 --- a/shared_realm.hpp +++ b/shared_realm.hpp @@ -101,6 +101,10 @@ namespace realm { std::thread::id thread_id() const { return m_thread_id; } void verify_thread() const; + // Close this Realm and remove it from the cache. Continuing to use a + // Realm after closing it will produce undefined behavior. + void close(); + ~Realm(); private: