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 24 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
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@
"flutter/realm_flutter/ios/src/**": true,
"flutter/realm_flutter/lib/**": true,
"flutter/realm_flutter/test/**": true
}
},
"dart.lineLength": 160
}
10 changes: 9 additions & 1 deletion lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ class _RealmCore {
});
}

void removeRealmObject(RealmObject object) {
void deleteRealmObject(RealmObject object) {
_realmLib.invokeGetBool(() => _realmLib.realm_object_delete(object.handle._pointer));
}

Expand Down Expand Up @@ -424,6 +424,14 @@ class _RealmCore {
_realmLib.invokeGetBool(() => _realmLib.realm_list_insert(list.handle._pointer, index, realm_value.ref));
});
}

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

void resultsDeleteAll(RealmResults results) {
_realmLib.invokeGetBool(() => _realmLib.realm_results_delete_all(results.handle._pointer));
}
}

class LastError {
Expand Down
25 changes: 24 additions & 1 deletion lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,37 @@ class Realm {
return object;
}

/// Delete given [RealmObject] from Realm database.
/// Throws [RealmException] on error.
void delete<T extends RealmObject>(T object) {
try {
realmCore.deleteRealmObject(object);
} catch (e) {
throw RealmException("Error deleting object from databse. Error: $e");
}
}

/// Deletes [RealmObject] items in given collection from Realm database.
void deleteMany<T extends RealmObject>(Iterable<T> items) {
if (items is RealmResults<T>) {
realmCore.resultsDeleteAll(items);
} else if (items is RealmList<T>) {
realmCore.listDeleteAll(items);
} else {
for (T realmObject in items) {
realmCore.deleteRealmObject(realmObject);
}
}
}

void addAll<T extends RealmObject>(Iterable<T> items) {
for (final i in items) {
add(i);
}
}

void remove<T extends RealmObject>(T object) {
realmCore.removeRealmObject(object);
realmCore.deleteRealmObject(object);
}

bool get _isInTransaction => realmCore.getIsWritable(this);
Expand Down
37 changes: 33 additions & 4 deletions lib/src/results.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,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 @@ -143,16 +143,19 @@ class RealmResults<T extends RealmObject> {
// }

/// 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);

/// 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.
Expand Down Expand Up @@ -208,3 +211,29 @@ extension RealmResultsInternal on RealmResults {
return RealmResults<T>._(handle, realm);
}
}

class _RealmResultsIterator<T extends RealmObject> implements Iterator<T> {
final RealmResults<T> _results;
int _index;
T? _current;
desistefanova marked this conversation as resolved.
Show resolved Hide resolved

_RealmResultsIterator(RealmResults<T> results)
: _results = results,
_index = -1;

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

@override
bool moveNext() {
int length = _results.length;
_index++;
if (_index >= length) {
_current = null;
return false;
}
_current = _results[_index];

return true;
}
}
191 changes: 184 additions & 7 deletions test/realm_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ Future<void> main([List<String>? args]) async {
expect(car, isNull);
});

test('Realm remove object', () {
test('Realm delete object', () {
var config = Configuration([Car.schema]);
var realm = Realm(config);

Expand All @@ -449,7 +449,7 @@ Future<void> main([List<String>? args]) async {
final car1 = realm.find<Car>("SomeNewNonExistingValue");
expect(car1, isNotNull);

realm.write(() => realm.remove(car1!));
realm.write(() => realm.delete(car1!));

var car2 = realm.find<Car>("SomeNewNonExistingValue");
expect(car2, isNull);
Expand All @@ -475,7 +475,7 @@ Future<void> main([List<String>? args]) async {

expect(cars.length, 1);

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

expect(cars.length, 0);
});
Expand All @@ -485,16 +485,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));
realm.write(() => realm.delete(car));

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

test('Results get by index', () {
Expand Down Expand Up @@ -679,5 +679,182 @@ 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.deleteMany from list', () {
var config = Configuration([Team.schema, Person.schema]);
var realm = Realm(config);

//Create two teams
final teamOne = Team()..name = "Team one";
final teamTwo = Team()..name = "Team two";
final teamThree = Team()..name = "Team three";
realm.write(() {
realm.add(teamOne);
realm.add(teamTwo);
realm.add(teamThree);
});

//Ensure the teams exist in realm
var teams = realm.all<Team>();
expect(teams.length, 3);

//Delete teams one and three from realm
realm.write(() => realm.deleteMany([teamOne, teamThree]));

//Ensure both teams are deleted and only teamTwo has left
expect(teams.length, 1);
expect(teams[0].name, teamTwo.name);
});

test('Realm.deleteMany 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
final newPlayers = [
Person()..name = "Michael Schumacher",
Person()..name = "Sebastian Vettel",
Person()..name = "Kimi Räikkönen",
];
realm.write(() => team.players.addAll(newPlayers));

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

//Delete team players
realm.write(() => realm.deleteMany(teams[0].players));

//Ensure players are deleted from collection
expect(teams[0].players.length, 0);

//Reload all persons from realm and ensure they are deleted
final allPersons = realm.all<Person>();
expect(allPersons.length, 0);
});

test('Realm.deleteMany 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
final newPlayers = [
Person()..name = "Michael Schumacher",
Person()..name = "Sebastian Vettel",
Person()..name = "Kimi Räikkönen",
];
realm.write(() {
teamOne.players.addAll(newPlayers);
teamTwo.players.addAll(newPlayers);
});

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

//Delete all players in a team from realm
realm.write(() => realm.deleteMany(teams[0].players));

//Ensure all players are deleted from collection
expect(teams[0].players.length, 0);

//Reload all persons from realm and ensure they are deleted
final allPersons = realm.all<Person>();
expect(allPersons.length, 0);
});

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

//Create two teams
realm.write(() {
realm.add(Team()..name = "Ferrari");
realm.add(Team()..name = "Maserati");
});

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

//Delete all objects in realmResults from realm
realm.write(() => realm.deleteMany(teams));
expect(teams.length, 0);

//Reload teams from realm and ensure they are deleted
teams = realm.all<Team>();
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
expect(teams.length, 0);
});

test('Realm.deleteMany from realmList after realm is closed', () {
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
final newPlayers = [
Person()..name = "Michael Schumacher",
Person()..name = "Sebastian Vettel",
Person()..name = "Kimi Räikkönen",
];
realm.write(() => team.players.addAll(newPlayers));

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

//Try to delete team players while realm is closed
final players = teams[0].players;
expect(
() => realm.write(() {
realm.close();
realm.deleteMany(players);
}),
throws<RealmException>());

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

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

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

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

//Iterate through teams and add realm objects to a list
List<Team> list = [];
for (Team team in teams) {
list.add(team);
}

//Ensure list size is the same like teams collection size
expect(list.length, teams.length);
});
});
}