Skip to content

Commit

Permalink
Snapshot results on iterating (#258)
Browse files Browse the repository at this point in the history
* Snapshot results of RealmObjects when iteration starts. Fixes #166
  • Loading branch information
desistefanova authored Feb 28, 2022
1 parent df08276 commit 81ed943
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ x.x.x Release notes (yyyy-MM-dd)
### Compatibility
* Dart ^2.15 on Windows, MacOS and Linux

### Fixed
* Snapshot the results collection when iterating if the items are realm objects. ([#258](https://github.com/realm/realm-dart/pull/258))


0.2.0+alpha Release notes (2022-01-31)
==============================================================
Expand Down
1 change: 1 addition & 0 deletions flutter/realm_flutter/ios/Classes/RealmPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void dummy(void) {
realm_results_get_object(NULL, 0);
realm_list_size(NULL, 0);
realm_dart_results_add_notification_callback(NULL, NULL, NULL, NULL);
realm_results_snapshot(NULL);
}

@end
5 changes: 5 additions & 0 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,11 @@ class _RealmCore {
return _realmLib.realm_equals(first.handle._pointer.cast(), second.handle._pointer.cast());
}

RealmResultsHandle resultsSnapshot(RealmResults results) {
final resultsPointer = _realmLib.invokeGetPointer(() => _realmLib.realm_results_snapshot(results.handle._pointer));
return RealmResultsHandle._(resultsPointer);
}

bool objectIsValid(RealmObject object) {
return _realmLib.realm_object_is_valid(object.handle._pointer);
}
Expand Down
13 changes: 11 additions & 2 deletions lib/src/results.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ import 'realm_class.dart';
class RealmResults<T extends RealmObject> extends collection.IterableBase<T> {
final RealmResultsHandle _handle;

/// The Realm isntance this collection belongs to.
/// The Realm instance this collection belongs to.
final Realm realm;

final _supportsSnapshot = <T>[] is List<RealmObject?>;

RealmResults._(this._handle, this.realm);

Expand All @@ -56,7 +58,14 @@ class RealmResults<T extends RealmObject> extends collection.IterableBase<T> {

/// Returns a new `Iterator` that allows iterating the elements in this `RealmResults`.
@override
Iterator<T> get iterator => _RealmResultsIterator(this);
Iterator<T> get iterator {
var results = this;
if (_supportsSnapshot) {
final handle = realmCore.resultsSnapshot(this);
results = RealmResultsInternal.create<T>(handle, realm);
}
return _RealmResultsIterator(results);
}

/// The number of values in this `Results` collection.
@override
Expand Down
1 change: 1 addition & 0 deletions src/realm_dart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void dummy(void) {
realm_results_get_object(nullptr, 0);
realm_list_size(nullptr, 0);
realm_results_add_notification_callback(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
realm_results_snapshot(nullptr);
#if (ANDROID)
realm_android_dummy();
#endif
Expand Down
40 changes: 39 additions & 1 deletion test/results_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,45 @@ Future<void> main([List<String>? args]) async {
realm.close();
});

test('Results snapshot iteration test', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

//Create two teams
realm.write(() {
realm.add(Team("team One"));
realm.add(Team("team Two"));
});

//Reload teams from realm and ensure they exist
var teams = realm.all<Team>();
expect(teams.length, 2);

//Adding new teams to real while iterating through them.
//Iterator use a snapshot of results collection and ignores newly added teams.
List<Team> list = [];
for (Team team in teams) {
list.add(team);
realm.write(() {
realm.add(Team("new team"));
});
}
//Ensure list size is the same like teams collection size was at the beginnig
expect(list.length, 2);

//Ensure teams collection is increased
expect(teams.length, 4);

//Iterating teams again will create a snapshot with the newly added items
list.clear();
for (Team team in teams) {
list.add(team);
}
expect(list.length, teams.length);

realm.close();
});

test('Results query', () {
var config = Configuration([Car.schema]);
var realm = Realm(config);
Expand Down Expand Up @@ -212,7 +251,6 @@ Future<void> main([List<String>? args]) async {
realm.close();
});


test('Query results with no arguments throws', () {
var config = Configuration([Car.schema]);
var realm = Realm(config);
Expand Down

0 comments on commit 81ed943

Please sign in to comment.