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 10 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 realmResultsRemoveAll(RealmResults results) {
_realmLib.invokeGetBool(() => _realmLib.realm_results_delete_all(results.handle._pointer));
}
}

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

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

/// Removes [RealmObject] items in given collection from Realm database.
/// Throws [RealmException] on error.
void removeMany<T extends RealmObject>(Iterable<T> items) {
try {
if (items is RealmResults<T>) {
realmCore.realmResultsRemoveAll(items);
} else if (items is RealmList<T>) {
realmCore.realmListRemoveAll(items);
} else {
for (T realmObject in items) {
realmCore.removeRealmObject(realmObject);
}
}
} catch (e) {
throw RealmException("Error deleting objects from databse. Error: $e");
}
}

bool get _isInTransaction => realmCore.getIsWritable(this);
Expand Down
41 changes: 37 additions & 4 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 @@ -142,16 +142,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 @@ -207,3 +210,33 @@ extension RealmResultsInternal on RealmResults {
return RealmResults<T>._(handle, realm);
}
}

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

_RealmResultsIterator(RealmResults<T> results)
: _results = results,
_length = results.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 = _results.length;
if (_length != length) {
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
throw ConcurrentModificationError(_results);
}
if (_index >= length) {
_current = null;
return false;
}
_current = _results[_index];
_index++;
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
return true;
}
}
167 changes: 164 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,166 @@ 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));

//Reload teams from database and ensure they are removed
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 collection
expect(teams[0].players.length, 0);

//Reload persons from database and ensure they are removed
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 collection
expect(teams[0].players.length, 0);

//Reload persons from database and ensure they are removed
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));
expect(teams.length, 0);

//Reload teams from databse and ensure they are removed
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 database
realm = Realm(config);
final personsFromDB = realm.all<Person>();
expect(personsFromDB.length, 3);
});

test('RealmResults iteration test', () {
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";
realm.write(() => {realm.add(teamOne), realm.add(teamTwo)});

//Get teams from database
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
expect(list.length, teams.length);
});
});
}