add isValid methods to results and list

This commit is contained in:
Ari Lazier 2016-05-16 16:01:14 -07:00
parent 6af98acd11
commit fd25afe214
7 changed files with 75 additions and 20 deletions

View File

@ -57,7 +57,8 @@ struct ListClass : ClassDefinition<T, realm::List, CollectionClass<T>> {
static void snapshot(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void snapshot(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void filtered(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void filtered(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void sorted(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void sorted(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void is_valid(ContextType, ObjectType, size_t, const ValueType [], ReturnValue &);
std::string const name = "List"; std::string const name = "List";
MethodMap<T> const methods = { MethodMap<T> const methods = {
@ -69,6 +70,7 @@ struct ListClass : ClassDefinition<T, realm::List, CollectionClass<T>> {
{"snapshot", wrap<snapshot>}, {"snapshot", wrap<snapshot>},
{"filtered", wrap<filtered>}, {"filtered", wrap<filtered>},
{"sorted", wrap<sorted>}, {"sorted", wrap<sorted>},
{"isValid", wrap<is_valid>},
}; };
PropertyMap<T> const properties = { PropertyMap<T> const properties = {
@ -224,5 +226,10 @@ void ListClass<T>::sorted(ContextType ctx, ObjectType this_object, size_t argc,
return_value.set(ResultsClass<T>::create_sorted(ctx, *list, argc, arguments)); return_value.set(ResultsClass<T>::create_sorted(ctx, *list, argc, arguments));
} }
template<typename T>
void ListClass<T>::is_valid(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
return_value.set(get_internal<T, ListClass<T>>(this_object)->is_valid());
}
} // js } // js
} // realm } // realm

View File

@ -247,14 +247,14 @@ inline typename T::Function RealmClass<T>::create_constructor(ContextType ctx) {
return realm_constructor; return realm_constructor;
} }
static void convert_outdated_datetime_columns(const SharedRealm &realm) { static inline void convert_outdated_datetime_columns(const SharedRealm &realm) {
if (realm->config().upgrade_initial_version != realm->config().upgrade_final_version && if (realm->config().upgrade_initial_version != realm->config().upgrade_final_version &&
realm->config().upgrade_initial_version < 5) { realm->config().upgrade_initial_version < 5) {
// any versions earlier than file format 5 are stored as milliseconds and need to be converted to the new format // any versions earlier than file format 5 are stored as milliseconds and need to be converted to the new format
for (auto& object_schema : *realm->config().schema) { for (auto& object_schema : *realm->config().schema) {
auto table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name); auto table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);
for (auto& property : object_schema.properties) { for (auto& property : object_schema.properties) {
if (property.type == PropertyTypeDate) { if (property.type == realm::PropertyType::Date) {
if (!realm->is_in_transaction()) { if (!realm->is_in_transaction()) {
realm->begin_transaction(); realm->begin_transaction();
} }

View File

@ -55,6 +55,7 @@ struct ResultsClass : ClassDefinition<T, realm::Results, CollectionClass<T>> {
static void snapshot(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void snapshot(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void filtered(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void filtered(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void sorted(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void sorted(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void is_valid(ContextType, ObjectType, size_t, const ValueType [], ReturnValue &);
std::string const name = "Results"; std::string const name = "Results";
@ -62,6 +63,7 @@ struct ResultsClass : ClassDefinition<T, realm::Results, CollectionClass<T>> {
{"snapshot", wrap<snapshot>}, {"snapshot", wrap<snapshot>},
{"filtered", wrap<filtered>}, {"filtered", wrap<filtered>},
{"sorted", wrap<sorted>}, {"sorted", wrap<sorted>},
{"isValid", wrap<is_valid>},
}; };
PropertyMap<T> const properties = { PropertyMap<T> const properties = {
@ -233,5 +235,10 @@ void ResultsClass<T>::sorted(ContextType ctx, ObjectType this_object, size_t arg
return_value.set(create_sorted(ctx, *results, argc, arguments)); return_value.set(create_sorted(ctx, *results, argc, arguments));
} }
template<typename T>
void ResultsClass<T>::is_valid(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
return_value.set(get_internal<T, ResultsClass<T>>(this_object)->is_valid());
}
} // js } // js
} // realm } // realm

View File

@ -90,15 +90,23 @@ Results::~Results()
} }
} }
bool Results::is_valid() const
{
if (m_table && !m_table->is_attached())
return false;
if (m_mode == Mode::TableView && (!m_table_view.is_attached() || m_table_view.depends_on_deleted_object()))
return false;
if (m_mode == Mode::LinkView && !m_link_view->is_attached())
return false;
return true;
}
void Results::validate_read() const void Results::validate_read() const
{ {
if (m_realm) if (m_realm)
m_realm->verify_thread(); m_realm->verify_thread();
if (m_table && !m_table->is_attached()) if (!is_valid())
throw InvalidatedException();
if (m_mode == Mode::TableView && (!m_table_view.is_attached() || m_table_view.depends_on_deleted_object()))
throw InvalidatedException();
if (m_mode == Mode::LinkView && !m_link_view->is_attached())
throw InvalidatedException(); throw InvalidatedException();
} }

View File

@ -193,6 +193,9 @@ public:
static void set_table_view(Results& results, TableView&& tv); static void set_table_view(Results& results, TableView&& tv);
}; };
// Returns if this Results class is still valid
bool is_valid() const;
private: private:
SharedRealm m_realm; SharedRealm m_realm;
const ObjectSchema *m_object_schema; const ObjectSchema *m_object_schema;

View File

@ -627,4 +627,25 @@ module.exports = BaseTest.extend({
}); });
}); });
}, },
testIsValid: function() {
var realm = new Realm({schema: [schemas.PersonObject, schemas.PersonList]});
var object;
var list;
realm.write(function() {
object = realm.create('PersonList', {list: [
{name: 'Ari', age: 10},
{name: 'Tim', age: 11},
{name: 'Bjarne', age: 12},
]});
list = object.list;
TestCase.assertEqual(list.isValid(), true);
realm.delete(object);
});
TestCase.assertEqual(list.isValid(), false);
TestCase.assertThrows(function() {
list.length;
});
},
}); });

View File

@ -285,28 +285,37 @@ module.exports = BaseTest.extend({
testResultsInvalidation: function() { testResultsInvalidation: function() {
var realm = new Realm({schema: [schemas.TestObject]}); var realm = new Realm({schema: [schemas.TestObject]});
var testObjects = realm.objects('TestObject'); realm.write(function() {
var filteredObjects = testObjects.filtered('doubleCol > 1'); for (var i = 10; i > 0; i--) {
var sortedObjects = testObjects.sorted('doubleCol'); realm.create('TestObject', [i]);
var snapshotObjects = testObjects.snapshot(); }
});
var resultsVariants = [
realm.objects('TestObject'),
realm.objects('TestObject').filtered('doubleCol > 1'),
realm.objects('TestObject').filtered('doubleCol > 1').sorted('doubleCol'),
realm.objects('TestObject').filtered('doubleCol > 1').snapshot()
];
// test isValid
resultsVariants.forEach(function(objects) {
TestCase.assertEqual(objects.isValid(), true);
});
// close and test invalidated accessors
realm.close(); realm.close();
realm = new Realm({ realm = new Realm({
schemaVersion: 1, schemaVersion: 1,
schema: [schemas.TestObject, schemas.BasicTypes] schema: [schemas.TestObject, schemas.BasicTypes]
}); });
[ resultsVariants.forEach(function(objects) {
testObjects, TestCase.assertEqual(objects.isValid(), false);
filteredObjects,
sortedObjects,
snapshotObjects,
].forEach(function(objects) {
TestCase.assertThrows(function() { objects[0]; }); TestCase.assertThrows(function() { objects[0]; });
TestCase.assertThrows(function() { objects.filtered('doubleCol < 42'); }); TestCase.assertThrows(function() { objects.filtered('doubleCol < 42'); });
TestCase.assertThrows(function() { objects.sorted('doubleCol', true); }); TestCase.assertThrows(function() { objects.sorted('doubleCol', true); });
TestCase.assertThrows(function() { objects.snapshot(); }); TestCase.assertThrows(function() { objects.snapshot(); });
}); });
} },
}); });