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 linking_objects_count(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
|
||||||
static void get_object_id(ContextType, ObjectType, Arguments, ReturnValue &);
|
static void get_object_id(ContextType, ObjectType, Arguments, ReturnValue &);
|
||||||
static void is_same_object(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";
|
const std::string name = "RealmObject";
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ struct RealmObjectClass : ClassDefinition<T, realm::Object> {
|
||||||
{"linkingObjectsCount", wrap<linking_objects_count>},
|
{"linkingObjectsCount", wrap<linking_objects_count>},
|
||||||
{"_objectId", wrap<get_object_id>},
|
{"_objectId", wrap<get_object_id>},
|
||||||
{"_isSameObject", wrap<is_same_object>},
|
{"_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;
|
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>
|
template<typename T>
|
||||||
std::vector<String<T>> RealmObjectClass<T>::get_property_names(ContextType ctx, ObjectType object) {
|
std::vector<String<T>> RealmObjectClass<T>::get_property_names(ContextType ctx, ObjectType object) {
|
||||||
auto realm_object = get_internal<T, RealmObjectClass<T>>(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())
|
TestCase.assertTrue(new Date('2017-12-07T20:16:03.837Z').toISOString() === objects[0].dateCol.toISOString())
|
||||||
|
|
||||||
realm.close()
|
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