Fix crash and other errors with Results snapshots

When deleteAll() is called on a Realm, it calls clear() on all of its Tables, which seems to not update TableViews unless they are synced. The is_row_attached(row_ndx) method still returns true otherwise. A workaround is here until that is fixed.

Fixes #434
This commit is contained in:
Scott Kyle 2016-05-20 13:42:17 -07:00
parent 3b6ee92224
commit 2672cd901f
1 changed files with 14 additions and 5 deletions

View File

@ -96,7 +96,7 @@ bool Results::is_valid() const
m_realm->verify_thread(); m_realm->verify_thread();
if (m_table && !m_table->is_attached()) if (m_table && !m_table->is_attached())
return false; return false;
if (m_mode == Mode::TableView && (!m_table_view.is_attached() || m_table_view.depends_on_deleted_object())) if (m_mode == Mode::TableView && (!m_table_view.is_attached() || (m_live && m_table_view.depends_on_deleted_object())))
return false; return false;
if (m_mode == Mode::LinkView && !m_link_view->is_attached()) if (m_mode == Mode::LinkView && !m_link_view->is_attached())
return false; return false;
@ -121,8 +121,8 @@ void Results::set_live(bool live)
{ {
validate_read(); validate_read();
if (!live && m_mode == Mode::Table) { if (!live && (m_mode == Mode::Table || m_mode == Mode::LinkView)) {
m_query = m_table->where(); m_query = get_query();
m_mode = Mode::Query; m_mode = Mode::Query;
} }
@ -173,7 +173,8 @@ RowExpr Results::get(size_t row_ndx)
update_tableview(); update_tableview();
if (row_ndx >= m_table_view.size()) if (row_ndx >= m_table_view.size())
break; break;
if (!m_live && !m_table_view.is_row_attached(row_ndx)) // If clear() was called on the underlying Table, then is_row_attached(row_ndx) will still return true.
if (!m_live && (m_table_view.get_parent().is_empty() || !m_table_view.is_row_attached(row_ndx)))
return {}; return {};
return m_table_view.get(row_ndx); return m_table_view.get(row_ndx);
} }
@ -392,7 +393,15 @@ void Results::clear()
case Mode::TableView: case Mode::TableView:
validate_write(); validate_write();
update_tableview(); update_tableview();
if (m_live) {
m_table_view.clear(RemoveMode::unordered); m_table_view.clear(RemoveMode::unordered);
}
else {
// Copy the TableView because a non-live Results shouldn't have let its size() change.
TableView table_view_copy = m_table_view;
table_view_copy.clear(RemoveMode::unordered);
}
break; break;
case Mode::LinkView: case Mode::LinkView:
validate_write(); validate_write();