latest object store
This commit is contained in:
commit
7fe2f69b8c
|
@ -7,7 +7,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
|
|||
include(CompilerFlags)
|
||||
|
||||
include(RealmCore)
|
||||
set(REALM_CORE_VERSION "0.96.2" CACHE STRING "")
|
||||
set(REALM_CORE_VERSION "0.97.0" CACHE STRING "")
|
||||
use_realm_core(${REALM_CORE_VERSION})
|
||||
|
||||
include_directories(${REALM_CORE_INCLUDE_DIR} src external/pegtl)
|
||||
|
|
|
@ -11,7 +11,7 @@ Cross-platform code used accross bindings. Binding developers can choose to use
|
|||
The object store's build system currently only suports building for OS X. The object store itself can build for all Apple
|
||||
platforms when integrated into a binding.
|
||||
|
||||
1. Install CMake. You can download an installer for OS X from the [CMake download page], or install via [Homebrew](http://brew.sh):
|
||||
1. Install CMake. You can download an installer for OS X from the [CMake download page](https://cmake.org/download/), or install via [Homebrew](http://brew.sh):
|
||||
```
|
||||
brew install cmake
|
||||
```
|
||||
|
|
|
@ -159,7 +159,7 @@ void AsyncQuery::run()
|
|||
if (m_initial_run_complete) {
|
||||
// Make an empty tableview from the query to get the table version, since
|
||||
// Query doesn't expose it
|
||||
if (m_query->find_all(0, 0, 0).outside_version() == m_handed_over_table_version) {
|
||||
if (m_query->find_all(0, 0, 0).sync_if_needed() == m_handed_over_table_version) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ void AsyncQuery::prepare_handover()
|
|||
REALM_ASSERT(m_tv.is_in_sync());
|
||||
|
||||
m_initial_run_complete = true;
|
||||
m_handed_over_table_version = m_tv.outside_version();
|
||||
m_handed_over_table_version = m_tv.sync_if_needed();
|
||||
m_tv_handover = m_sg->export_for_handover(m_tv, MutableSourcePayload::Move);
|
||||
|
||||
// detach the TableView as we won't need it again and keeping it around
|
||||
|
@ -231,7 +231,7 @@ bool AsyncQuery::deliver(SharedGroup& sg, std::exception_ptr err)
|
|||
m_tv_handover->version = m_sg_version;
|
||||
Results::Internal::set_table_view(*m_target_results,
|
||||
std::move(*sg.import_from_handover(std::move(m_tv_handover))));
|
||||
m_delievered_table_version = m_handed_over_table_version;
|
||||
m_delivered_table_version = m_handed_over_table_version;
|
||||
|
||||
}
|
||||
REALM_ASSERT(!m_tv_handover);
|
||||
|
@ -259,8 +259,8 @@ std::function<void (std::exception_ptr)> AsyncQuery::next_callback()
|
|||
std::lock_guard<std::mutex> callback_lock(m_callback_mutex);
|
||||
for (++m_callback_index; m_callback_index < m_callbacks.size(); ++m_callback_index) {
|
||||
auto& callback = m_callbacks[m_callback_index];
|
||||
if (m_error || callback.delivered_version != m_delievered_table_version) {
|
||||
callback.delivered_version = m_delievered_table_version;
|
||||
if (m_error || callback.delivered_version != m_delivered_table_version) {
|
||||
callback.delivered_version = m_delivered_table_version;
|
||||
return callback.fn;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ private:
|
|||
SharedGroup* m_sg = nullptr;
|
||||
|
||||
uint_fast64_t m_handed_over_table_version = -1;
|
||||
uint_fast64_t m_delievered_table_version = -1;
|
||||
uint_fast64_t m_delivered_table_version = -1;
|
||||
|
||||
// Iteration variable for looping over callbacks
|
||||
// remove_callback() updates this when needed
|
||||
|
|
|
@ -385,7 +385,7 @@ void RealmCoordinator::move_new_queries_to_main()
|
|||
void RealmCoordinator::advance_helper_shared_group_to_latest()
|
||||
{
|
||||
if (m_new_queries.empty()) {
|
||||
LangBindHelper::advance_read(*m_query_sg, *m_query_history);
|
||||
LangBindHelper::advance_read(*m_query_sg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -397,14 +397,13 @@ void RealmCoordinator::advance_helper_shared_group_to_latest()
|
|||
|
||||
// Import all newly added queries to our helper SG
|
||||
for (auto& query : m_new_queries) {
|
||||
LangBindHelper::advance_read(*m_advancer_sg, *m_advancer_history, query->version());
|
||||
LangBindHelper::advance_read(*m_advancer_sg, query->version());
|
||||
query->attach_to(*m_advancer_sg);
|
||||
}
|
||||
|
||||
// Advance both SGs to the newest version
|
||||
LangBindHelper::advance_read(*m_advancer_sg, *m_advancer_history);
|
||||
LangBindHelper::advance_read(*m_query_sg, *m_query_history,
|
||||
m_advancer_sg->get_version_of_current_transaction());
|
||||
LangBindHelper::advance_read(*m_advancer_sg);
|
||||
LangBindHelper::advance_read(*m_query_sg, m_advancer_sg->get_version_of_current_transaction());
|
||||
|
||||
// Transfer all new queries over to the main SG
|
||||
for (auto& query : m_new_queries) {
|
||||
|
@ -421,7 +420,6 @@ void RealmCoordinator::advance_to_ready(Realm& realm)
|
|||
decltype(m_queries) queries;
|
||||
|
||||
auto& sg = Realm::Internal::get_shared_group(realm);
|
||||
auto& history = Realm::Internal::get_history(realm);
|
||||
|
||||
auto get_query_version = [&] {
|
||||
for (auto& query : m_queries) {
|
||||
|
@ -440,8 +438,8 @@ void RealmCoordinator::advance_to_ready(Realm& realm)
|
|||
}
|
||||
|
||||
// no async queries; just advance to latest
|
||||
if (version.version == 0) {
|
||||
transaction::advance(sg, history, realm.m_binding_context.get());
|
||||
if (version.version == std::numeric_limits<uint_fast64_t>::max()) {
|
||||
transaction::advance(sg, realm.m_binding_context.get());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -453,14 +451,14 @@ void RealmCoordinator::advance_to_ready(Realm& realm)
|
|||
while (true) {
|
||||
// Advance to the ready version without holding any locks because it
|
||||
// may end up calling user code (in did_change() notifications)
|
||||
transaction::advance(sg, history, realm.m_binding_context.get(), version);
|
||||
transaction::advance(sg, realm.m_binding_context.get(), version);
|
||||
|
||||
// Reacquire the lock and recheck the query version, as the queries may
|
||||
// have advanced to a later version while we didn't hold the lock. If
|
||||
// so, we need to release the lock and re-advance
|
||||
std::lock_guard<std::mutex> lock(m_query_mutex);
|
||||
version = get_query_version();
|
||||
if (version.version == 0)
|
||||
if (version.version == std::numeric_limits<uint_fast64_t>::max())
|
||||
return;
|
||||
if (version != sg.get_version_of_current_transaction())
|
||||
continue;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
namespace realm {
|
||||
class AsyncQueryCallback;
|
||||
class ClientHistory;
|
||||
class Replication;
|
||||
class Results;
|
||||
class Schema;
|
||||
class SharedGroup;
|
||||
|
@ -102,13 +102,13 @@ private:
|
|||
|
||||
// SharedGroup used for actually running async queries
|
||||
// Will have a read transaction iff m_queries is non-empty
|
||||
std::unique_ptr<ClientHistory> m_query_history;
|
||||
std::unique_ptr<Replication> m_query_history;
|
||||
std::unique_ptr<SharedGroup> m_query_sg;
|
||||
|
||||
// SharedGroup used to advance queries in m_new_queries to the main shared
|
||||
// group's transaction version
|
||||
// Will have a read transaction iff m_new_queries is non-empty
|
||||
std::unique_ptr<ClientHistory> m_advancer_history;
|
||||
std::unique_ptr<Replication> m_advancer_history;
|
||||
std::unique_ptr<SharedGroup> m_advancer_sg;
|
||||
std::exception_ptr m_async_error;
|
||||
|
||||
|
|
|
@ -432,23 +432,21 @@ public:
|
|||
namespace realm {
|
||||
namespace _impl {
|
||||
namespace transaction {
|
||||
void advance(SharedGroup& sg, ClientHistory& history, BindingContext* context,
|
||||
SharedGroup::VersionID version)
|
||||
void advance(SharedGroup& sg, BindingContext* context, SharedGroup::VersionID version)
|
||||
{
|
||||
TransactLogObserver(context, sg, [&](auto&&... args) {
|
||||
LangBindHelper::advance_read(sg, history, std::move(args)...);
|
||||
LangBindHelper::advance_read(sg, std::move(args)...);
|
||||
}, true);
|
||||
}
|
||||
|
||||
void begin(SharedGroup& sg, ClientHistory& history, BindingContext* context,
|
||||
bool validate_schema_changes)
|
||||
void begin(SharedGroup& sg, BindingContext* context, bool validate_schema_changes)
|
||||
{
|
||||
TransactLogObserver(context, sg, [&](auto&&... args) {
|
||||
LangBindHelper::promote_to_write(sg, history, std::move(args)...);
|
||||
LangBindHelper::promote_to_write(sg, std::move(args)...);
|
||||
}, validate_schema_changes);
|
||||
}
|
||||
|
||||
void commit(SharedGroup& sg, ClientHistory&, BindingContext* context)
|
||||
void commit(SharedGroup& sg, BindingContext* context)
|
||||
{
|
||||
LangBindHelper::commit_and_continue_as_read(sg);
|
||||
|
||||
|
@ -457,10 +455,10 @@ void commit(SharedGroup& sg, ClientHistory&, BindingContext* context)
|
|||
}
|
||||
}
|
||||
|
||||
void cancel(SharedGroup& sg, ClientHistory& history, BindingContext* context)
|
||||
void cancel(SharedGroup& sg, BindingContext* context)
|
||||
{
|
||||
TransactLogObserver(context, sg, [&](auto&&... args) {
|
||||
LangBindHelper::rollback_and_continue_as_read(sg, history, std::move(args)...);
|
||||
LangBindHelper::rollback_and_continue_as_read(sg, std::move(args)...);
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,27 +24,26 @@
|
|||
namespace realm {
|
||||
class BindingContext;
|
||||
class SharedGroup;
|
||||
class ClientHistory;
|
||||
|
||||
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, BindingContext* binding_context,
|
||||
void advance(SharedGroup& sg, BindingContext* binding_context,
|
||||
SharedGroup::VersionID version=SharedGroup::VersionID{});
|
||||
|
||||
// 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, BindingContext* binding_context,
|
||||
void begin(SharedGroup& sg, BindingContext* binding_context,
|
||||
bool validate_schema_changes=true);
|
||||
|
||||
// Commit a write transaction
|
||||
void commit(SharedGroup& sg, ClientHistory& history, BindingContext* binding_context);
|
||||
void commit(SharedGroup& sg, BindingContext* 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, BindingContext* binding_context);
|
||||
void cancel(SharedGroup& sg, BindingContext* binding_context);
|
||||
} // namespace transaction
|
||||
} // namespace _impl
|
||||
} // namespace realm
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace realm {
|
|||
|
||||
size_t table_column = -1;
|
||||
bool requires_index() const { return is_primary || is_indexed; }
|
||||
bool is_indexable() const { return type == PropertyTypeInt || type == PropertyTypeBool || type == PropertyTypeString || type == PropertyTypeDate; }
|
||||
};
|
||||
|
||||
static inline const char *string_for_property_type(PropertyType type) {
|
||||
|
|
|
@ -89,7 +89,7 @@ void Schema::validate() const
|
|||
|
||||
// check indexable
|
||||
if (prop.is_indexed) {
|
||||
if (prop.type != PropertyTypeString && prop.type != PropertyTypeInt) {
|
||||
if (!prop.is_indexable()) {
|
||||
exceptions.emplace_back(PropertyTypeNotIndexableException(object.name, prop));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ Realm::Realm(Config config)
|
|||
}
|
||||
|
||||
void Realm::open_with_config(const Config& config,
|
||||
std::unique_ptr<ClientHistory>& history,
|
||||
std::unique_ptr<Replication>& history,
|
||||
std::unique_ptr<SharedGroup>& shared_group,
|
||||
std::unique_ptr<Group>& read_only_group)
|
||||
{
|
||||
|
@ -211,9 +211,8 @@ void Realm::update_schema(std::unique_ptr<Schema> schema, uint64_t version)
|
|||
}
|
||||
|
||||
read_group();
|
||||
transaction::begin(*m_shared_group, *m_history, m_binding_context.get(),
|
||||
transaction::begin(*m_shared_group, m_binding_context.get(),
|
||||
/* error on schema changes */ false);
|
||||
m_in_transaction = true;
|
||||
|
||||
struct WriteTransactionGuard {
|
||||
Realm& realm;
|
||||
|
@ -289,20 +288,27 @@ void Realm::verify_in_write() const
|
|||
}
|
||||
}
|
||||
|
||||
bool Realm::is_in_transaction() const noexcept
|
||||
{
|
||||
if (!m_shared_group) {
|
||||
return false;
|
||||
}
|
||||
return m_shared_group->get_transact_stage() == SharedGroup::transact_Writing;
|
||||
}
|
||||
|
||||
void Realm::begin_transaction()
|
||||
{
|
||||
check_read_write(this);
|
||||
verify_thread();
|
||||
|
||||
if (m_in_transaction) {
|
||||
if (is_in_transaction()) {
|
||||
throw InvalidTransactionException("The Realm is already in a write transaction");
|
||||
}
|
||||
|
||||
// make sure we have a read transaction
|
||||
read_group();
|
||||
|
||||
transaction::begin(*m_shared_group, *m_history, m_binding_context.get());
|
||||
m_in_transaction = true;
|
||||
transaction::begin(*m_shared_group, m_binding_context.get());
|
||||
}
|
||||
|
||||
void Realm::commit_transaction()
|
||||
|
@ -310,12 +316,11 @@ void Realm::commit_transaction()
|
|||
check_read_write(this);
|
||||
verify_thread();
|
||||
|
||||
if (!m_in_transaction) {
|
||||
if (!is_in_transaction()) {
|
||||
throw InvalidTransactionException("Can't commit a non-existing write transaction");
|
||||
}
|
||||
|
||||
m_in_transaction = false;
|
||||
transaction::commit(*m_shared_group, *m_history, m_binding_context.get());
|
||||
transaction::commit(*m_shared_group, m_binding_context.get());
|
||||
m_coordinator->send_commit_notifications();
|
||||
}
|
||||
|
||||
|
@ -324,18 +329,19 @@ void Realm::cancel_transaction()
|
|||
check_read_write(this);
|
||||
verify_thread();
|
||||
|
||||
if (!m_in_transaction) {
|
||||
if (!is_in_transaction()) {
|
||||
throw InvalidTransactionException("Can't cancel a non-existing write transaction");
|
||||
}
|
||||
|
||||
m_in_transaction = false;
|
||||
transaction::cancel(*m_shared_group, *m_history, m_binding_context.get());
|
||||
transaction::cancel(*m_shared_group, m_binding_context.get());
|
||||
}
|
||||
|
||||
void Realm::invalidate()
|
||||
{
|
||||
verify_thread();
|
||||
if (m_in_transaction) {
|
||||
check_read_write(this);
|
||||
|
||||
if (is_in_transaction()) {
|
||||
cancel_transaction();
|
||||
}
|
||||
if (!m_group) {
|
||||
|
@ -353,7 +359,7 @@ bool Realm::compact()
|
|||
if (m_config.read_only) {
|
||||
throw InvalidTransactionException("Can't compact a read-only Realm");
|
||||
}
|
||||
if (m_in_transaction) {
|
||||
if (is_in_transaction()) {
|
||||
throw InvalidTransactionException("Can't compact a Realm within a write transaction");
|
||||
}
|
||||
|
||||
|
@ -395,7 +401,7 @@ bool Realm::refresh()
|
|||
check_read_write(this);
|
||||
|
||||
// can't be any new changes if we're in a write transaction
|
||||
if (m_in_transaction) {
|
||||
if (is_in_transaction()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -405,7 +411,7 @@ bool Realm::refresh()
|
|||
}
|
||||
|
||||
if (m_group) {
|
||||
transaction::advance(*m_shared_group, *m_history, m_binding_context.get());
|
||||
transaction::advance(*m_shared_group, m_binding_context.get());
|
||||
m_coordinator->process_available_async(*this);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
namespace realm {
|
||||
class BindingContext;
|
||||
class ClientHistory;
|
||||
class Replication;
|
||||
class Group;
|
||||
class Realm;
|
||||
class RealmDelegate;
|
||||
|
@ -114,7 +114,7 @@ namespace realm {
|
|||
void begin_transaction();
|
||||
void commit_transaction();
|
||||
void cancel_transaction();
|
||||
bool is_in_transaction() const { return m_in_transaction; }
|
||||
bool is_in_transaction() const noexcept;
|
||||
bool is_in_read_transaction() const { return !!m_group; }
|
||||
|
||||
bool refresh();
|
||||
|
@ -149,7 +149,6 @@ namespace realm {
|
|||
// AsyncQuery needs access to the SharedGroup to be able to call the
|
||||
// handover functions, which are not very wrappable
|
||||
static SharedGroup& get_shared_group(Realm& realm) { return *realm.m_shared_group; }
|
||||
static ClientHistory& get_history(Realm& realm) { return *realm.m_history; }
|
||||
|
||||
// AsyncQuery needs to be able to access the owning coordinator to
|
||||
// wake up the worker thread when a callback is added, and
|
||||
|
@ -158,17 +157,16 @@ namespace realm {
|
|||
};
|
||||
|
||||
static void open_with_config(const Config& config,
|
||||
std::unique_ptr<ClientHistory>& history,
|
||||
std::unique_ptr<Replication>& history,
|
||||
std::unique_ptr<SharedGroup>& shared_group,
|
||||
std::unique_ptr<Group>& read_only_group);
|
||||
|
||||
private:
|
||||
Config m_config;
|
||||
std::thread::id m_thread_id = std::this_thread::get_id();
|
||||
bool m_in_transaction = false;
|
||||
bool m_auto_refresh = true;
|
||||
|
||||
std::unique_ptr<ClientHistory> m_history;
|
||||
std::unique_ptr<Replication> m_history;
|
||||
std::unique_ptr<SharedGroup> m_shared_group;
|
||||
std::unique_ptr<Group> m_read_only_group;
|
||||
|
||||
|
|
Loading…
Reference in New Issue