|
@@ -28,15 +28,15 @@
|
|
|
#include "results.hpp"
|
|
|
#include "schema.hpp"
|
|
|
#include "thread_safe_reference.hpp"
|
|
|
+#include "util/scheduler.hpp"
|
|
|
|
|
|
#include "impl/object_accessor_impl.hpp"
|
|
|
|
|
|
+#include <realm/db.hpp>
|
|
|
#include <realm/history.hpp>
|
|
|
+#include <realm/string_data.hpp>
|
|
|
#include <realm/util/optional.hpp>
|
|
|
|
|
|
-#include <future>
|
|
|
-#include <thread>
|
|
|
-
|
|
|
using namespace realm;
|
|
|
|
|
|
static TableRef get_table(Realm& realm, StringData object_name) {
|
|
@@ -70,7 +70,6 @@ TEST_CASE("thread safe reference") {
|
|
|
};
|
|
|
|
|
|
InMemoryTestFile config;
|
|
|
- config.cache = false;
|
|
|
config.automatic_change_notifications = false;
|
|
|
SharedRealm r = Realm::get_shared_realm(config);
|
|
|
r->update_schema(schema);
|
|
@@ -80,123 +79,111 @@ TEST_CASE("thread safe reference") {
|
|
|
auto foo = create_object(r, "foo object", {{"ignore me", INT64_C(0)}});
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- SECTION("disallowed during write transactions") {
|
|
|
+ const auto int_obj_col = r->schema().find("int object")->persisted_properties[0].column_key;
|
|
|
+
|
|
|
+ SECTION("allowed during write transactions") {
|
|
|
SECTION("obtain") {
|
|
|
r->begin_transaction();
|
|
|
- REQUIRE_THROWS(r->obtain_thread_safe_reference(foo));
|
|
|
+ REQUIRE_NOTHROW(ThreadSafeReference(foo));
|
|
|
}
|
|
|
SECTION("resolve") {
|
|
|
- auto ref = r->obtain_thread_safe_reference(foo);
|
|
|
+ auto ref = ThreadSafeReference(foo);
|
|
|
r->begin_transaction();
|
|
|
- REQUIRE_THROWS(r->resolve_thread_safe_reference(std::move(ref)));
|
|
|
+ REQUIRE_NOTHROW(ref.resolve<Object>(r));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
SECTION("cleanup properly unpins version") {
|
|
|
auto history = make_in_realm_history(config.path);
|
|
|
- SharedGroup shared_group(*history, config.options());
|
|
|
+ auto shared_group = DB::create(*history, config.options());
|
|
|
|
|
|
auto get_current_version = [&]() -> VersionID {
|
|
|
- shared_group.begin_read();
|
|
|
- auto version = shared_group.get_version_of_current_transaction();
|
|
|
- shared_group.end_read();
|
|
|
+ auto rt = shared_group->start_read();
|
|
|
+ auto version = rt->get_version_of_current_transaction();
|
|
|
return version;
|
|
|
};
|
|
|
|
|
|
auto reference_version = get_current_version();
|
|
|
- auto ref = util::make_optional(r->obtain_thread_safe_reference(foo));
|
|
|
+ auto ref = util::make_optional(ThreadSafeReference(foo));
|
|
|
r->begin_transaction(); r->commit_transaction(); // Advance version
|
|
|
|
|
|
REQUIRE(get_current_version() != reference_version); // Ensure advanced
|
|
|
- REQUIRE_NOTHROW(shared_group.begin_read(reference_version)); shared_group.end_read(); // Ensure pinned
|
|
|
- bool did_run_section = false;
|
|
|
+ REQUIRE_NOTHROW(shared_group->start_read(reference_version)); // Ensure pinned
|
|
|
|
|
|
- SECTION("destroyed without being resolved") {
|
|
|
- did_run_section = true;
|
|
|
- ref = {}; // Destroy thread safe reference, unpinning version
|
|
|
- }
|
|
|
- SECTION("exception thrown on resolve") {
|
|
|
- did_run_section = true;
|
|
|
- r->begin_transaction(); // Get into state that'll throw exception on resolve
|
|
|
- REQUIRE_THROWS(r->resolve_thread_safe_reference(std::move(*ref)));
|
|
|
- r->commit_transaction();
|
|
|
- }
|
|
|
- {
|
|
|
- // Clean up old versions by creating a write with dirty data
|
|
|
- r->begin_transaction();
|
|
|
- foo.row().set_int(0, 1);
|
|
|
- r->commit_transaction();
|
|
|
- }
|
|
|
-
|
|
|
- catch2_ensure_section_run_workaround(did_run_section, "cleanup properly unpins version", [&](){
|
|
|
- REQUIRE_THROWS(shared_group.begin_read(reference_version)); // Ensure unpinned
|
|
|
- });
|
|
|
+ ref = {}; // Destroy thread safe reference, unpinning version
|
|
|
+ r->begin_transaction(); r->commit_transaction(); // Clean up old versions
|
|
|
+ REQUIRE_THROWS(shared_group->start_read(reference_version)); // Verify unpinned
|
|
|
}
|
|
|
|
|
|
SECTION("version mismatch") {
|
|
|
-#ifndef _MSC_VER // Visual C++'s buggy <future> needs its template argument to be default constructible so skip this test
|
|
|
SECTION("resolves at older version") {
|
|
|
r->begin_transaction();
|
|
|
- auto num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ Object num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
- auto ref = std::async([config]() -> auto {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object num = Object(r, "int object", 0);
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
+ ColKey col = num.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ ObjKey k = num.obj().get_key();
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- num.row().set_int(0, 9);
|
|
|
- r->commit_transaction();
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
+ ThreadSafeReference ref;
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Object num = Object(r2, "int object", k);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
+
|
|
|
+ r2->begin_transaction();
|
|
|
+ num.obj().set(col, 9);
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
- return r->obtain_thread_safe_reference(num);
|
|
|
- }).get();
|
|
|
+ ref = num;
|
|
|
+ };
|
|
|
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
- Object num_prime = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
- REQUIRE(num_prime.row().get_int(0) == 9);
|
|
|
- REQUIRE(num.row().get_int(0) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
+ Object num_prime = ref.resolve<Object>(r);
|
|
|
+ REQUIRE(num_prime.obj().get<Int>(col) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 9);
|
|
|
|
|
|
r->begin_transaction();
|
|
|
- num.row().set_int(0, 11);
|
|
|
+ num.obj().set(col, 11);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- REQUIRE(num_prime.row().get_int(0) == 11);
|
|
|
- REQUIRE(num.row().get_int(0) == 11);
|
|
|
+ REQUIRE(num_prime.obj().get<Int>(col) == 11);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 11);
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
SECTION("resolve at newer version") {
|
|
|
r->begin_transaction();
|
|
|
- auto num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ Object num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
- auto ref = r->obtain_thread_safe_reference(num);
|
|
|
- std::thread([ref = std::move(ref), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object num = Object(r, "int object", 0);
|
|
|
+ ColKey col = num.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ ObjKey k = num.obj().get_key();
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- num.row().set_int(0, 9);
|
|
|
- r->commit_transaction();
|
|
|
- REQUIRE(num.row().get_int(0) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
+ auto ref = ThreadSafeReference(num);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Object num = Object(r2, "int object", k);
|
|
|
|
|
|
- Object num_prime = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
- REQUIRE(num_prime.row().get_int(0) == 9);
|
|
|
+ r2->begin_transaction();
|
|
|
+ num.obj().set(col, 9);
|
|
|
+ r2->commit_transaction();
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 9);
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- num_prime.row().set_int(0, 11);
|
|
|
- r->commit_transaction();
|
|
|
+ Object num_prime = ref.resolve<Object>(r2);
|
|
|
+ REQUIRE(num_prime.obj().get<Int>(col) == 9);
|
|
|
|
|
|
- REQUIRE(num.row().get_int(0) == 11);
|
|
|
- REQUIRE(num_prime.row().get_int(0) == 11);
|
|
|
- }).join();
|
|
|
+ r2->begin_transaction();
|
|
|
+ num_prime.obj().set(col, 11);
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 11);
|
|
|
+ REQUIRE(num_prime.obj().get<Int>(col) == 11);
|
|
|
+ }
|
|
|
+
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
r->refresh();
|
|
|
- REQUIRE(num.row().get_int(0) == 11);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 11);
|
|
|
}
|
|
|
|
|
|
SECTION("resolve at newer version when schema is specified") {
|
|
@@ -204,76 +191,79 @@ TEST_CASE("thread safe reference") {
|
|
|
config.schema = schema;
|
|
|
SharedRealm r = Realm::get_shared_realm(config);
|
|
|
r->begin_transaction();
|
|
|
- auto num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ Object num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- auto ref = r->obtain_thread_safe_reference(num);
|
|
|
+ ColKey col = num.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ auto ref = ThreadSafeReference(num);
|
|
|
|
|
|
r->begin_transaction();
|
|
|
- num.row().set_int(0, 9);
|
|
|
+ num.obj().set(col, 9);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- REQUIRE_NOTHROW(r->resolve_thread_safe_reference(std::move(ref)));
|
|
|
+ REQUIRE_NOTHROW(ref.resolve<Object>(r));
|
|
|
}
|
|
|
|
|
|
SECTION("resolve references at multiple versions") {
|
|
|
auto commit_new_num = [&](int64_t value) -> Object {
|
|
|
r->begin_transaction();
|
|
|
- auto num = create_object(r, "int object", {{"value", value}});
|
|
|
+ Object num = create_object(r, "int object", {{"value", value}});
|
|
|
r->commit_transaction();
|
|
|
return num;
|
|
|
};
|
|
|
|
|
|
- auto ref1 = r->obtain_thread_safe_reference(commit_new_num(1));
|
|
|
- auto ref2 = r->obtain_thread_safe_reference(commit_new_num(2));
|
|
|
- std::thread([ref1 = std::move(ref1), ref2 = std::move(ref2), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object num1 = r->resolve_thread_safe_reference(std::move(ref1));
|
|
|
- Object num2 = r->resolve_thread_safe_reference(std::move(ref2));
|
|
|
+ auto ref1 = ThreadSafeReference(commit_new_num(1));
|
|
|
+ auto ref2 = ThreadSafeReference(commit_new_num(2));
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Object num1 = ref1.resolve<Object>(r2);
|
|
|
+ Object num2 = ref2.resolve<Object>(r2);
|
|
|
|
|
|
- REQUIRE(num1.row().get_int(0) == 1);
|
|
|
- REQUIRE(num2.row().get_int(0) == 2);
|
|
|
- }).join();
|
|
|
+ ColKey col = num1.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ REQUIRE(num1.obj().get<Int>(col) == 1);
|
|
|
+ REQUIRE(num2.obj().get<Int>(col) == 2);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
SECTION("same thread") {
|
|
|
r->begin_transaction();
|
|
|
- auto num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ Object num = create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
- auto ref = r->obtain_thread_safe_reference(num);
|
|
|
+ ColKey col = num.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
+ auto ref = ThreadSafeReference(num);
|
|
|
bool did_run_section = false;
|
|
|
|
|
|
SECTION("same realm") {
|
|
|
did_run_section = true;
|
|
|
{
|
|
|
- Object num = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
+ Object num = ref.resolve<Object>(r);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
r->begin_transaction();
|
|
|
- num.row().set_int(0, 9);
|
|
|
+ num.obj().set(col, 9);
|
|
|
r->commit_transaction();
|
|
|
- REQUIRE(num.row().get_int(0) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 9);
|
|
|
}
|
|
|
- REQUIRE(num.row().get_int(0) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 9);
|
|
|
}
|
|
|
SECTION("different realm") {
|
|
|
did_run_section = true;
|
|
|
{
|
|
|
SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object num = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
+ Object num = ref.resolve<Object>(r);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
r->begin_transaction();
|
|
|
- num.row().set_int(0, 9);
|
|
|
+ num.obj().set(col, 9);
|
|
|
r->commit_transaction();
|
|
|
- REQUIRE(num.row().get_int(0) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 9);
|
|
|
}
|
|
|
- REQUIRE(num.row().get_int(0) == 7);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 7);
|
|
|
}
|
|
|
catch2_ensure_section_run_workaround(did_run_section, "same thread", [&](){
|
|
|
r->begin_transaction(); // advance to latest version by starting a write
|
|
|
- REQUIRE(num.row().get_int(0) == 9);
|
|
|
+ REQUIRE(num.obj().get<Int>(col) == 9);
|
|
|
r->cancel_transaction();
|
|
|
});
|
|
|
}
|
|
@@ -285,73 +275,77 @@ TEST_CASE("thread safe reference") {
|
|
|
auto num = create_object(r, "int object", {{"value", INT64_C(0)}});
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- auto ref_str = r->obtain_thread_safe_reference(str);
|
|
|
- auto ref_num = r->obtain_thread_safe_reference(num);
|
|
|
- std::thread([ref_str = std::move(ref_str), ref_num = std::move(ref_num), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object str = r->resolve_thread_safe_reference(std::move(ref_str));
|
|
|
- Object num = r->resolve_thread_safe_reference(std::move(ref_num));
|
|
|
+ ColKey col_num = num.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ ColKey col_str = str.get_object_schema().property_for_name("value")->column_key;
|
|
|
+ auto ref_str = ThreadSafeReference(str);
|
|
|
+ auto ref_num = ThreadSafeReference(num);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Object str = ref_str.resolve<Object>(r2);
|
|
|
+ Object num = ref_num.resolve<Object>(r2);
|
|
|
|
|
|
- REQUIRE(str.row().get_string(0).is_null());
|
|
|
- REQUIRE(num.row().get_int(0) == 0);
|
|
|
+ REQUIRE(str.obj().get<String>(col_str).is_null());
|
|
|
+ REQUIRE(num.obj().get<Int>(col_num) == 0);
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- str.row().set_string(0, "the meaning of life");
|
|
|
- num.row().set_int(0, 42);
|
|
|
- r->commit_transaction();
|
|
|
- }).join();
|
|
|
+ r2->begin_transaction();
|
|
|
+ str.obj().set(col_str, "the meaning of life");
|
|
|
+ num.obj().set(col_num, 42);
|
|
|
+ r2->commit_transaction();
|
|
|
+ }
|
|
|
|
|
|
- REQUIRE(str.row().get_string(0).is_null());
|
|
|
- REQUIRE(num.row().get_int(0) == 0);
|
|
|
+ REQUIRE(str.obj().get<String>(col_str).is_null());
|
|
|
+ REQUIRE(num.obj().get<Int>(col_num) == 0);
|
|
|
|
|
|
r->refresh();
|
|
|
|
|
|
- REQUIRE(str.row().get_string(0) == "the meaning of life");
|
|
|
- REQUIRE(num.row().get_int(0) == 42);
|
|
|
+ REQUIRE(str.obj().get<String>(col_str) == "the meaning of life");
|
|
|
+ REQUIRE(num.obj().get<Int>(col_num) == 42);
|
|
|
}
|
|
|
|
|
|
SECTION("object list") {
|
|
|
r->begin_transaction();
|
|
|
auto zero = create_object(r, "int object", {{"value", INT64_C(0)}});
|
|
|
- create_object(r, "int array object", {{"value", AnyVector{zero}}});
|
|
|
- List list(r, *get_table(*r, "int array object"), 0, 0);
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{zero}}});
|
|
|
+ auto col = get_table(*r, "int array object")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(list.size() == 1);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 0);
|
|
|
- auto ref = r->obtain_thread_safe_reference(list);
|
|
|
- std::thread([ref = std::move(ref), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- List list = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 0);
|
|
|
+ auto ref = ThreadSafeReference(list);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ List list = ref.resolve<List>(r2);
|
|
|
REQUIRE(list.size() == 1);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 0);
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 0);
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
+ r2->begin_transaction();
|
|
|
list.remove_all();
|
|
|
- auto one = create_object(r, "int object", {{"value", INT64_C(1)}});
|
|
|
- auto two = create_object(r, "int object", {{"value", INT64_C(2)}});
|
|
|
- list.add(one.row());
|
|
|
- list.add(two.row());
|
|
|
- r->commit_transaction();
|
|
|
+ auto one = create_object(r2, "int object", {{"value", INT64_C(1)}});
|
|
|
+ auto two = create_object(r2, "int object", {{"value", INT64_C(2)}});
|
|
|
+ list.add(one.obj());
|
|
|
+ list.add(two.obj());
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
REQUIRE(list.size() == 2);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 1);
|
|
|
- REQUIRE(list.get(1).get_int(0) == 2);
|
|
|
- }).join();
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 1);
|
|
|
+ REQUIRE(list.get(1).get<int64_t>(int_obj_col) == 2);
|
|
|
+ }
|
|
|
|
|
|
REQUIRE(list.size() == 1);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 0);
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 0);
|
|
|
|
|
|
r->refresh();
|
|
|
|
|
|
REQUIRE(list.size() == 2);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 1);
|
|
|
- REQUIRE(list.get(1).get_int(0) == 2);
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 1);
|
|
|
+ REQUIRE(list.get(1).get<int64_t>(int_obj_col) == 2);
|
|
|
}
|
|
|
|
|
|
SECTION("sorted object results") {
|
|
|
auto& table = *get_table(*r, "string object");
|
|
|
- auto results = Results(r, table.where().not_equal(0, "C")).sort({table, {{0}}, {false}});
|
|
|
+ auto col = table.get_column_key("value");
|
|
|
+ auto results = Results(r, table.where().not_equal(col, "C")).sort({{{col}}, {false}});
|
|
|
|
|
|
r->begin_transaction();
|
|
|
create_object(r, "string object", {{"value", "A"s}});
|
|
@@ -361,45 +355,46 @@ TEST_CASE("thread safe reference") {
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "D");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- REQUIRE(results.get(2).get_string(0) == "A");
|
|
|
- auto ref = r->obtain_thread_safe_reference(results);
|
|
|
- std::thread([ref = std::move(ref), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Results results = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "D");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ REQUIRE(results.get(2).get<StringData>(col) == "A");
|
|
|
+ auto ref = ThreadSafeReference(results);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Results results = ref.resolve<Results>(r2);
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "D");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- REQUIRE(results.get(2).get_string(0) == "A");
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "D");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ REQUIRE(results.get(2).get<StringData>(col) == "A");
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- results.get(2).move_last_over();
|
|
|
- results.get(0).move_last_over();
|
|
|
- create_object(r, "string object", {{"value", "E"s}});
|
|
|
- r->commit_transaction();
|
|
|
+ r2->begin_transaction();
|
|
|
+ results.get(2).remove();
|
|
|
+ results.get(0).remove();
|
|
|
+ create_object(r2, "string object", {{"value", "E"s}});
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
REQUIRE(results.size() == 2);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "E");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- }).join();
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "E");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ }
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "D");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- REQUIRE(results.get(2).get_string(0) == "A");
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "D");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ REQUIRE(results.get(2).get<StringData>(col) == "A");
|
|
|
|
|
|
r->refresh();
|
|
|
|
|
|
REQUIRE(results.size() == 2);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "E");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "E");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
}
|
|
|
|
|
|
SECTION("distinct object results") {
|
|
|
auto& table = *get_table(*r, "string object");
|
|
|
- auto results = Results(r, table.where()).distinct({table, {{0}}}).sort({{"value", true}});
|
|
|
+ auto col = table.get_column_key("value");
|
|
|
+ auto results = Results(r, table.where()).distinct({{{col}}}).sort({{"value", true}});
|
|
|
|
|
|
r->begin_transaction();
|
|
|
create_object(r, "string object", {{"value", "A"s}});
|
|
@@ -408,63 +403,64 @@ TEST_CASE("thread safe reference") {
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(results.size() == 2);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "A");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- auto ref = r->obtain_thread_safe_reference(results);
|
|
|
- std::thread([ref = std::move(ref), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Results results = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "A");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ auto ref = ThreadSafeReference(results);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Results results = ref.resolve<Results>(r2);
|
|
|
|
|
|
REQUIRE(results.size() == 2);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "A");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "A");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- results.get(0).move_last_over();
|
|
|
- create_object(r, "string object", {{"value", "C"s}});
|
|
|
- r->commit_transaction();
|
|
|
+ r2->begin_transaction();
|
|
|
+ results.get(0).remove();
|
|
|
+ create_object(r2, "string object", {{"value", "C"s}});
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "A");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- REQUIRE(results.get(2).get_string(0) == "C");
|
|
|
- }).join();
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "A");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ REQUIRE(results.get(2).get<StringData>(col) == "C");
|
|
|
+ }
|
|
|
|
|
|
REQUIRE(results.size() == 2);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "A");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "A");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
|
|
|
r->refresh();
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
- REQUIRE(results.get(0).get_string(0) == "A");
|
|
|
- REQUIRE(results.get(1).get_string(0) == "B");
|
|
|
- REQUIRE(results.get(2).get_string(0) == "C");
|
|
|
+ REQUIRE(results.get(0).get<StringData>(col) == "A");
|
|
|
+ REQUIRE(results.get(1).get<StringData>(col) == "B");
|
|
|
+ REQUIRE(results.get(2).get<StringData>(col) == "C");
|
|
|
}
|
|
|
|
|
|
SECTION("int list") {
|
|
|
r->begin_transaction();
|
|
|
- create_object(r, "int array", {{"value", AnyVector{INT64_C(0)}}});
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{INT64_C(0)}}});
|
|
|
+ auto col = get_table(*r, "int array")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- auto ref = r->obtain_thread_safe_reference(list);
|
|
|
- std::thread([ref = std::move(ref), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- List list = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ auto ref = ThreadSafeReference(list);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ List list = ref.resolve<List>(r2);
|
|
|
REQUIRE(list.size() == 1);
|
|
|
REQUIRE(list.get<int64_t>(0) == 0);
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
+ r2->begin_transaction();
|
|
|
list.remove_all();
|
|
|
- list.add(1);
|
|
|
- list.add(2);
|
|
|
- r->commit_transaction();
|
|
|
+ list.add(int64_t(1));
|
|
|
+ list.add(int64_t(2));
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
REQUIRE(list.size() == 2);
|
|
|
REQUIRE(list.get<int64_t>(0) == 1);
|
|
|
REQUIRE(list.get<int64_t>(1) == 2);
|
|
|
- }).join();
|
|
|
+ };
|
|
|
|
|
|
REQUIRE(list.size() == 1);
|
|
|
REQUIRE(list.get<int64_t>(0) == 0);
|
|
@@ -478,8 +474,9 @@ TEST_CASE("thread safe reference") {
|
|
|
|
|
|
SECTION("sorted int results") {
|
|
|
r->begin_transaction();
|
|
|
- create_object(r, "int array", {{"value", AnyVector{INT64_C(0), INT64_C(2), INT64_C(1)}}});
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{INT64_C(0), INT64_C(2), INT64_C(1)}}});
|
|
|
+ auto col = get_table(*r, "int array")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
auto results = list.sort({{"self", true}});
|
|
@@ -488,10 +485,11 @@ TEST_CASE("thread safe reference") {
|
|
|
REQUIRE(results.get<int64_t>(0) == 0);
|
|
|
REQUIRE(results.get<int64_t>(1) == 1);
|
|
|
REQUIRE(results.get<int64_t>(2) == 2);
|
|
|
- auto ref = r->obtain_thread_safe_reference(results);
|
|
|
+ auto ref = ThreadSafeReference(results);
|
|
|
std::thread([ref = std::move(ref), config]() mutable {
|
|
|
+ config.scheduler = util::Scheduler::get_frozen();
|
|
|
SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Results results = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ Results results = ref.resolve<Results>(r);
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
REQUIRE(results.get<int64_t>(0) == 0);
|
|
@@ -499,9 +497,10 @@ TEST_CASE("thread safe reference") {
|
|
|
REQUIRE(results.get<int64_t>(2) == 2);
|
|
|
|
|
|
r->begin_transaction();
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ auto table = get_table(*r, "int array");
|
|
|
+ List list(r, *table->begin(), table->get_column_key("value"));
|
|
|
list.remove(1);
|
|
|
- list.add(-1);
|
|
|
+ list.add(int64_t(-1));
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
@@ -525,8 +524,10 @@ TEST_CASE("thread safe reference") {
|
|
|
|
|
|
SECTION("distinct int results") {
|
|
|
r->begin_transaction();
|
|
|
- create_object(r, "int array", {{"value", AnyVector{INT64_C(3), INT64_C(2), INT64_C(1), INT64_C(1), INT64_C(2)}}});
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ auto obj = create_object(
|
|
|
+ r, "int array", {{"value", AnyVector{INT64_C(3), INT64_C(2), INT64_C(1), INT64_C(1), INT64_C(2)}}});
|
|
|
+ auto col = get_table(*r, "int array")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
auto results = list.as_results().distinct({"self"}).sort({{"self", true}});
|
|
@@ -536,10 +537,11 @@ TEST_CASE("thread safe reference") {
|
|
|
REQUIRE(results.get<int64_t>(1) == 2);
|
|
|
REQUIRE(results.get<int64_t>(2) == 3);
|
|
|
|
|
|
- auto ref = r->obtain_thread_safe_reference(results);
|
|
|
+ auto ref = ThreadSafeReference(results);
|
|
|
std::thread([ref = std::move(ref), config]() mutable {
|
|
|
+ config.scheduler = util::Scheduler::get_frozen();
|
|
|
SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Results results = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ Results results = ref.resolve<Results>(r);
|
|
|
|
|
|
REQUIRE(results.size() == 3);
|
|
|
REQUIRE(results.get<int64_t>(0) == 1);
|
|
@@ -547,7 +549,8 @@ TEST_CASE("thread safe reference") {
|
|
|
REQUIRE(results.get<int64_t>(2) == 3);
|
|
|
|
|
|
r->begin_transaction();
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ auto table = get_table(*r, "int array");
|
|
|
+ List list(r, *table->begin(), table->get_column_key("value"));
|
|
|
list.remove(1);
|
|
|
list.remove(0);
|
|
|
r->commit_transaction();
|
|
@@ -570,49 +573,49 @@ TEST_CASE("thread safe reference") {
|
|
|
}
|
|
|
|
|
|
SECTION("multiple types") {
|
|
|
- auto results = Results(r, get_table(*r, "int object")->where().equal(0, 5));
|
|
|
+ auto results = Results(r, get_table(*r, "int object")->where().equal(int_obj_col, 5));
|
|
|
|
|
|
r->begin_transaction();
|
|
|
auto num = create_object(r, "int object", {{"value", INT64_C(5)}});
|
|
|
- create_object(r, "int array object", {{"value", AnyVector{}}});
|
|
|
- List list(r, *get_table(*r, "int array object"), 0, 0);
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{}}});
|
|
|
+ auto col = get_table(*r, "int array object")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(list.size() == 0);
|
|
|
REQUIRE(results.size() == 1);
|
|
|
- REQUIRE(results.get(0).get_int(0) == 5);
|
|
|
- auto ref_num = r->obtain_thread_safe_reference(num);
|
|
|
- auto ref_list = r->obtain_thread_safe_reference(list);
|
|
|
- auto ref_results = r->obtain_thread_safe_reference(results);
|
|
|
- std::thread([ref_num = std::move(ref_num), ref_list = std::move(ref_list),
|
|
|
- ref_results = std::move(ref_results), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object num = r->resolve_thread_safe_reference(std::move(ref_num));
|
|
|
- List list = r->resolve_thread_safe_reference(std::move(ref_list));
|
|
|
- Results results = r->resolve_thread_safe_reference(std::move(ref_results));
|
|
|
+ REQUIRE(results.get(0).get<int64_t>(int_obj_col) == 5);
|
|
|
+ auto ref_num = ThreadSafeReference(num);
|
|
|
+ auto ref_list = ThreadSafeReference(list);
|
|
|
+ auto ref_results = ThreadSafeReference(results);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ auto num = ref_num.resolve<Object>(r2);
|
|
|
+ auto list = ref_list.resolve<List>(r2);
|
|
|
+ auto results = ref_results.resolve<Results>(r2);
|
|
|
|
|
|
REQUIRE(list.size() == 0);
|
|
|
REQUIRE(results.size() == 1);
|
|
|
- REQUIRE(results.get(0).get_int(0) == 5);
|
|
|
+ REQUIRE(results.get(0).get<int64_t>(int_obj_col) == 5);
|
|
|
|
|
|
- r->begin_transaction();
|
|
|
- num.row().set_int(0, 6);
|
|
|
- list.add(num.row().get_index());
|
|
|
- r->commit_transaction();
|
|
|
+ r2->begin_transaction();
|
|
|
+ num.obj().set_all(6);
|
|
|
+ list.add(num.obj().get_key());
|
|
|
+ r2->commit_transaction();
|
|
|
|
|
|
REQUIRE(list.size() == 1);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 6);
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 6);
|
|
|
REQUIRE(results.size() == 0);
|
|
|
- }).join();
|
|
|
+ }
|
|
|
|
|
|
REQUIRE(list.size() == 0);
|
|
|
REQUIRE(results.size() == 1);
|
|
|
- REQUIRE(results.get(0).get_int(0) == 5);
|
|
|
+ REQUIRE(results.get(0).get<int64_t>(int_obj_col) == 5);
|
|
|
|
|
|
r->refresh();
|
|
|
|
|
|
REQUIRE(list.size() == 1);
|
|
|
- REQUIRE(list.get(0).get_int(0) == 6);
|
|
|
+ REQUIRE(list.get(0).get<int64_t>(int_obj_col) == 6);
|
|
|
REQUIRE(results.size() == 0);
|
|
|
}
|
|
|
}
|
|
@@ -620,13 +623,13 @@ TEST_CASE("thread safe reference") {
|
|
|
SECTION("resolve at version where handed over thing has been deleted") {
|
|
|
Object obj;
|
|
|
auto delete_and_resolve = [&](auto&& list) {
|
|
|
- auto ref = r->obtain_thread_safe_reference(list);
|
|
|
+ auto ref = ThreadSafeReference(list);
|
|
|
|
|
|
r->begin_transaction();
|
|
|
- obj.row().move_last_over();
|
|
|
+ obj.obj().remove();
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- return r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ return ref.resolve<typename std::remove_reference<decltype(list)>::type>(r);
|
|
|
};
|
|
|
|
|
|
SECTION("object") {
|
|
@@ -640,7 +643,8 @@ TEST_CASE("thread safe reference") {
|
|
|
SECTION("object list") {
|
|
|
r->begin_transaction();
|
|
|
obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
- List list(r, *get_table(*r, "int array object"), 0, 0);
|
|
|
+ auto col = get_table(*r, "int array object")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(!delete_and_resolve(list).is_valid());
|
|
@@ -648,8 +652,9 @@ TEST_CASE("thread safe reference") {
|
|
|
|
|
|
SECTION("int list") {
|
|
|
r->begin_transaction();
|
|
|
- obj = create_object(r, "int array", {{"value", AnyVector{INT64_C(1)}}});
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ auto col = get_table(*r, "int array")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
REQUIRE(!delete_and_resolve(list).is_valid());
|
|
@@ -658,7 +663,8 @@ TEST_CASE("thread safe reference") {
|
|
|
SECTION("object results") {
|
|
|
r->begin_transaction();
|
|
|
obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
- List list(r, *get_table(*r, "int array object"), 0, 0);
|
|
|
+ auto col = get_table(*r, "int array object")->get_column_key("value");
|
|
|
+ List list(r, obj.obj(), col);
|
|
|
r->commit_transaction();
|
|
|
|
|
|
auto results = delete_and_resolve(list.sort({{"value", true}}));
|
|
@@ -668,22 +674,193 @@ TEST_CASE("thread safe reference") {
|
|
|
|
|
|
SECTION("int results") {
|
|
|
r->begin_transaction();
|
|
|
- obj = create_object(r, "int array", {{"value", AnyVector{INT64_C(1)}}});
|
|
|
- List list(r, *get_table(*r, "int array"), 0, 0);
|
|
|
+ obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ List list(r, obj.obj(), get_table(*r, "int array")->get_column_key("value"));
|
|
|
r->commit_transaction();
|
|
|
|
|
|
- auto results = delete_and_resolve(list.sort({{"self", true}}));
|
|
|
+ REQUIRE(!delete_and_resolve(list).is_valid());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("resolve at version before where handed over thing was created") {
|
|
|
+ auto create_ref = [&](auto&& fn) -> ThreadSafeReference {
|
|
|
+ ThreadSafeReference ref;
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ r2->begin_transaction();
|
|
|
+ auto obj = fn(r2);
|
|
|
+ r2->commit_transaction();
|
|
|
+ ref = obj;
|
|
|
+ };
|
|
|
+ return ref;
|
|
|
+ };
|
|
|
+
|
|
|
+ SECTION("object") {
|
|
|
+ auto obj = create_ref([](auto& r) {
|
|
|
+ return create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ }).resolve<Object>(r);
|
|
|
+ REQUIRE(obj.is_valid());
|
|
|
+ REQUIRE(obj.get_column_value<int64_t>("value") == 7);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("object list") {
|
|
|
+ auto list = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array object")->get_column_key("value"));
|
|
|
+ }).resolve<List>(r);
|
|
|
+ REQUIRE(list.is_valid());
|
|
|
+ REQUIRE(list.size() == 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("int list") {
|
|
|
+ auto list = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array")->get_column_key("value"));
|
|
|
+ }).resolve<List>(r);
|
|
|
+ REQUIRE(list.is_valid());
|
|
|
+ REQUIRE(list.size() == 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("object results") {
|
|
|
+ auto results = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
+ Results results = List(r, obj.obj(), get_table(*r, "int array object")->get_column_key("value"))
|
|
|
+ .sort({{"value", true}});
|
|
|
+ REQUIRE(results.size() == 1);
|
|
|
+ return results;
|
|
|
+ }).resolve<Results>(r);
|
|
|
REQUIRE(results.is_valid());
|
|
|
- REQUIRE(results.size() == 0);
|
|
|
+ REQUIRE(results.size() == 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("int results") {
|
|
|
+ auto results = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array")->get_column_key("value")).sort({{"self", true}});
|
|
|
+ }).resolve<Results>(r);
|
|
|
+ REQUIRE(results.is_valid());
|
|
|
+ REQUIRE(results.size() == 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("create TSR inside the write transaction which created the object being handed over") {
|
|
|
+ auto create_ref = [&](auto&& fn) -> ThreadSafeReference {
|
|
|
+ ThreadSafeReference ref;
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ r2->begin_transaction();
|
|
|
+ ref = fn(r2);
|
|
|
+ r2->commit_transaction();
|
|
|
+ };
|
|
|
+ return ref;
|
|
|
+ };
|
|
|
+
|
|
|
+ SECTION("object") {
|
|
|
+ auto obj = create_ref([](auto& r) {
|
|
|
+ return create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ }).resolve<Object>(r);
|
|
|
+ REQUIRE(obj.is_valid());
|
|
|
+ REQUIRE(obj.get_column_value<int64_t>("value") == 7);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("object list") {
|
|
|
+ auto list = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array object")->get_column_key("value"));
|
|
|
+ }).resolve<List>(r);
|
|
|
+ REQUIRE(list.is_valid());
|
|
|
+ REQUIRE(list.size() == 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("int list") {
|
|
|
+ auto list = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array")->get_column_key("value"));
|
|
|
+ }).resolve<List>(r);
|
|
|
+ REQUIRE(list.is_valid());
|
|
|
+ REQUIRE(list.size() == 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("object results") {
|
|
|
+ REQUIRE_THROWS(create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
+ Results results = List(r, obj.obj(), get_table(*r, "int array object")->get_column_key("value"))
|
|
|
+ .sort({{"value", true}});
|
|
|
+ REQUIRE(results.size() == 1);
|
|
|
+ return results;
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("int results") {
|
|
|
+ auto results = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array")->get_column_key("value")).sort({{"self", true}});
|
|
|
+ }).resolve<Results>(r);
|
|
|
+ REQUIRE(results.is_valid());
|
|
|
+ REQUIRE(results.size() == 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("create TSR inside cancelled write transaction") {
|
|
|
+ auto create_ref = [&](auto&& fn) -> ThreadSafeReference {
|
|
|
+ ThreadSafeReference ref;
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ r2->begin_transaction();
|
|
|
+ ref = fn(r2);
|
|
|
+ r2->cancel_transaction();
|
|
|
+ };
|
|
|
+ return ref;
|
|
|
+ };
|
|
|
+
|
|
|
+ SECTION("object") {
|
|
|
+ auto obj = create_ref([](auto& r) {
|
|
|
+ return create_object(r, "int object", {{"value", INT64_C(7)}});
|
|
|
+ }).resolve<Object>(r);
|
|
|
+ REQUIRE_FALSE(obj.is_valid());
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("object list") {
|
|
|
+ auto list = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array object")->get_column_key("value"));
|
|
|
+ }).resolve<List>(r);
|
|
|
+ REQUIRE_FALSE(list.is_valid());
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("int list") {
|
|
|
+ auto list = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array")->get_column_key("value"));
|
|
|
+ }).resolve<List>(r);
|
|
|
+ REQUIRE_FALSE(list.is_valid());
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("object results") {
|
|
|
+ REQUIRE_THROWS(create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array object", {{"value", AnyVector{AnyDict{{"value", INT64_C(0)}}}}});
|
|
|
+ Results results = List(r, obj.obj(), get_table(*r, "int array object")->get_column_key("value"))
|
|
|
+ .sort({{"value", true}});
|
|
|
+ REQUIRE(results.size() == 1);
|
|
|
+ return results;
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ SECTION("int results") {
|
|
|
+ auto results = create_ref([](auto& r) {
|
|
|
+ auto obj = create_object(r, "int array", {{"value", AnyVector{{INT64_C(1)}}}});
|
|
|
+ return List(r, obj.obj(), get_table(*r, "int array")->get_column_key("value")).sort({{"self", true}});
|
|
|
+ }).resolve<Results>(r);
|
|
|
+ REQUIRE_FALSE(results.is_valid());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
SECTION("lifetime") {
|
|
|
SECTION("retains source realm") { // else version will become unpinned
|
|
|
- auto ref = r->obtain_thread_safe_reference(foo);
|
|
|
+ auto ref = ThreadSafeReference(foo);
|
|
|
r = nullptr;
|
|
|
r = Realm::get_shared_realm(config);
|
|
|
- REQUIRE_NOTHROW(r->resolve_thread_safe_reference(std::move(ref)));
|
|
|
+ REQUIRE_NOTHROW(ref.resolve<Object>(r));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -693,17 +870,17 @@ TEST_CASE("thread safe reference") {
|
|
|
r->commit_transaction();
|
|
|
REQUIRE(num.get_object_schema().name == "int object");
|
|
|
|
|
|
- auto ref = r->obtain_thread_safe_reference(num);
|
|
|
- std::thread([ref = std::move(ref), config]() mutable {
|
|
|
- SharedRealm r = Realm::get_shared_realm(config);
|
|
|
- Object num = r->resolve_thread_safe_reference(std::move(ref));
|
|
|
+ auto ref = ThreadSafeReference(num);
|
|
|
+ {
|
|
|
+ SharedRealm r2 = Realm::get_shared_realm(config);
|
|
|
+ Object num = ref.resolve<Object>(r2);
|
|
|
REQUIRE(num.get_object_schema().name == "int object");
|
|
|
- }).join();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- SECTION("disallow multiple resolves") {
|
|
|
- auto ref = r->obtain_thread_safe_reference(foo);
|
|
|
- r->resolve_thread_safe_reference(std::move(ref));
|
|
|
- REQUIRE_THROWS(r->resolve_thread_safe_reference(std::move(ref)));
|
|
|
+ SECTION("allow multiple resolves") {
|
|
|
+ auto ref = ThreadSafeReference(foo);
|
|
|
+ ref.resolve<Object>(r);
|
|
|
+ REQUIRE_NOTHROW(ref.resolve<Object>(r));
|
|
|
}
|
|
|
}
|