commit
7dd3951bef
|
@ -56,6 +56,7 @@ struct RealmObjectClass : ClassDefinition<T, realm::Object> {
|
|||
static void linking_objects_count(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
|
||||
static void get_object_id(ContextType, ObjectType, Arguments, ReturnValue &);
|
||||
static void is_same_object(ContextType, ObjectType, Arguments, ReturnValue &);
|
||||
static void set_link(ContextType, ObjectType, Arguments, ReturnValue &);
|
||||
|
||||
const std::string name = "RealmObject";
|
||||
|
||||
|
@ -72,6 +73,7 @@ struct RealmObjectClass : ClassDefinition<T, realm::Object> {
|
|||
{"linkingObjectsCount", wrap<linking_objects_count>},
|
||||
{"_objectId", wrap<get_object_id>},
|
||||
{"_isSameObject", wrap<is_same_object>},
|
||||
{"_setLink", wrap<set_link>},
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -140,6 +142,53 @@ bool RealmObjectClass<T>::set_property(ContextType ctx, ObjectType object, const
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmObjectClass<T>::set_link(ContextType ctx, ObjectType object, Arguments args, ReturnValue& return_value) {
|
||||
args.validate_count(2);
|
||||
|
||||
auto realm_object = get_internal<T, RealmObjectClass<T>>(object);
|
||||
realm_object->realm()->verify_in_write();
|
||||
|
||||
NativeAccessor<T> accessor(ctx, realm_object->realm(), realm_object->get_object_schema());
|
||||
std::string property_name = Value::validated_to_string(ctx, args[0], "propertyName");
|
||||
const Property* prop = realm_object->get_object_schema().property_for_name(property_name);
|
||||
if (!prop) {
|
||||
throw std::invalid_argument(util::format("No such property: %1", property_name));
|
||||
}
|
||||
if (prop->type != realm::PropertyType::Object) {
|
||||
throw TypeErrorException(accessor, realm_object->get_object_schema().name, *prop, args[1]);
|
||||
}
|
||||
auto& linked_schema = *realm_object->realm()->schema().find(prop->object_type);
|
||||
auto linked_pk = linked_schema.primary_key_property();
|
||||
if (!linked_pk) {
|
||||
throw std::invalid_argument("Linked object type must have a primary key.");
|
||||
}
|
||||
|
||||
auto table = realm_object->row().get_table();
|
||||
auto linked_table = table->get_link_target(prop->table_column);
|
||||
|
||||
size_t row_ndx = realm::not_found;
|
||||
if (linked_pk->type == realm::PropertyType::String) {
|
||||
row_ndx = linked_table->find_first(linked_pk->table_column,
|
||||
accessor.template unbox<StringData>(args[1]));
|
||||
}
|
||||
else if (is_nullable(linked_pk->type)) {
|
||||
row_ndx = linked_table->find_first(linked_pk->table_column,
|
||||
accessor.template unbox<util::Optional<int64_t>>(args[1]));
|
||||
}
|
||||
else {
|
||||
row_ndx = linked_table->find_first(linked_pk->table_column,
|
||||
accessor.template unbox<int64_t>(args[1]));
|
||||
}
|
||||
|
||||
if (row_ndx == realm::not_found) {
|
||||
realm_object->row().set_null(prop->table_column);
|
||||
}
|
||||
else {
|
||||
realm_object->row().set_link(prop->table_column, row_ndx);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<String<T>> RealmObjectClass<T>::get_property_names(ContextType ctx, ObjectType object) {
|
||||
auto realm_object = get_internal<T, RealmObjectClass<T>>(object);
|
||||
|
|
|
@ -473,5 +473,87 @@ module.exports = {
|
|||
TestCase.assertTrue(new Date('2017-12-07T20:16:03.837Z').toISOString() === objects[0].dateCol.toISOString())
|
||||
|
||||
realm.close()
|
||||
},
|
||||
|
||||
testSetLink: function() {
|
||||
const schema = [
|
||||
{
|
||||
name: 'PrimaryInt',
|
||||
primaryKey: 'pk',
|
||||
properties: {
|
||||
pk: 'int',
|
||||
value: 'int'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'PrimaryOptionalInt',
|
||||
primaryKey: 'pk',
|
||||
properties: {
|
||||
pk: 'int?',
|
||||
value: 'int'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'PrimaryString',
|
||||
primaryKey: 'pk',
|
||||
properties: {
|
||||
pk: 'string?',
|
||||
value: 'int'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Links',
|
||||
properties: {
|
||||
intLink: 'PrimaryInt',
|
||||
optIntLink: 'PrimaryOptionalInt',
|
||||
stringLink: 'PrimaryString'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const realm = new Realm({schema: schema});
|
||||
realm.write(function() {
|
||||
realm.create('PrimaryInt', {pk: 1, value: 2})
|
||||
realm.create('PrimaryInt', {pk: 2, value: 4})
|
||||
realm.create('PrimaryOptionalInt', {pk: 1, value: 2})
|
||||
realm.create('PrimaryOptionalInt', {pk: 2, value: 4})
|
||||
realm.create('PrimaryOptionalInt', {pk: null, value: 6})
|
||||
realm.create('PrimaryString', {pk: 'a', value: 2})
|
||||
realm.create('PrimaryString', {pk: 'b', value: 4})
|
||||
realm.create('PrimaryString', {pk: null, value: 6})
|
||||
|
||||
const obj = realm.create('Links', {});
|
||||
|
||||
obj._setLink('intLink', 3);
|
||||
TestCase.assertEqual(obj.intLink, null);
|
||||
obj._setLink('intLink', 1);
|
||||
TestCase.assertEqual(obj.intLink.value, 2);
|
||||
obj._setLink('intLink', 2);
|
||||
TestCase.assertEqual(obj.intLink.value, 4);
|
||||
obj._setLink('intLink', 3);
|
||||
TestCase.assertEqual(obj.intLink, null);
|
||||
|
||||
obj._setLink('optIntLink', 3);
|
||||
TestCase.assertEqual(obj.optIntLink, null);
|
||||
obj._setLink('optIntLink', 1);
|
||||
TestCase.assertEqual(obj.optIntLink.value, 2);
|
||||
obj._setLink('optIntLink', 2);
|
||||
TestCase.assertEqual(obj.optIntLink.value, 4);
|
||||
obj._setLink('optIntLink', null);
|
||||
TestCase.assertEqual(obj.optIntLink.value, 6);
|
||||
obj._setLink('optIntLink', 3);
|
||||
TestCase.assertEqual(obj.optIntLink, null);
|
||||
|
||||
obj._setLink('stringLink', 'c');
|
||||
TestCase.assertEqual(obj.stringLink, null);
|
||||
obj._setLink('stringLink', 'a');
|
||||
TestCase.assertEqual(obj.stringLink.value, 2);
|
||||
obj._setLink('stringLink', 'b');
|
||||
TestCase.assertEqual(obj.stringLink.value, 4);
|
||||
obj._setLink('stringLink', null);
|
||||
TestCase.assertEqual(obj.stringLink.value, 6);
|
||||
obj._setLink('stringLink', 'c');
|
||||
TestCase.assertEqual(obj.stringLink, null);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue