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,6 +57,7 @@ struct ListClass : ClassDefinition<T, realm::List, CollectionClass<T>> {
static void snapshot(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 is_valid(ContextType, ObjectType, size_t, const ValueType [], ReturnValue &);
std::string const name = "List";
@ -69,6 +70,7 @@ struct ListClass : ClassDefinition<T, realm::List, CollectionClass<T>> {
{"snapshot", wrap<snapshot>},
{"filtered", wrap<filtered>},
{"sorted", wrap<sorted>},
{"isValid", wrap<is_valid>},
};
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));
}
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
} // realm

View File

@ -247,14 +247,14 @@ inline typename T::Function RealmClass<T>::create_constructor(ContextType ctx) {
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 &&
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
for (auto& object_schema : *realm->config().schema) {
auto table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);
for (auto& property : object_schema.properties) {
if (property.type == PropertyTypeDate) {
if (property.type == realm::PropertyType::Date) {
if (!realm->is_in_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 filtered(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";
@ -62,6 +63,7 @@ struct ResultsClass : ClassDefinition<T, realm::Results, CollectionClass<T>> {
{"snapshot", wrap<snapshot>},
{"filtered", wrap<filtered>},
{"sorted", wrap<sorted>},
{"isValid", wrap<is_valid>},
};
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));
}
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
} // 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
{
if (m_realm)
m_realm->verify_thread();
if (m_table && !m_table->is_attached())
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())
if (!is_valid())
throw InvalidatedException();
}

View File

@ -193,6 +193,9 @@ public:
static void set_table_view(Results& results, TableView&& tv);
};
// Returns if this Results class is still valid
bool is_valid() const;
private:
SharedRealm m_realm;
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() {
var realm = new Realm({schema: [schemas.TestObject]});
var testObjects = realm.objects('TestObject');
var filteredObjects = testObjects.filtered('doubleCol > 1');
var sortedObjects = testObjects.sorted('doubleCol');
var snapshotObjects = testObjects.snapshot();
realm.write(function() {
for (var i = 10; i > 0; i--) {
realm.create('TestObject', [i]);
}
});
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 = new Realm({
schemaVersion: 1,
schema: [schemas.TestObject, schemas.BasicTypes]
});
[
testObjects,
filteredObjects,
sortedObjects,
snapshotObjects,
].forEach(function(objects) {
resultsVariants.forEach(function(objects) {
TestCase.assertEqual(objects.isValid(), false);
TestCase.assertThrows(function() { objects[0]; });
TestCase.assertThrows(function() { objects.filtered('doubleCol < 42'); });
TestCase.assertThrows(function() { objects.sorted('doubleCol', true); });
TestCase.assertThrows(function() { objects.snapshot(); });
});
}
},
});