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 list.query #239

Merged
merged 4 commits into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ vNext
### Changes
* Primary key annotation no longer requires field to be final.

### Enhancements
* Allow query on lists
nielsenko marked this conversation as resolved.
Show resolved Hide resolved


0.2.0+alpha Release notes (2022-01-31)
==============================================================
Expand Down
32 changes: 25 additions & 7 deletions lib/src/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import 'native/realm_core.dart';

import 'realm_object.dart';
import 'realm_class.dart';
import 'results.dart';

/// Instances of this class are live collections and will update as new elements are either
/// Instances of this class are live collections and will update as new elements are either
/// added to or deleted from the Realm that match the underlying query.
///
///{@category Realm}
class RealmList<T extends Object> extends collection.ListBase<T> {
late final RealmListHandle _handle;
late final Realm _realm;
final RealmListHandle _handle;
final Realm _realm;

RealmList._(this._handle, this._realm);

Expand Down Expand Up @@ -72,9 +73,9 @@ class RealmList<T extends Object> extends collection.ListBase<T> {

/// Clears the collection in memory and the references
/// to the objects in this collection in Realm.
/// Removes all elements from this list.
///

/// Removes all elements from this list.
///
/// The length of the list becomes zero.
/// If the elements are managed [RealmObject]s, they all remain in the Realm.
@override
Expand All @@ -83,10 +84,27 @@ class RealmList<T extends Object> extends collection.ListBase<T> {
}
}

// The query operations on lists only work for list of objects (core restriction),
// so we add it as an extension method to allow the compiler to prevent misuse.
extension RealmListOfObject<T extends RealmObject> on RealmList<T> {
/// Filter list.
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
///
/// @param query The query
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
/// @param args Possible parameters for substition in query
///
/// @return The live result
///
/// Only works for lists of objects.
RealmResults<T> query(String query, [List<Object> args = const []]) {
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
final handle = realmCore.queryList(this, query, args);
return RealmResultsInternal.create<T>(handle, realm);
}
}

/// @nodoc
extension RealmListInternal on RealmList {
RealmListHandle get handle => _handle;
Realm? get realm => _realm;
Realm get realm => _realm;

static RealmList<T> create<T extends Object>(RealmListHandle handle, Realm realm) => RealmList<T>._(handle, realm);

Expand Down
23 changes: 22 additions & 1 deletion lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,27 @@ class _RealmCore {
});
}

RealmResultsHandle queryList(RealmList target, String query, List<Object> args) {
return using((arena) {
nielsenko marked this conversation as resolved.
Show resolved Hide resolved
final length = args.length;
final argsPointer = arena<realm_value_t>(length);
for (var i = 0; i < length; ++i) {
_intoRealmValue(args[i], argsPointer.elementAt(i), arena);
}
final queryHandle = RealmQueryHandle._(_realmLib.invokeGetPointer(
() => _realmLib.realm_query_parse_for_list(
target.handle._pointer,
query.toUtf8Ptr(arena),
length,
argsPointer,
),
));
final resultsPointer = _realmLib.invokeGetPointer(() => _realmLib.realm_query_find_all(queryHandle._pointer));
return RealmResultsHandle._(resultsPointer);
});
}


RealmObjectHandle getObjectAt(RealmResults results, int index) {
final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_results_get_object(results.handle._pointer, index));
return RealmObjectHandle._(pointer);
Expand Down Expand Up @@ -404,7 +425,7 @@ class _RealmCore {
return using((Arena arena) {
final realm_value = arena<realm_value_t>();
_realmLib.invokeGetBool(() => _realmLib.realm_list_get(list.handle._pointer, index, realm_value));
return realm_value.toDartValue(list.realm!);
return realm_value.toDartValue(list.realm);
});
}

Expand Down
2 changes: 1 addition & 1 deletion lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export 'package:realm_common/realm_common.dart'
show Ignored, Indexed, MapTo, PrimaryKey, RealmError, RealmModel, RealmUnsupportedSetError, RealmCollectionType, RealmPropertyType;

export "configuration.dart" show Configuration, RealmSchema, SchemaObject;
export 'list.dart' show RealmList;
export 'list.dart' show RealmList, RealmListOfObject;
export 'realm_object.dart' show RealmException, RealmObject;
export 'realm_property.dart';
export 'results.dart' show RealmResults;
Expand Down
4 changes: 2 additions & 2 deletions lib/src/results.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import 'realm_class.dart';
///
/// {@category Realm}
class RealmResults<T extends RealmObject> extends collection.IterableBase<T> {
late final RealmResultsHandle _handle;
late final Realm _realm;
final RealmResultsHandle _handle;
final Realm _realm;

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

Expand Down
20 changes: 20 additions & 0 deletions test/realm_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,26 @@ Future<void> main([List<String>? args]) async {
realm.close();
});

test('Query list', () {
final config = Configuration([Team.schema, Person.schema]);
final realm = Realm(config);

final person = Person('Kasper');
final team = Team('Realm-dart', players: [
Person('Lubo'),
person,
Person('Desi'),
]);

realm.write(() => realm.add(team));

// TODO: Get rid of cast, once type signature of team.players is a RealmList<Person>
// as opposed to the List<Person> we have today.
final result = (team.players as RealmList<Person>).query(r'name BEGINSWITH $0', ['K']);
nielsenko marked this conversation as resolved.
Show resolved Hide resolved

expect(result, [person]);
});

test('Sort result', () {
var config = Configuration([Person.schema]);
var realm = Realm(config);
Expand Down