From dc0839772f417024b840f385030f09870ba5bd69 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Fri, 14 Aug 2015 09:47:33 -0700 Subject: [PATCH] add Realm.delete --- src/RJSObject.mm | 3 +- src/RJSRealm.mm | 75 +++++++++++++++++++++++++++++++-------------- src/RJSUtil.hpp | 1 + src/RJSUtil.mm | 5 +++ tests/RealmTests.js | 29 ++++++++++++++++++ 5 files changed, 88 insertions(+), 25 deletions(-) diff --git a/src/RJSObject.mm b/src/RJSObject.mm index c734b957..0429932d 100644 --- a/src/RJSObject.mm +++ b/src/RJSObject.mm @@ -169,9 +169,8 @@ template<> size_t RJSAccessor::to_object_index(JSContextRef ctx, SharedRealm &re return RJSGetInternal(object)->row.get_index(); } - static JSStringRef arrayString = JSStringCreateWithUTF8CString("Array"); ObjectSchema &object_schema = realm->config().schema->at(prop.object_type); - if (RJSIsValueObjectOfType(ctx, object, arrayString)) { + if (RJSIsValueArray(ctx, object)) { object = RJSDictForPropertyArray(ctx, object_schema, object); } diff --git a/src/RJSRealm.mm b/src/RJSRealm.mm index c2df7a42..a2712777 100644 --- a/src/RJSRealm.mm +++ b/src/RJSRealm.mm @@ -211,13 +211,8 @@ JSValueRef RealmCreateObject(JSContextRef ctx, JSObjectRef function, JSObjectRef SharedRealm sharedRealm = *RJSGetInternal(thisObject); ObjectSchema &object_schema = sharedRealm->config().schema->at(className); - JSObjectRef object = JSValueToObject(ctx, arguments[1], jsException); - if (!object) { - return NULL; - } - - static JSStringRef arrayString = JSStringCreateWithUTF8CString("Array"); - if (RJSIsValueObjectOfType(ctx, arguments[1], arrayString)) { + JSObjectRef object = RJSValidatedValueToObject(ctx, arguments[1]); + if (RJSIsValueArray(ctx, arguments[1])) { object = RJSDictForPropertyArray(ctx, object_schema, object); } @@ -231,21 +226,58 @@ JSValueRef RealmCreateObject(JSContextRef ctx, JSObjectRef function, JSObjectRef } } +JSValueRef RealmDelete(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { + try { + RJSValidateArgumentCount(argumentCount, 1); + + if (RJSIsValueArray(ctx, arguments[0])) { + JSObjectRef array = RJSValidatedValueToObject(ctx, arguments[0]); + size_t length = RJSValidatedArrayLength(ctx, array); + for (size_t i = 0; i < length; i++) { + JSValueRef object = RJSValidatedObjectAtIndex(ctx, array, (unsigned int)i); + RealmDelete(ctx, function, thisObject, 1, &object, jsException); + } + return NULL; + } + + if (!JSValueIsObjectOfClass(ctx, arguments[0], RJSObjectClass())) { + throw std::runtime_error("Argument to 'delete' must be a Realm object."); + } + + Object *object = RJSGetInternal(RJSValidatedValueToObject(ctx, arguments[0])); + + SharedRealm realm = *RJSGetInternal(thisObject); + + if (!realm->is_in_transaction()) { + throw std::runtime_error("Can only delete objects within a transaction."); + } + + realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object->object_schema.name); + table->remove(object->row.get_index()); + + return NULL; + } + catch (std::exception &exp) { + if (jsException) { + *jsException = RJSMakeError(ctx, exp); + } + return NULL; + } +} + JSValueRef RealmWrite(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { try { RJSValidateArgumentCount(argumentCount, 1); - JSObjectRef object = JSValueToObject(ctx, arguments[0], jsException); - if (object) { - SharedRealm realm = *RJSGetInternal(thisObject); - realm->begin_transaction(); - JSObjectCallAsFunction(ctx, object, thisObject, 0, NULL, jsException); - if (*jsException) { - realm->cancel_transaction(); - } - else { - realm->commit_transaction(); - } + JSObjectRef object = RJSValidatedValueToObject(ctx, arguments[0]); + SharedRealm realm = *RJSGetInternal(thisObject); + realm->begin_transaction(); + JSObjectCallAsFunction(ctx, object, thisObject, 0, NULL, jsException); + if (*jsException) { + realm->cancel_transaction(); + } + else { + realm->commit_transaction(); } } catch (std::exception &exp) { @@ -269,11 +301,7 @@ JSValueRef RealmAddNotification(JSContextRef ctx, JSObjectRef function, JSObject try { RJSValidateArgumentCount(argumentCount, 1); - JSObjectRef user_function = JSValueToObject(ctx, arguments[0], jsException); - if (!user_function) { - return NULL; - } - + JSObjectRef user_function = RJSValidatedValueToObject(ctx, arguments[0]); SharedRealm realm = *RJSGetInternal(thisObject); JSGlobalContextRef gCtx = JSGlobalContextRetain(JSContextGetGlobalContext(ctx)); Realm::NotificationFunction func = std::make_shared>([=](std::string notification_name) { @@ -309,6 +337,7 @@ JSClassRef RJSRealmClass() { const JSStaticFunction realmFuncs[] = { {"objects", RealmObjects}, {"create", RealmCreateObject}, + {"delete", RealmDelete}, {"write", RealmWrite}, {"addNotification", RealmAddNotification}, {NULL, NULL}, diff --git a/src/RJSUtil.hpp b/src/RJSUtil.hpp index 5bdf428c..86001521 100644 --- a/src/RJSUtil.hpp +++ b/src/RJSUtil.hpp @@ -172,3 +172,4 @@ static inline bool RJSIsValueObjectOfType(JSContextRef ctx, JSValueRef value, JS return ret; } +bool RJSIsValueArray(JSContextRef ctx, JSValueRef value); diff --git a/src/RJSUtil.mm b/src/RJSUtil.mm index 0b3647a5..4c41b1e1 100644 --- a/src/RJSUtil.mm +++ b/src/RJSUtil.mm @@ -79,3 +79,8 @@ JSValueRef RJSValueForString(JSContextRef ctx, const std::string &str) { JSStringRelease(jsStr); return value; } + +bool RJSIsValueArray(JSContextRef ctx, JSValueRef value) { + static JSStringRef arrayString = JSStringCreateWithUTF8CString("Array"); + return RJSIsValueObjectOfType(ctx, value, arrayString); +} \ No newline at end of file diff --git a/tests/RealmTests.js b/tests/RealmTests.js index 36549be3..1fd3ea2d 100644 --- a/tests/RealmTests.js +++ b/tests/RealmTests.js @@ -84,6 +84,35 @@ var RealmTests = { TestCase.assertEqual(objects[1].doubleCol, 2, 'wrong object property value'); }, + testRealmDelete: function() { + var realm = new Realm({schema: [TestObjectSchema]}); + realm.write(function() { + realm.create('TestObject', [1]); + realm.create('TestObject', [2]); + realm.create('TestObject', [3]); + realm.create('TestObject', [4]); + }); + + var objects = realm.objects('TestObject'); + TestCase.assertEqual(objects.length, 4, 'wrong object count'); + TestCase.assertThrows(function() { + realm.delete(objects[0]); + }, "can only delete in a write transaction"); + + realm.write(function() { + TestCase.assertThrows(function() { + realm.delete(); + }); + + realm.delete(objects[0]); + TestCase.assertEqual(objects.length, 3, 'wrong object count'); + TestCase.assertEqual(objects[0].doubleCol, 2); + + realm.delete([objects[0], objects[1]]); + TestCase.assertEqual(objects.length, 1, 'wrong object count'); + }); + }, + testRealmObjects: function() { var realm = new Realm({schema: [TestObjectSchema]}); realm.write(function() {