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]});