diff --git a/CHANGELOG.md b/CHANGELOG.md index b0a5ca74..a45cdd11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +NEXT_RELEASE Release notes (YYYY-MM-DD) +============================================================= + +### Fixed +* None + +### Enhancements +* Add `realm::db_config::enable_forced_sync_history()` which allows you to open a synced Realm + even if a sync configuration is not supplied. + +### Compatibility +* Fileformat: Generates files with format v24. Reads and automatically upgrade from fileformat v10. + +### Internals +* None + 2.2.0 Release notes (2024-07-22) ============================================================= diff --git a/include/cpprealm/internal/bridge/realm.hpp b/include/cpprealm/internal/bridge/realm.hpp index 38703d1e..c7220b12 100644 --- a/include/cpprealm/internal/bridge/realm.hpp +++ b/include/cpprealm/internal/bridge/realm.hpp @@ -199,6 +199,10 @@ namespace realm::internal::bridge { void set_schema_version(uint64_t version); void set_encryption_key(const std::array&); void should_compact_on_launch(std::function&& fn); + /// Open the Realm using the sync history mode even if a sync configuration is not supplied. + /// This mode is used for opening a synced realm with a local realm config in the scenario + /// that you do not have a valid sync user object. + void enable_forced_sync_history(); std::optional get_schema(); template diff --git a/include/cpprealm/networking/websocket.hpp b/include/cpprealm/networking/websocket.hpp index 1e4ea988..5b0c232c 100644 --- a/include/cpprealm/networking/websocket.hpp +++ b/include/cpprealm/networking/websocket.hpp @@ -305,7 +305,7 @@ namespace realm::networking { configuration m_configuration; private: void initialize(); - std::unique_ptr<::realm::sync::SyncSocketProvider> m_provider; + std::shared_ptr<::realm::sync::SyncSocketProvider> m_provider; }; } diff --git a/src/cpprealm/internal/bridge/realm.cpp b/src/cpprealm/internal/bridge/realm.cpp index 845b4985..f6d39d08 100644 --- a/src/cpprealm/internal/bridge/realm.cpp +++ b/src/cpprealm/internal/bridge/realm.cpp @@ -309,6 +309,10 @@ namespace realm::internal::bridge { get_config()->should_compact_on_launch_function = std::move(fn); } + void realm::config::enable_forced_sync_history() { + get_config()->force_sync_history = true; + } + enum ::realm::client_reset_mode realm::config::get_client_reset_mode() const { return static_cast(get_config()->sync_config->client_resync_mode); } diff --git a/src/cpprealm/networking/websocket.cpp b/src/cpprealm/networking/websocket.cpp index 76851891..5686c6c5 100644 --- a/src/cpprealm/networking/websocket.cpp +++ b/src/cpprealm/networking/websocket.cpp @@ -65,7 +65,7 @@ namespace realm::networking { auto user_agent_binding_info = std::string("RealmCpp/") + std::string(REALMCXX_VERSION_STRING); auto user_agent = util::format("RealmSync/%1 (%2) %3", REALM_VERSION_STRING, util::get_platform_info(), user_agent_binding_info); - m_provider = std::make_unique<::realm::sync::websocket::DefaultSocketProvider>(util::Logger::get_default_logger(), user_agent); + m_provider = std::make_shared<::realm::sync::websocket::DefaultSocketProvider>(util::Logger::get_default_logger(), user_agent); } std::unique_ptr default_socket_provider::connect(std::unique_ptr o, websocket_endpoint&& ep) { diff --git a/tests/sync/flexible_sync_tests.cpp b/tests/sync/flexible_sync_tests.cpp index 9f7c5cb6..f1142527 100644 --- a/tests/sync/flexible_sync_tests.cpp +++ b/tests/sync/flexible_sync_tests.cpp @@ -102,6 +102,86 @@ TEST_CASE("flexible_sync", "[sync]") { auto flx_sync_config2 = user.flexible_sync_configuration(); REQUIRE_THROWS(db(flx_sync_config2)); } + + SECTION("open synced realm without sync config") { + auto user = app.login(realm::App::credentials::anonymous()).get(); + std::string realm_path = user.flexible_sync_configuration().path(); + + { + auto flx_sync_config = user.flexible_sync_configuration(); + auto synced_realm = db(flx_sync_config); + auto update_success = synced_realm.subscriptions().update([](realm::mutable_sync_subscription_set &subs) { + subs.clear(); + }).get(); + CHECK(update_success == true); + CHECK(synced_realm.subscriptions().size() == 0); + + update_success = synced_realm.subscriptions().update([](realm::mutable_sync_subscription_set &subs) { + subs.add("my-sub", [](auto &obj) { + return obj.str_col == "a" && obj._id > 500 && obj._id < 520; + }); + subs.add("foo-link"); + }) + .get(); + CHECK(update_success == true); + CHECK(synced_realm.subscriptions().size() == 2); + synced_realm.get_sync_session()->wait_for_upload_completion().get(); + synced_realm.get_sync_session()->wait_for_download_completion().get(); + + auto objs = synced_realm.objects(); + CHECK(objs.size() == 0); + + synced_realm.write([&synced_realm]() { + AllTypesObject o; + o._id = 501; + o.str_col = "a"; + synced_realm.add(std::move(o)); + }); + + synced_realm.refresh(); + synced_realm.get_sync_session()->wait_for_upload_completion().get(); + synced_realm.get_sync_session()->wait_for_download_completion().get(); + objs = synced_realm.objects(); + CHECK(objs.size() == 1); + } + + { + auto local_config = realm::db_config(); + local_config.set_path(realm_path); + local_config.enable_forced_sync_history(); + auto local_realm = realm::open(local_config); + CHECK(local_realm.objects().size() == 1); + local_realm.write([&local_realm]() { + AllTypesObject o; + o._id = 502; + o.str_col = "a"; + local_realm.add(std::move(o)); + }); + // outside of subscription view, will be reverted once opened + // with a sync config. + local_realm.write([&local_realm]() { + AllTypesObject o; + o._id = 503; + o.str_col = "b"; + local_realm.add(std::move(o)); + }); + CHECK(local_realm.objects().size() == 3); + } + + { + auto flx_sync_config = user.flexible_sync_configuration(); + auto synced_realm = db(flx_sync_config); + CHECK(synced_realm.objects().size() == 3); + auto subs_size = synced_realm.subscriptions().size(); + CHECK(subs_size == 2); + + synced_realm.get_sync_session()->wait_for_upload_completion().get(); + synced_realm.get_sync_session()->wait_for_download_completion().get(); + synced_realm.refresh(); + CHECK(synced_realm.objects().size() == 2); + } + } + } template