From 60720614634b16109c330a2ded3e51438dbd7560 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 19 Apr 2016 14:41:33 -0700 Subject: [PATCH 01/12] api to check if object has been deleted --- src/js_realm.hpp | 14 ++++++++++++++ src/object-store/src/object_accessor.hpp | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/js_realm.hpp b/src/js_realm.hpp index b3cb1351..1c01207e 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -138,6 +138,7 @@ class Realm { static void create(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void delete_one(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void delete_all(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); + static void is_object_valid(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void write(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void add_listener(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void remove_listener(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); @@ -212,6 +213,7 @@ struct RealmClass : ClassDefinition { {"create", wrap}, {"delete", wrap}, {"deleteAll", wrap}, + {"isValid", wrap}, {"write", wrap}, {"addListener", wrap}, {"removeListener", wrap}, @@ -454,6 +456,18 @@ void Realm::delete_all(ContextType ctx, ObjectType this_object, size_t argc, ObjectStore::table_for_object_type(realm->read_group(), objectSchema.name)->clear(); } } + +template +void Realm::is_object_valid(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { + validate_argument_count(argc, 0); + + ObjectType arg = Value::validated_to_object(ctx, arguments[0]); + if (!Object::template is_instance>(ctx, arg)) { + throw std::runtime_error("Argument to Realm.isValid must be a 'RealmObject'"); + } + auto object = get_internal>(arg); + return_value.set(object->is_valid()); +} template void Realm::write(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { diff --git a/src/object-store/src/object_accessor.hpp b/src/object-store/src/object_accessor.hpp index 61ef0a1d..c27d7a52 100644 --- a/src/object-store/src/object_accessor.hpp +++ b/src/object-store/src/object_accessor.hpp @@ -47,6 +47,8 @@ namespace realm { SharedRealm realm() { return m_realm; } const ObjectSchema &get_object_schema() { return *m_object_schema; } Row row() { return m_row; } + + bool is_valid() { return m_row.is_attached(); } private: SharedRealm m_realm; @@ -57,6 +59,8 @@ namespace realm { inline void set_property_value_impl(ContextType ctx, const Property &property, ValueType value, bool try_update); template inline ValueType get_property_value_impl(ContextType ctx, const Property &property); + + inline void verify_attached(); }; // @@ -109,6 +113,13 @@ namespace realm { static Mixed to_mixed(ContextType ctx, ValueType &val) { throw std::runtime_error("'Any' type is unsupported"); } }; + class InvalidatedObjectException : public std::runtime_error + { + public: + InvalidatedObjectException(const std::string object_type, const std::string message) : std::runtime_error(message), object_type(object_type) {} + const std::string object_type; + }; + class InvalidPropertyException : public std::runtime_error { public: @@ -137,6 +148,8 @@ namespace realm { template inline void Object::set_property_value(ContextType ctx, std::string prop_name, ValueType value, bool try_update) { + verify_attached(); + const Property *prop = m_object_schema->property_for_name(prop_name); if (!prop) { throw InvalidPropertyException(m_object_schema->name, prop_name, @@ -148,6 +161,8 @@ namespace realm { template inline ValueType Object::get_property_value(ContextType ctx, std::string prop_name) { + verify_attached(); + const Property *prop = m_object_schema->property_for_name(prop_name); if (!prop) { throw InvalidPropertyException(m_object_schema->name, prop_name, @@ -324,6 +339,13 @@ namespace realm { } return object; } + + inline void Object::verify_attached() { + if (!m_row.is_attached()) { + throw InvalidatedObjectException("Accessing object of type " + m_object_schema->name + " which has been deleted", + m_object_schema->name); + } + } // // List implementation From 3509caedd5dcb6d2920c596fe4a4508466e2f749 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 19 Apr 2016 16:03:18 -0700 Subject: [PATCH 02/12] bugfix for empty results, fix for realm.isValid --- lib/browser/index.js | 1 + src/js_realm.hpp | 11 ++++++----- src/js_types.hpp | 2 +- src/jsc/jsc_class.hpp | 6 ++++++ src/node/node_class.hpp | 6 ++++++ src/object-store/src/object_accessor.hpp | 5 +++-- tests/js/results-tests.js | 2 ++ 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/browser/index.js b/lib/browser/index.js index 1830df93..175fe939 100644 --- a/lib/browser/index.js +++ b/lib/browser/index.js @@ -151,6 +151,7 @@ export default class Realm { // Non-mutating methods: util.createMethods(Realm.prototype, objectTypes.REALM, [ 'close', + 'isValid', ]); // Mutating methods: diff --git a/src/js_realm.hpp b/src/js_realm.hpp index 1c01207e..a3b520ab 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -459,14 +459,15 @@ void Realm::delete_all(ContextType ctx, ObjectType this_object, size_t argc, template void Realm::is_object_valid(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { - validate_argument_count(argc, 0); + validate_argument_count(argc, 1); ObjectType arg = Value::validated_to_object(ctx, arguments[0]); - if (!Object::template is_instance>(ctx, arg)) { - throw std::runtime_error("Argument to Realm.isValid must be a 'RealmObject'"); + if (Object::template is_instance>(ctx, arg)) { + return_value.set(get_internal>(arg)->is_valid()); + } + else { + throw std::runtime_error("Object is not a Realm Object"); } - auto object = get_internal>(arg); - return_value.set(object->is_valid()); } template diff --git a/src/js_types.hpp b/src/js_types.hpp index 2147039e..0f2af00e 100644 --- a/src/js_types.hpp +++ b/src/js_types.hpp @@ -104,7 +104,7 @@ struct Value { static return_t validated_to_##type(ContextType ctx, const ValueType &value, const char *name = nullptr) { \ if (!is_##type(ctx, value)) { \ std::string prefix = name ? std::string("'") + name + "'" : "JS value"; \ - throw std::invalid_argument(prefix + " must be: " #type); \ + throw std::invalid_argument(prefix + " must be of type: " #type); \ } \ return to_##type(ctx, value); \ } diff --git a/src/jsc/jsc_class.hpp b/src/jsc/jsc_class.hpp index f60080f6..b37040c4 100644 --- a/src/jsc/jsc_class.hpp +++ b/src/jsc/jsc_class.hpp @@ -23,6 +23,8 @@ #include "js_class.hpp" #include "js_util.hpp" +#include "results.hpp" + namespace realm { namespace jsc { @@ -276,6 +278,10 @@ inline JSValueRef ObjectWrap::get_property(JSContextRef ctx, JSObject // Out-of-bounds index getters should just return undefined in JS. return Value::from_undefined(ctx); } + catch (Results::OutOfBoundsIndexException &) { + // Out-of-bounds index getters should just return undefined in JS. + return Value::from_undefined(ctx); + } catch (std::invalid_argument &) { // Property is not a number. } diff --git a/src/node/node_class.hpp b/src/node/node_class.hpp index 757e6228..596d55a6 100644 --- a/src/node/node_class.hpp +++ b/src/node/node_class.hpp @@ -23,6 +23,8 @@ #include "js_class.hpp" #include "js_util.hpp" +#include "results.hpp" + namespace realm { namespace node { @@ -342,6 +344,10 @@ void wrap(uint32_t index, Nan::NAN_INDEX_GETTER_ARGS_TYPE info) { // Out-of-bounds index getters should just return undefined in JS. return_value.set_undefined(); } + catch (Results::OutOfBoundsIndexException &) { + // Out-of-bounds index getters should just return undefined in JS. + return_value.set_undefined(); + } catch (std::exception &e) { Nan::ThrowError(node::Exception::value(isolate, e)); } diff --git a/src/object-store/src/object_accessor.hpp b/src/object-store/src/object_accessor.hpp index c27d7a52..fc86a62c 100644 --- a/src/object-store/src/object_accessor.hpp +++ b/src/object-store/src/object_accessor.hpp @@ -342,8 +342,9 @@ namespace realm { inline void Object::verify_attached() { if (!m_row.is_attached()) { - throw InvalidatedObjectException("Accessing object of type " + m_object_schema->name + " which has been deleted", - m_object_schema->name); + throw InvalidatedObjectException(m_object_schema->name, + "Accessing object of type " + m_object_schema->name + " which has been deleted" + ); } } diff --git a/tests/js/results-tests.js b/tests/js/results-tests.js index 3470a267..4c31eb28 100644 --- a/tests/js/results-tests.js +++ b/tests/js/results-tests.js @@ -50,6 +50,8 @@ module.exports = BaseTest.extend({ testResultsSubscript: function() { var realm = new Realm({schema: [schemas.PersonObject]}); + TestCase.assertEqual(realm.objects('PersonObject')[0], undefined); + realm.write(function() { realm.create('PersonObject', {name: 'name1', age: 1}); realm.create('PersonObject', {name: 'name2', age: 2}); From 78cb44b1a10df77015c979e4c785c111e65e96a7 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 19 Apr 2016 16:07:24 -0700 Subject: [PATCH 03/12] add test for isValid --- tests/js/realm-tests.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/js/realm-tests.js b/tests/js/realm-tests.js index 3e6aec72..ecd130e2 100644 --- a/tests/js/realm-tests.js +++ b/tests/js/realm-tests.js @@ -516,6 +516,22 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(realm.objects('IntPrimaryObject').length, 0); }, + testIsValid: function() { + var realm = new Realm({schema: [schemas.TestObject]}); + var obj; + realm.write(function() { + obj = realm.create('TestObject', {doubleCol: 1}); + TestCase.assertEqual(realm.isValid(obj), true); + realm.delete(obj); + TestCase.assertEqual(realm.isValid(obj), false); + }); + + TestCase.assertEqual(realm.isValid(obj), false); + TestCase.assertThrows(function() { + obj.doubleCol; + }); + }, + testRealmObjects: function() { var realm = new Realm({schema: [schemas.PersonObject, schemas.DefaultValues, schemas.TestObject]}); From 48e63652950d16a7fa02704c10b8c808173480ed Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 19 Apr 2016 16:09:10 -0700 Subject: [PATCH 04/12] changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79745316..e2611bba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,11 @@ x.x.x Release notes (yyyy-MM-dd) ### Enhancements * Support for queries comparing optional properties to `null` +* `Realm.isValid(object)` has been added to enable checking if an object has been deleted ### Bugfixes -* None +* When accessing an empty Results `undefined` is returned rather than throwing an exception +* Accessing a deleted object throws a javascript exception rather than crashing 0.11.1 Release notes (2016-3-29) ============================================================= From 988f723f4974c3cd16f65eca1e015ad261040b55 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Thu, 21 Apr 2016 13:38:10 -0700 Subject: [PATCH 05/12] remove unnecessary catch block --- src/jsc/jsc_class.hpp | 4 ---- src/node/node_class.hpp | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/jsc/jsc_class.hpp b/src/jsc/jsc_class.hpp index b37040c4..b2750afd 100644 --- a/src/jsc/jsc_class.hpp +++ b/src/jsc/jsc_class.hpp @@ -278,10 +278,6 @@ inline JSValueRef ObjectWrap::get_property(JSContextRef ctx, JSObject // Out-of-bounds index getters should just return undefined in JS. return Value::from_undefined(ctx); } - catch (Results::OutOfBoundsIndexException &) { - // Out-of-bounds index getters should just return undefined in JS. - return Value::from_undefined(ctx); - } catch (std::invalid_argument &) { // Property is not a number. } diff --git a/src/node/node_class.hpp b/src/node/node_class.hpp index 596d55a6..be042a95 100644 --- a/src/node/node_class.hpp +++ b/src/node/node_class.hpp @@ -344,10 +344,6 @@ void wrap(uint32_t index, Nan::NAN_INDEX_GETTER_ARGS_TYPE info) { // Out-of-bounds index getters should just return undefined in JS. return_value.set_undefined(); } - catch (Results::OutOfBoundsIndexException &) { - // Out-of-bounds index getters should just return undefined in JS. - return_value.set_undefined(); - } catch (std::exception &e) { Nan::ThrowError(node::Exception::value(isolate, e)); } From b59784670b9a1aec332ae0407b499963ba649f27 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 26 Apr 2016 16:30:04 -0700 Subject: [PATCH 06/12] create RealmObject class and make isValid a member --- lib/browser/index.js | 1 - lib/browser/objects.js | 10 ++++++++- src/js_realm.hpp | 19 +++-------------- src/js_realm_object.hpp | 17 ++++++++++++++++ src/object-store/src/object_accessor.hpp | 12 +++++------ tests/js/object-tests.js | 26 +++++++++++++++++++++++- tests/js/realm-tests.js | 16 --------------- 7 files changed, 60 insertions(+), 41 deletions(-) diff --git a/lib/browser/index.js b/lib/browser/index.js index 175fe939..1830df93 100644 --- a/lib/browser/index.js +++ b/lib/browser/index.js @@ -151,7 +151,6 @@ export default class Realm { // Non-mutating methods: util.createMethods(Realm.prototype, objectTypes.REALM, [ 'close', - 'isValid', ]); // Mutating methods: diff --git a/lib/browser/objects.js b/lib/browser/objects.js index f0f78220..674023a5 100644 --- a/lib/browser/objects.js +++ b/lib/browser/objects.js @@ -23,10 +23,18 @@ import { getterForProperty, setterForProperty } from './util'; const registeredConstructors = {}; +export default class RealmObject { +} + +// Non-mutating methods: +createMethods(RealmObject.prototype, objectTypes.OBJECT, [ + 'isValid', +]); + export function create(realmId, info) { let schema = info.schema; let constructor = (registeredConstructors[realmId] || {})[schema.name]; - let object = constructor ? Object.create(constructor.prototype) : {}; + let object = Object.create(constructor ? constructor.prototype : RealmObject.prototype); object[keys.realm] = realmId; object[keys.id] = info.id; diff --git a/src/js_realm.hpp b/src/js_realm.hpp index a3b520ab..9b2fa25e 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -138,7 +138,6 @@ class Realm { static void create(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void delete_one(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void delete_all(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); - static void is_object_valid(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void write(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void add_listener(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); static void remove_listener(ContextType, ObjectType, size_t, const ValueType[], ReturnValue &); @@ -213,7 +212,6 @@ struct RealmClass : ClassDefinition { {"create", wrap}, {"delete", wrap}, {"deleteAll", wrap}, - {"isValid", wrap}, {"write", wrap}, {"addListener", wrap}, {"removeListener", wrap}, @@ -233,11 +231,13 @@ inline typename T::Function Realm::create_constructor(ContextType ctx) { FunctionType collection_constructor = ObjectWrap>::create_constructor(ctx); FunctionType list_constructor = ObjectWrap>::create_constructor(ctx); FunctionType results_constructor = ObjectWrap>::create_constructor(ctx); + FunctionType realm_object_constructor = ObjectWrap>::create_constructor(ctx); PropertyAttributes attributes = PropertyAttributes(ReadOnly | DontEnum | DontDelete); Object::set_property(ctx, realm_constructor, "Collection", collection_constructor, attributes); Object::set_property(ctx, realm_constructor, "List", list_constructor, attributes); Object::set_property(ctx, realm_constructor, "Results", results_constructor, attributes); + Object::set_property(ctx, realm_constructor, "RealmObject", realm_object_constructor, attributes); return realm_constructor; } @@ -456,19 +456,6 @@ void Realm::delete_all(ContextType ctx, ObjectType this_object, size_t argc, ObjectStore::table_for_object_type(realm->read_group(), objectSchema.name)->clear(); } } - -template -void Realm::is_object_valid(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { - validate_argument_count(argc, 1); - - ObjectType arg = Value::validated_to_object(ctx, arguments[0]); - if (Object::template is_instance>(ctx, arg)) { - return_value.set(get_internal>(arg)->is_valid()); - } - else { - throw std::runtime_error("Object is not a Realm Object"); - } -} template void Realm::write(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { @@ -484,7 +471,7 @@ void Realm::write(ContextType ctx, ObjectType this_object, size_t argc, const } catch (std::exception &e) { realm->cancel_transaction(); - throw e; + throw; } realm->commit_transaction(); diff --git a/src/js_realm_object.hpp b/src/js_realm_object.hpp index c5df2226..f682c67c 100644 --- a/src/js_realm_object.hpp +++ b/src/js_realm_object.hpp @@ -46,6 +46,8 @@ class RealmObject { static void get_property(ContextType, ObjectType, const String &, ReturnValue &); static bool set_property(ContextType, ObjectType, const String &, ValueType); static std::vector get_property_names(ContextType, ObjectType); + + static void is_valid(ContextType, ObjectType, size_t, const ValueType [], ReturnValue &); }; template @@ -59,8 +61,23 @@ struct RealmObjectClass : ClassDefinition { wrap, wrap, }; + + using ContextType = typename T::Context; + using ObjectType = typename T::Object; + using ValueType = typename T::Value; + using ReturnValue = js::ReturnValue; + + + MethodMap const methods = { + {"isValid", wrap}, + }; }; +template +void RealmObject::is_valid(ContextType ctx, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { + return_value.set(get_internal>(this_object)->is_valid()); +} + template typename T::Object RealmObject::create_instance(ContextType ctx, realm::Object &realm_object) { static String prototype_string = "prototype"; diff --git a/src/object-store/src/object_accessor.hpp b/src/object-store/src/object_accessor.hpp index fc86a62c..9727fe45 100644 --- a/src/object-store/src/object_accessor.hpp +++ b/src/object-store/src/object_accessor.hpp @@ -48,7 +48,7 @@ namespace realm { const ObjectSchema &get_object_schema() { return *m_object_schema; } Row row() { return m_row; } - bool is_valid() { return m_row.is_attached(); } + bool is_valid() const { return m_row.is_attached(); } private: SharedRealm m_realm; @@ -147,9 +147,7 @@ namespace realm { // template inline void Object::set_property_value(ContextType ctx, std::string prop_name, ValueType value, bool try_update) - { - verify_attached(); - + { const Property *prop = m_object_schema->property_for_name(prop_name); if (!prop) { throw InvalidPropertyException(m_object_schema->name, prop_name, @@ -161,8 +159,6 @@ namespace realm { template inline ValueType Object::get_property_value(ContextType ctx, std::string prop_name) { - verify_attached(); - const Property *prop = m_object_schema->property_for_name(prop_name); if (!prop) { throw InvalidPropertyException(m_object_schema->name, prop_name, @@ -176,6 +172,8 @@ namespace realm { { using Accessor = NativeAccessor; + verify_attached(); + if (!m_realm->is_in_transaction()) { throw MutationOutsideTransactionException("Can only set property values within a transaction."); } @@ -240,6 +238,8 @@ namespace realm { { using Accessor = NativeAccessor; + verify_attached(); + size_t column = property.table_column; if (property.is_nullable && m_row.is_null(column)) { return Accessor::null_value(ctx); diff --git a/tests/js/object-tests.js b/tests/js/object-tests.js index addc067a..2edf89e6 100644 --- a/tests/js/object-tests.js +++ b/tests/js/object-tests.js @@ -431,5 +431,29 @@ module.exports = BaseTest.extend({ object.dataCol = [1]; }); }); - } + }, + + testObjectConstructor: function() { + var realm = new Realm({schema: [schemas.TestObject]}); + realm.write(function() { + var obj = realm.create('TestObject', {doubleCol: 1}); + TestCase.assertTrue(obj instanceof Realm.RealmObject); + }); + }, + + testIsValid: function() { + var realm = new Realm({schema: [schemas.TestObject]}); + var obj; + realm.write(function() { + obj = realm.create('TestObject', {doubleCol: 1}); + TestCase.assertEqual(obj.isValid(), true); + realm.delete(obj); + TestCase.assertEqual(obj.isValid(), false); + }); + + TestCase.assertEqual(obj.isValid(), false); + TestCase.assertThrows(function() { + obj.doubleCol; + }); + }, }); diff --git a/tests/js/realm-tests.js b/tests/js/realm-tests.js index ecd130e2..3e6aec72 100644 --- a/tests/js/realm-tests.js +++ b/tests/js/realm-tests.js @@ -516,22 +516,6 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(realm.objects('IntPrimaryObject').length, 0); }, - testIsValid: function() { - var realm = new Realm({schema: [schemas.TestObject]}); - var obj; - realm.write(function() { - obj = realm.create('TestObject', {doubleCol: 1}); - TestCase.assertEqual(realm.isValid(obj), true); - realm.delete(obj); - TestCase.assertEqual(realm.isValid(obj), false); - }); - - TestCase.assertEqual(realm.isValid(obj), false); - TestCase.assertThrows(function() { - obj.doubleCol; - }); - }, - testRealmObjects: function() { var realm = new Realm({schema: [schemas.PersonObject, schemas.DefaultValues, schemas.TestObject]}); From 591dce8051b483691dc98444d4242bf1f0fa46b6 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 26 Apr 2016 16:53:50 -0700 Subject: [PATCH 07/12] one fix for chrome debug mode --- lib/browser/objects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/objects.js b/lib/browser/objects.js index 674023a5..8f54783f 100644 --- a/lib/browser/objects.js +++ b/lib/browser/objects.js @@ -19,7 +19,7 @@ 'use strict'; import { keys } from './constants'; -import { getterForProperty, setterForProperty } from './util'; +import { getterForProperty, setterForProperty, createMethods } from './util'; const registeredConstructors = {}; From 27d973151fba00fbbce58a343248cad2553a3b68 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 26 Apr 2016 16:59:03 -0700 Subject: [PATCH 08/12] pr fixes --- src/js_realm.hpp | 2 +- src/js_realm_object.hpp | 10 ++++------ src/jsc/jsc_class.hpp | 2 -- src/node/node_class.hpp | 2 -- src/object-store/src/object_accessor.hpp | 4 ++-- tests/js/object-tests.js | 2 +- 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/js_realm.hpp b/src/js_realm.hpp index 9b2fa25e..ebba1bae 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -237,7 +237,7 @@ inline typename T::Function Realm::create_constructor(ContextType ctx) { Object::set_property(ctx, realm_constructor, "Collection", collection_constructor, attributes); Object::set_property(ctx, realm_constructor, "List", list_constructor, attributes); Object::set_property(ctx, realm_constructor, "Results", results_constructor, attributes); - Object::set_property(ctx, realm_constructor, "RealmObject", realm_object_constructor, attributes); + Object::set_property(ctx, realm_constructor, "Object", realm_object_constructor, attributes); return realm_constructor; } diff --git a/src/js_realm_object.hpp b/src/js_realm_object.hpp index f682c67c..16ce879b 100644 --- a/src/js_realm_object.hpp +++ b/src/js_realm_object.hpp @@ -52,6 +52,10 @@ class RealmObject { template struct RealmObjectClass : ClassDefinition { + using ContextType = typename T::Context; + using ObjectType = typename T::Object; + using ValueType = typename T::Value; + using ReturnValue = js::ReturnValue; using RealmObject = js::RealmObject; const std::string name = "RealmObject"; @@ -61,12 +65,6 @@ struct RealmObjectClass : ClassDefinition { wrap, wrap, }; - - using ContextType = typename T::Context; - using ObjectType = typename T::Object; - using ValueType = typename T::Value; - using ReturnValue = js::ReturnValue; - MethodMap const methods = { {"isValid", wrap}, diff --git a/src/jsc/jsc_class.hpp b/src/jsc/jsc_class.hpp index b2750afd..f60080f6 100644 --- a/src/jsc/jsc_class.hpp +++ b/src/jsc/jsc_class.hpp @@ -23,8 +23,6 @@ #include "js_class.hpp" #include "js_util.hpp" -#include "results.hpp" - namespace realm { namespace jsc { diff --git a/src/node/node_class.hpp b/src/node/node_class.hpp index be042a95..757e6228 100644 --- a/src/node/node_class.hpp +++ b/src/node/node_class.hpp @@ -23,8 +23,6 @@ #include "js_class.hpp" #include "js_util.hpp" -#include "results.hpp" - namespace realm { namespace node { diff --git a/src/object-store/src/object_accessor.hpp b/src/object-store/src/object_accessor.hpp index 9727fe45..3af25193 100644 --- a/src/object-store/src/object_accessor.hpp +++ b/src/object-store/src/object_accessor.hpp @@ -47,7 +47,7 @@ namespace realm { SharedRealm realm() { return m_realm; } const ObjectSchema &get_object_schema() { return *m_object_schema; } Row row() { return m_row; } - + bool is_valid() const { return m_row.is_attached(); } private: @@ -147,7 +147,7 @@ namespace realm { // template inline void Object::set_property_value(ContextType ctx, std::string prop_name, ValueType value, bool try_update) - { + { const Property *prop = m_object_schema->property_for_name(prop_name); if (!prop) { throw InvalidPropertyException(m_object_schema->name, prop_name, diff --git a/tests/js/object-tests.js b/tests/js/object-tests.js index 2edf89e6..db41c5dd 100644 --- a/tests/js/object-tests.js +++ b/tests/js/object-tests.js @@ -437,7 +437,7 @@ module.exports = BaseTest.extend({ var realm = new Realm({schema: [schemas.TestObject]}); realm.write(function() { var obj = realm.create('TestObject', {doubleCol: 1}); - TestCase.assertTrue(obj instanceof Realm.RealmObject); + TestCase.assertTrue(obj instanceof Realm.Object); }); }, From 785e57eb47a3e59b6e52cd313ce6f84eba88335a Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 26 Apr 2016 17:08:00 -0700 Subject: [PATCH 09/12] another fix for chrome debug mode --- lib/browser/objects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/objects.js b/lib/browser/objects.js index 8f54783f..e9ce6346 100644 --- a/lib/browser/objects.js +++ b/lib/browser/objects.js @@ -18,7 +18,7 @@ 'use strict'; -import { keys } from './constants'; +import { keys, objectTypes } from './constants'; import { getterForProperty, setterForProperty, createMethods } from './util'; const registeredConstructors = {}; From ca622f27b7b9f527fa455a5e97c542e0bea54435 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 26 Apr 2016 17:14:15 -0700 Subject: [PATCH 10/12] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2611bba..87a61d9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ x.x.x Release notes (yyyy-MM-dd) ### Enhancements * Support for queries comparing optional properties to `null` -* `Realm.isValid(object)` has been added to enable checking if an object has been deleted +* `object.isValid()` has been added to enable checking if an object has been deleted ### Bugfixes * When accessing an empty Results `undefined` is returned rather than throwing an exception From df14c7760d52694c84fa874aa9e139ecdc6fd56f Mon Sep 17 00:00:00 2001 From: Scott Kyle Date: Tue, 26 Apr 2016 17:32:55 -0700 Subject: [PATCH 11/12] Fix Realm.Object in Chrome debug mode --- lib/browser/index.js | 13 ++++++++----- lib/browser/objects.js | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/browser/index.js b/lib/browser/index.js index 1830df93..64ca70b7 100644 --- a/lib/browser/index.js +++ b/lib/browser/index.js @@ -23,7 +23,7 @@ import { keys, propTypes, objectTypes } from './constants'; import Collection, * as collections from './collections'; import List, { createList } from './lists'; import Results, { createResults } from './results'; -import * as objects from './objects'; +import RealmObject, { createObject, registerConstructors, typeForConstructor } from './objects'; import * as rpc from './rpc'; import * as util from './util'; @@ -32,7 +32,7 @@ const listenersKey = Symbol(); rpc.registerTypeConverter(objectTypes.LIST, createList); rpc.registerTypeConverter(objectTypes.RESULTS, createResults); -rpc.registerTypeConverter(objectTypes.OBJECT, objects.create); +rpc.registerTypeConverter(objectTypes.OBJECT, createObject); export default class Realm { constructor(config) { @@ -62,7 +62,7 @@ export default class Realm { let realmId = rpc.createRealm(Array.from(arguments)); - objects.registerConstructors(realmId, constructors); + registerConstructors(realmId, constructors); this[keys.id] = realmId; this[keys.realm] = realmId; @@ -79,7 +79,7 @@ export default class Realm { create(type, ...args) { if (typeof type == 'function') { - type = objects.typeForConstructor(this[keys.realm], type); + type = typeForConstructor(this[keys.realm], type); } let method = util.createMethod(objectTypes.REALM, 'create', true); @@ -88,7 +88,7 @@ export default class Realm { objects(type, ...args) { if (typeof type == 'function') { - type = objects.typeForConstructor(this[keys.realm], type); + type = typeForConstructor(this[keys.realm], type); } let method = util.createMethod(objectTypes.REALM, 'objects'); @@ -169,6 +169,9 @@ Object.defineProperties(Realm, { Results: { value: Results, }, + Object: { + value: RealmObject, + }, defaultPath: { get: util.getterForProperty('defaultPath'), set: util.setterForProperty('defaultPath'), diff --git a/lib/browser/objects.js b/lib/browser/objects.js index e9ce6346..30ed84c2 100644 --- a/lib/browser/objects.js +++ b/lib/browser/objects.js @@ -31,10 +31,10 @@ createMethods(RealmObject.prototype, objectTypes.OBJECT, [ 'isValid', ]); -export function create(realmId, info) { +export function createObject(realmId, info) { let schema = info.schema; let constructor = (registeredConstructors[realmId] || {})[schema.name]; - let object = Object.create(constructor ? constructor.prototype : RealmObject.prototype); + let object = Object.create(constructor ? constructor.prototype : RealmObject.prototype); object[keys.realm] = realmId; object[keys.id] = info.id; From 588bbc327ade1d0f547078e90bc83b65ded2df48 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 26 Apr 2016 17:40:56 -0700 Subject: [PATCH 12/12] remove un-needed usings --- src/js_realm_object.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/js_realm_object.hpp b/src/js_realm_object.hpp index 16ce879b..d9c0bbde 100644 --- a/src/js_realm_object.hpp +++ b/src/js_realm_object.hpp @@ -52,10 +52,6 @@ class RealmObject { template struct RealmObjectClass : ClassDefinition { - using ContextType = typename T::Context; - using ObjectType = typename T::Object; - using ValueType = typename T::Value; - using ReturnValue = js::ReturnValue; using RealmObject = js::RealmObject; const std::string name = "RealmObject";