primary keys and upsert
This commit is contained in:
parent
df05636e7a
commit
ee87cbc17a
|
@ -221,8 +221,8 @@
|
||||||
0270BC7B1B7D020100010E03 /* RealmJSTests.mm */,
|
0270BC7B1B7D020100010E03 /* RealmJSTests.mm */,
|
||||||
0270BC7C1B7D020100010E03 /* RealmTests.js */,
|
0270BC7C1B7D020100010E03 /* RealmTests.js */,
|
||||||
0270BC7D1B7D020100010E03 /* ResultsTests.js */,
|
0270BC7D1B7D020100010E03 /* ResultsTests.js */,
|
||||||
0270BC7E1B7D020100010E03 /* TestCase.js */,
|
|
||||||
0270BC7F1B7D020100010E03 /* TestObjects.js */,
|
0270BC7F1B7D020100010E03 /* TestObjects.js */,
|
||||||
|
0270BC7E1B7D020100010E03 /* TestCase.js */,
|
||||||
);
|
);
|
||||||
path = RealmJSTests;
|
path = RealmJSTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
|
@ -221,7 +221,12 @@ JSValueRef RealmCreateObject(JSContextRef ctx, JSObjectRef function, JSObjectRef
|
||||||
object = RJSDictForPropertyArray(ctx, object_schema->second, object);
|
object = RJSDictForPropertyArray(ctx, object_schema->second, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RJSObjectCreate(ctx, Object::create<JSValueRef>(ctx, sharedRealm, object_schema->second, object, false));
|
bool update = false;
|
||||||
|
if (argumentCount == 3) {
|
||||||
|
update = RJSValidatedValueToBool(ctx, arguments[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RJSObjectCreate(ctx, Object::create<JSValueRef>(ctx, sharedRealm, object_schema->second, object, update));
|
||||||
}
|
}
|
||||||
catch (std::exception &exp) {
|
catch (std::exception &exp) {
|
||||||
if (jsException) {
|
if (jsException) {
|
||||||
|
|
|
@ -118,6 +118,7 @@ static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef ob
|
||||||
|
|
||||||
ObjectSchema objectSchema;
|
ObjectSchema objectSchema;
|
||||||
static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
|
static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
|
||||||
|
|
||||||
objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);
|
objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);
|
||||||
|
|
||||||
size_t numProperties = RJSValidatedArrayLength(ctx, propertiesObject);
|
size_t numProperties = RJSValidatedArrayLength(ctx, propertiesObject);
|
||||||
|
@ -126,6 +127,17 @@ static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef ob
|
||||||
objectSchema.properties.emplace_back(RJSParseProperty(ctx, property));
|
objectSchema.properties.emplace_back(RJSParseProperty(ctx, property));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSStringRef primaryString = JSStringCreateWithUTF8CString("primaryKey");
|
||||||
|
JSValueRef primaryValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, primaryString);
|
||||||
|
if (!JSValueIsUndefined(ctx, primaryValue)) {
|
||||||
|
objectSchema.primary_key = RJSValidatedStringForValue(ctx, primaryValue);
|
||||||
|
Property *property = objectSchema.primary_key_property();
|
||||||
|
if (!property) {
|
||||||
|
throw std::runtime_error("Missing primary key property '" + objectSchema.primary_key + "'");
|
||||||
|
}
|
||||||
|
property->is_primary = true;
|
||||||
|
}
|
||||||
|
|
||||||
// store prototype
|
// store prototype
|
||||||
if (prototypeObject) {
|
if (prototypeObject) {
|
||||||
JSValueProtect(ctx, prototypeObject);
|
JSValueProtect(ctx, prototypeObject);
|
||||||
|
|
|
@ -112,6 +112,18 @@ static inline double RJSValidatedValueToNumber(JSContextRef ctx, JSValueRef valu
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool RJSValidatedValueToBool(JSContextRef ctx, JSValueRef value) {
|
||||||
|
JSValueRef exception = NULL;
|
||||||
|
if (!JSValueIsBoolean(ctx, value)) {
|
||||||
|
throw std::runtime_error("Value is not a boolean");
|
||||||
|
}
|
||||||
|
bool b = JSValueToNumber(ctx, value, &exception);
|
||||||
|
if (exception) {
|
||||||
|
throw RJSException(ctx, exception);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
static inline JSValueRef RJSValidatedPropertyValue(JSContextRef ctx, JSObjectRef object, JSStringRef property) {
|
static inline JSValueRef RJSValidatedPropertyValue(JSContextRef ctx, JSObjectRef object, JSStringRef property) {
|
||||||
JSValueRef exception = NULL;
|
JSValueRef exception = NULL;
|
||||||
JSValueRef propertyValue = JSObjectGetProperty(ctx, object, property, &exception);
|
JSValueRef propertyValue = JSObjectGetProperty(ctx, object, property, &exception);
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace realm {
|
||||||
size_t row_index = realm::not_found;
|
size_t row_index = realm::not_found;
|
||||||
realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);
|
realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);
|
||||||
Property *primary_prop = object_schema.primary_key_property();
|
Property *primary_prop = object_schema.primary_key_property();
|
||||||
if (try_update && primary_prop) {
|
if (primary_prop) {
|
||||||
// search for existing object based on primary key type
|
// search for existing object based on primary key type
|
||||||
ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
|
ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
|
||||||
if (primary_prop->type == PropertyTypeString) {
|
if (primary_prop->type == PropertyTypeString) {
|
||||||
|
@ -167,6 +167,10 @@ namespace realm {
|
||||||
else {
|
else {
|
||||||
row_index = table->find_first_int(primary_prop->table_column, Accessor::to_long(ctx, primary_value));
|
row_index = table->find_first_int(primary_prop->table_column, Accessor::to_long(ctx, primary_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!try_update && row_index != realm::not_found) {
|
||||||
|
throw std::runtime_error("Attempting to create an object of type '" + object_schema.name + "' with an exising primary key value.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no existing, create row
|
// if no existing, create row
|
||||||
|
|
|
@ -82,6 +82,23 @@ var RealmTests = {
|
||||||
TestCase.assertEqual(objects.length, 2, 'wrong object count');
|
TestCase.assertEqual(objects.length, 2, 'wrong object count');
|
||||||
TestCase.assertEqual(objects[0].doubleCol, 1, 'wrong object property value');
|
TestCase.assertEqual(objects[0].doubleCol, 1, 'wrong object property value');
|
||||||
TestCase.assertEqual(objects[1].doubleCol, 2, 'wrong object property value');
|
TestCase.assertEqual(objects[1].doubleCol, 2, 'wrong object property value');
|
||||||
|
|
||||||
|
// test primary object
|
||||||
|
realm = new Realm({path: TestUtil.realmPathForFile('intPrimary.realm'), schema: [IntPrimaryObjectSchema, StringPrimaryObjectSchema]});
|
||||||
|
realm.write(function() {
|
||||||
|
var obj0 = realm.create('IntPrimaryObject', [0, 'val0']);
|
||||||
|
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
realm.create('IntPrimaryObject', [0, 'val0']);
|
||||||
|
});
|
||||||
|
realm.create('IntPrimaryObject', [1, 'val1'], true);
|
||||||
|
var objects = realm.objects('IntPrimaryObject');
|
||||||
|
TestCase.assertEqual(objects.length, 2);
|
||||||
|
|
||||||
|
realm.create('IntPrimaryObject', [0, 'newVal0'], true);
|
||||||
|
TestCase.assertEqual(obj0.valueCol, 'newVal0');
|
||||||
|
TestCase.assertEqual(objects.length, 2);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
testRealmDelete: function() {
|
testRealmDelete: function() {
|
||||||
|
@ -167,3 +184,4 @@ var RealmTests = {
|
||||||
TestCase.assertEqual(notificationCount, 1);
|
TestCase.assertEqual(notificationCount, 1);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,3 +58,21 @@ var LinkTypesObjectSchema = {
|
||||||
{name: 'arrayCol', type: RealmType.Array, objectType: 'TestObject'},
|
{name: 'arrayCol', type: RealmType.Array, objectType: 'TestObject'},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var IntPrimaryObjectSchema = {
|
||||||
|
name: 'IntPrimaryObject',
|
||||||
|
primaryKey: 'primaryCol',
|
||||||
|
properties: [
|
||||||
|
{name: 'primaryCol', type: RealmType.Int},
|
||||||
|
{name: 'valueCol', type: RealmType.String},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
var StringPrimaryObjectSchema = {
|
||||||
|
name: 'StringPrimaryObject',
|
||||||
|
primaryKey: 'primaryCol',
|
||||||
|
properties: [
|
||||||
|
{name: 'primaryCol', type: RealmType.String},
|
||||||
|
{name: 'valueCol', type: RealmType.String},
|
||||||
|
]
|
||||||
|
};
|
Loading…
Reference in New Issue