Skip to content

Commit

Permalink
Expose embeddedObject.getParent
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsenko committed Nov 3, 2022
1 parent 58c01e9 commit 3f6289e
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
21 changes: 19 additions & 2 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import '../scheduler.dart';
import '../subscription.dart';
import '../user.dart';
import '../session.dart';
import '../util.dart';
import 'realm_bindings.dart';
import '../migration.dart';

Expand Down Expand Up @@ -716,8 +717,20 @@ class _RealmCore {
}

RealmObjectHandle createEmbeddedObject(RealmObjectBase obj, int propertyKey) {
final realmPtr = _realmLib.invokeGetPointer(() => _realmLib.realm_set_embedded(obj.handle._pointer, propertyKey));
return RealmObjectHandle._(realmPtr, obj.realm.handle);
final objectPtr = _realmLib.invokeGetPointer(() => _realmLib.realm_set_embedded(obj.handle._pointer, propertyKey));
return RealmObjectHandle._(objectPtr, obj.realm.handle);
}

Tuple<RealmObjectHandle, int> getEmbeddedParent(EmbeddedObject obj) {
return using((Arena arena) {
final parentPtr = arena<Pointer<realm_object>>();
final classKeyPtr = arena<Uint32>();
_realmLib.invokeGetBool(() => _realmLib.realm_object_get_parent(obj.handle._pointer, parentPtr, classKeyPtr));

final handle = RealmObjectHandle._(parentPtr.value, obj.realm.handle);

return Tuple(handle, classKeyPtr.value);
});
}

RealmObjectHandle getOrCreateRealmObjectWithPrimaryKey(Realm realm, int classKey, Object? primaryKey) {
Expand Down Expand Up @@ -1054,6 +1067,10 @@ class _RealmCore {
return _realmLib.realm_equals(first._pointer.cast(), second._pointer.cast());
}

int getObjectKey(RealmObjectBase obj) {
return _realmLib.realm_object_get_key(obj.handle._pointer);
}

bool objectEquals(RealmObjectBase first, RealmObjectBase second) => _equals(first.handle, second.handle);
bool realmEquals(Realm first, Realm second) => _equals(first.handle, second.handle);
bool userEquals(User first, User second) => _equals(first.handle, second.handle);
Expand Down
15 changes: 15 additions & 0 deletions lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import 'results.dart';
import 'scheduler.dart';
import 'subscription.dart';
import 'session.dart';
import 'util.dart';

export 'package:realm_common/realm_common.dart'
show
Expand Down Expand Up @@ -757,6 +758,20 @@ class RealmMetadata {

return metadata;
}

Tuple<Type, RealmObjectMetadata> getByClassKey(int key) {
final type = _typeMap.entries.firstWhereOrNull((e) => e.value.classKey == key);
if (type != null) {
return Tuple(type.key, type.value);
}

final metadata = _stringMap.values.firstWhereOrNull((e) => e.classKey == key);
if (metadata != null) {
return Tuple(RealmObjectBase, metadata);
}

throw RealmError("Object with classKey $key not found in the current Realm's schema.");
}
}

/// Exposes a set of dynamic methods on the Realm object. These don't use strongly typed
Expand Down
12 changes: 11 additions & 1 deletion lib/src/realm_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,17 @@ mixin RealmObjectBase on RealmEntity implements Finalizable {
mixin RealmObject on RealmObjectBase {}

/// @nodoc
mixin EmbeddedObject on RealmObjectBase {}
mixin EmbeddedObject on RealmObjectBase {
RealmObjectBase? getParent() {
if (!isManaged) {
return null;
}

final parent = realmCore.getEmbeddedParent(this);
final metadata = realm.metadata.getByClassKey(parent.item2);
return realm.createObject(metadata.item1, parent.item1, metadata.item2);
}
}

/// @nodoc
//RealmObject package internal members
Expand Down
6 changes: 6 additions & 0 deletions lib/src/util.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Tuple<T1, T2> {
T1 item1;
T2 item2;

Tuple(this.item1, this.item2);
}
30 changes: 30 additions & 0 deletions test/embedded_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,36 @@ Future<void> main([List<String>? args]) async {

expect(parent.recursiveList, isEmpty);
});

test('EmbeddedObject.getParent returns parent', () async {
final realm = getLocalRealm();

final parent =
ObjectWithEmbedded('123', recursiveObject: RecursiveEmbedded1('1.1', child: RecursiveEmbedded2('2.1')), recursiveList: [RecursiveEmbedded1('1.2')]);

realm.write(() {
realm.add(parent);
});

final child1 = parent.recursiveObject!;

expect(child1.getParent(), parent);
expect(child1.child!.getParent(), child1);

expect(parent.recursiveList[0].getParent(), parent);
});

test('EmbeddedObject.getParent when unmanaged returns null', () async {
final parent =
ObjectWithEmbedded('123', recursiveObject: RecursiveEmbedded1('1.1', child: RecursiveEmbedded2('2.1')), recursiveList: [RecursiveEmbedded1('1.2')]);

final child1 = parent.recursiveObject!;

expect(child1.getParent(), null);
expect(child1.child!.getParent(), null);

expect(parent.recursiveList[0].getParent(), null);
});
}

extension on RealmObjectBase {
Expand Down

0 comments on commit 3f6289e

Please sign in to comment.