Mutating lists outside transaction should throw

This commit is contained in:
Scott Kyle 2015-10-12 02:23:09 -07:00
parent 33e0f5d8b1
commit c600af9182
2 changed files with 36 additions and 18 deletions

View File

@ -49,6 +49,14 @@ static inline ObjectArray * RJSVerifiedArray(JSObjectRef object) {
return array; return array;
} }
static inline ObjectArray * RJSVerifiedMutableArray(JSObjectRef object) {
ObjectArray *array = RJSVerifiedArray(object);
if (!array->realm->is_in_transaction()) {
throw std::runtime_error("Can only mutate lists within a transaction.");
}
return array;
}
JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) { JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
try { try {
// index subscripting // index subscripting
@ -89,7 +97,7 @@ void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccu
JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try { try {
ObjectArray *array = RJSVerifiedArray(thisObject); ObjectArray *array = RJSVerifiedMutableArray(thisObject);
RJSValidateArgumentCountIsAtLeast(argumentCount, 1); RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
for (size_t i = 0; i < argumentCount; i++) { for (size_t i = 0; i < argumentCount; i++) {
array->link_view->add(RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false)); array->link_view->add(RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
@ -106,7 +114,7 @@ JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj
JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try { try {
ObjectArray *array = RJSVerifiedArray(thisObject); ObjectArray *array = RJSVerifiedMutableArray(thisObject);
RJSValidateArgumentCount(argumentCount, 0); RJSValidateArgumentCount(argumentCount, 0);
size_t size = array->size(); size_t size = array->size();
@ -128,7 +136,7 @@ JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObje
JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try { try {
ObjectArray *array = RJSVerifiedArray(thisObject); ObjectArray *array = RJSVerifiedMutableArray(thisObject);
RJSValidateArgumentCountIsAtLeast(argumentCount, 1); RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
for (size_t i = 0; i < argumentCount; i++) { for (size_t i = 0; i < argumentCount; i++) {
array->link_view->insert(i, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false)); array->link_view->insert(i, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
@ -145,7 +153,7 @@ JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef this
JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try { try {
ObjectArray *array = RJSVerifiedArray(thisObject); ObjectArray *array = RJSVerifiedMutableArray(thisObject);
RJSValidateArgumentCount(argumentCount, 0); RJSValidateArgumentCount(argumentCount, 0);
if (array->size() == 0) { if (array->size() == 0) {
return JSValueMakeUndefined(ctx); return JSValueMakeUndefined(ctx);
@ -164,7 +172,7 @@ JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisOb
JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try { try {
ObjectArray *array = RJSVerifiedArray(thisObject); ObjectArray *array = RJSVerifiedMutableArray(thisObject);
size_t size = array->size(); size_t size = array->size();
RJSValidateArgumentCountIsAtLeast(argumentCount, 2); RJSValidateArgumentCountIsAtLeast(argumentCount, 2);

View File

@ -108,6 +108,7 @@ var ArrayTests = {
testPush: function() { testPush: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
var array; var array;
realm.write(function() { realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]); var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]);
TestCase.assertEqual(obj.arrayCol.length, 1); TestCase.assertEqual(obj.arrayCol.length, 1);
@ -128,14 +129,15 @@ var ArrayTests = {
}); });
TestCase.assertEqual(array.length, 4); TestCase.assertEqual(array.length, 4);
// TestCase.assertThrows(function() { TestCase.assertThrows(function() {
// array.push([1]); array.push([1]);
// }); }, 'can only push in a write transaction');
}, },
testPop: function() { testPop: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
var array; var array;
realm.write(function() { realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]); var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
array = obj.arrayCol; array = obj.arrayCol;
@ -151,14 +153,15 @@ var ArrayTests = {
}); });
}); });
// TestCase.assertThrows(function() { TestCase.assertThrows(function() {
// array.pop(); array.pop();
// }); }, 'can only pop in a write transaction');
}, },
testUnshift: function() { testUnshift: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
var array; var array;
realm.write(function() { realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]); var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]);
TestCase.assertEqual(obj.arrayCol.length, 1); TestCase.assertEqual(obj.arrayCol.length, 1);
@ -175,14 +178,15 @@ var ArrayTests = {
}); });
TestCase.assertEqual(array.length, 4); TestCase.assertEqual(array.length, 4);
// TestCase.assertThrows(function() { TestCase.assertThrows(function() {
// array.unshift([1]); array.unshift([1]);
// }); }, 'can only unshift in a write transaction');
}, },
testShift: function() { testShift: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
var array; var array;
realm.write(function() { realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]); var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
array = obj.arrayCol; array = obj.arrayCol;
@ -198,19 +202,21 @@ var ArrayTests = {
}); });
}); });
// TestCase.assertThrows(function() { TestCase.assertThrows(function() {
// array.shift(); array.shift();
// }); }, 'can only shift in a write transaction');
}, },
testSplice: function() { testSplice: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
var array;
realm.write(function() { realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]); var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
var array = obj.arrayCol;
var removed; var removed;
array = obj.arrayCol;
removed = array.splice(0, 0, obj.objectCol, obj.objectCol1); removed = array.splice(0, 0, obj.objectCol, obj.objectCol1);
TestCase.assertEqual(removed.length, 0); TestCase.assertEqual(removed.length, 0);
TestCase.assertEqual(array.length, 4); TestCase.assertEqual(array.length, 4);
@ -248,5 +254,9 @@ var ArrayTests = {
array.splice(0, 0, 0); array.splice(0, 0, 0);
}); });
}); });
TestCase.assertThrows(function() {
obj.arrayCol.splice(0, 0, obj.objectCol);
}, 'can only splice in a write transaction');
}, },
}; };