Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

realm delete many #153

Merged
merged 27 commits into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a508a5c
Realm.RemoveMany and Results.RemoveAll implemented
desistefanova Dec 23, 2021
44b4f32
RemoveAll for RealmResults
desistefanova Dec 29, 2021
9b17836
removed method Realm RemoveAll
desistefanova Dec 29, 2021
86a663e
broken line returned back
desistefanova Dec 29, 2021
5bffdb0
RealmResults extends IterableBase
desistefanova Dec 30, 2021
ca27374
Handled error and RealmException is thrown
desistefanova Dec 30, 2021
9942fc7
Small fixes after PR comments
desistefanova Jan 4, 2022
86e6814
Fixing errors in RealmResults iterator.
desistefanova Jan 4, 2022
9c67ce3
private _RealmResultsIterator
desistefanova Jan 4, 2022
2190222
methods summary added
desistefanova Jan 4, 2022
08eae30
ConcurrentModificationError removed form _RealmResultsIterator.moveNext
desistefanova Jan 5, 2022
e971f15
Fixes after code review
desistefanova Jan 6, 2022
c75a768
Comments in tests are corrected
desistefanova Jan 6, 2022
f1167fe
Players lists in tests reordered
desistefanova Jan 6, 2022
dd71fa4
Realm remove methods renamed to delete methods: remove=>delete, remov…
desistefanova Jan 7, 2022
1dfbd02
realm_results_snapshot added to c library and ios
desistefanova Jan 7, 2022
e5c5ddd
C API realm_results_snapshot deleted back from dummy
desistefanova Jan 10, 2022
f1683d5
Test "Realm.deleteMany from list" fixes after code review
desistefanova Jan 10, 2022
d699018
Update lib/src/native/realm_core.dart
desistefanova Jan 11, 2022
82b355d
Update lib/src/native/realm_core.dart
desistefanova Jan 11, 2022
f84a2a1
Methods renamed realmResultsDeleteAll ->resultsDeleteAll and realmLis…
desistefanova Jan 11, 2022
5069718
Merge branch 'master' into Realm.RemoveMany
desistefanova Jan 11, 2022
f6d4bbd
merge
desistefanova Jan 11, 2022
f180db9
Merge branch 'master' into Realm.RemoveMany
desistefanova Jan 11, 2022
95ceacb
Merge branch 'master' into Realm.RemoveMany
desistefanova Jan 11, 2022
f99a7ce
Fixed test 'Realm.deleteMany from realmList after realm is closed'
desistefanova Jan 11, 2022
b4394ea
test name changed
desistefanova Jan 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,14 @@ class _RealmCore {
});
}

void realmListRemoveAll(RealmList list) {
_realmLib.invokeGetBool(
() => _realmLib.realm_list_remove_all(list.handle._pointer));
}

void realmResultsDeleteAll(RealmResults results) {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
_realmLib.invokeGetBool(() => _realmLib.realm_results_delete_all(results.handle._pointer));
}
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
}

class LastError {
Expand Down
16 changes: 16 additions & 0 deletions lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ class Realm {
realmCore.removeRealmObject(object);
}

void removeMany<T extends RealmObject>(Iterable<T> list) {
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
try {
if (list is RealmResults<T>) {
realmCore.realmResultsDeleteAll(list);
} else if (list is RealmList<T>) {
realmCore.realmListRemoveAll(list);
} else {
for (T realmObject in list) {
realmCore.removeRealmObject(realmObject);
}
}
} catch (e) {
throw RealmException("Error deleting objects from databse. Error: $e");
}
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
}

bool get _isInTransaction => realmCore.getIsWritable(this);

void write(void Function() writeCallback) {
Expand Down
46 changes: 40 additions & 6 deletions lib/src/results.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class _ResultsList<T extends RealmObject> extends collection.ListBase<T> {
/// Instances of this class are typically live collections returned by [Realm.objects]
/// that will update as new objects are either added to or deleted from the Realm
/// that match the underlying query.
class RealmResults<T extends RealmObject> {
class RealmResults<T extends RealmObject> extends collection.IterableBase<T> {
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
late final RealmResultsHandle _handle;
late final Realm _realm;
// RealmResults _results;
Expand Down Expand Up @@ -135,25 +135,28 @@ class RealmResults<T extends RealmObject> {
// List<T> asList() {
// return _ResultsList(this);
// }

/// Returns the index of the given object in the Results collection.
// int indexOf(T value) {
// return _results.indexOf(value);
// }

/// Returns `true` if the Results collection is empty
bool isEmpty() {
return length == 0;
}
@override
bool get isEmpty => length == 0;

@override
Iterator<T> get iterator => RealmResultsIterator(this);
nielsenko marked this conversation as resolved.
Show resolved Hide resolved

/// Returns `true` if this Results collection has not been deleted and is part of a valid Realm.
///
/// Accessing an invalid Results collection will throw an [RealmException]
// bool get isValid => _results.isValid();

/// Returns the number of values in the Results collection.
@override
int get length => realmCore.getResultsCount(this);

/// Returns a human-readable description of the objects contained in the collection.
// String get description => _results.description;

Expand Down Expand Up @@ -207,3 +210,34 @@ extension RealmResultsInternal on RealmResults {
return RealmResults<T>._(handle, realm);
}
}

class RealmResultsIterator<T extends RealmObject> implements Iterator<T> {
final Iterable<T> _iterable;
final int _length;
int _index;
T? _current;
desistefanova marked this conversation as resolved.
Show resolved Hide resolved

RealmResultsIterator(Iterable<T> iterable)
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
: _iterable = iterable,
_length = iterable.length,
_index = 0;

@override
T get current => _current as T;
nielsenko marked this conversation as resolved.
Show resolved Hide resolved

@override
bool moveNext() {
int length = _iterable.length;
if (_length != length) {
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
throw ConcurrentModificationError(_iterable);
}
if (_index >= length) {
_current = null;
return false;
}
_current = _iterable.elementAt(_index);
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
_index++;
return true;
}
}

136 changes: 133 additions & 3 deletions test/realm_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -464,16 +464,16 @@ Future<void> main([List<String>? args]) async {
var realm = Realm(config);

var cars = realm.all<Car>();
expect(cars.isEmpty(), true);
expect(cars.isEmpty, true);

final car = Car();
realm.write(() => realm.add(car));

expect(cars.isEmpty(), false);
expect(cars.isEmpty, false);

realm.write(() => realm.remove(car));

expect(cars.isEmpty(), true);
expect(cars.isEmpty, true);
});

test('Results get by index', () {
Expand Down Expand Up @@ -552,5 +552,135 @@ Future<void> main([List<String>? args]) async {
expect(() => realm.write(() => players[-1] = Person()), throws<RealmException>("Index out of range"));
expect(() => realm.write(() => players[800] = Person()), throws<RealmException>());
});

test('Realm RemoveMany from List', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

//Create two Teams
final teamOne = Team()..name = "Ferrari";
final teamTwo = Team()..name = "Maserati";
realm.write(() => {realm.add(teamOne), realm.add(teamTwo)});

var teams = realm.all<Team>();
expect(teams.length, 2);

//Convert RealmResults to List (asList should be implemented)
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
List<Team> list = [];
int itemsCount = teams.length;
for (var i = 0; i < itemsCount; i++) {
list.add(teams[i]);
}

realm.write(() => realm.removeMany(list));
teams = realm.all<Team>();
blagoev marked this conversation as resolved.
Show resolved Hide resolved
expect(teams.length, 0);
});

test('Realm RemoveMany from RealmList', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

//Create a Team
final team = Team()..name = "Ferrari";
realm.write(() => realm.add(team));

//Add players to the team
realm.write(() => team.players.addAll([
Person()..name = "Michael Schumacher",
Person()..name = "Sebastian Vettel",
Person()..name = "Kimi Räikkönen"
]));

//Ensure the Tema exists in DB
var teams = realm.all<Team>();
expect(teams.length, 1);

//Remove team players
realm.write(() => realm.removeMany(teams[0].players));

//Ensure persons are deleted from DB
final personsFromDB = realm.all<Person>();
expect(personsFromDB.length, 0);
});

test('Realm RemoveMany from RealmList referenced by two objects', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

//Create two Teams
final teamOne = Team()..name = "Ferrari";
final teamTwo = Team()..name = "Maserati";
realm.write(() => {realm.add(teamOne), realm.add(teamTwo)});

//Create common players list for both Teams
List<Person> players = [
Person()..name = "Michael Schumacher",
Person()..name = "Sebastian Vettel",
Person()..name = "Kimi Räikkönen"
];
realm.write(() =>
{teamOne.players.addAll(players), teamTwo.players.addAll(players)});

//Ensule teams exist in DB
var teams = realm.all<Team>();
expect(teams.length, 2);

//Remove all players in a team
realm.write(() => realm.removeMany(teams[0].players));

//Ensure all persons are deleted from DB
final personsFromDB = realm.all<Person>();
expect(personsFromDB.length, 0);
});

test('Realm RemoveMany from RealmResults', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

//Create two Teams
final teamOne = Team()..name = "Ferrari";
final teamTwo = Team()..name = "Maserati";
realm.write(() => {realm.add(teamOne), realm.add(teamTwo)});

//Ensule teams exist in DB
var teams = realm.all<Team>();
expect(teams.length, 2);

//Remove all objects in RealmResults from DB
realm.write(() => realm.removeMany(teams));
teams = realm.all<Team>();
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
expect(teams.length, 0);
});

test('Realm RemoveMany from RealmList in closed realm', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

final team = Team()..name = "Ferrari";
realm.write(() => realm.add(team));

realm.write(() => team.players.addAll([
Person()..name = "Michael Schumacher",
Person()..name = "Sebastian Vettel",
Person()..name = "Kimi Räikkönen"
]));

//Ensure team exists
var teams = realm.all<Team>();
expect(teams.length, 1);

//Try to delete team players while realm is closed
final playersToDelete = teams[0].players;
expect(() => realm.write(() => {realm.close(),
realm.removeMany(playersToDelete)}),
throws<RealmException>("Error deleting objects from databse"));

//Ensure all persons still exists in DB
realm = Realm(config);
final personsFromDB = realm.all<Person>();
expect(personsFromDB.length, 3);

});
});
}