@@ -611,7 +611,7 @@ class _ConditionGroupAll extends _ConditionGroup {
611611/// Use [property] to only return values or an aggregate of a single Property.
612612class Query <T > {
613613 final Pointer <OBX_query > _cQuery;
614- final Store store;
614+ final Store store; // TODO make private
615615 final EntityDefinition <T > _entity;
616616
617617 int get entityId => _entity.model.id.id;
@@ -672,15 +672,23 @@ class Query<T> {
672672 void close () => checkObx (C .query_close (_cQuery));
673673
674674 /// Finds Objects matching the query and returns the first result or null
675- /// if there are no results.
676- /// Warning: this implicitly sets offset=0 & limit=1 and leaves them set.
677- /// In the future, this behaviour will change.
675+ /// if there are no results. Note: [offset] and [limit] are respected, if set.
678676 T ? findFirst () {
679- // TODO move to the core to avoid side-effects
680- offset (0 );
681- limit (1 );
682- final list = find ();
683- return (list.isEmpty ? null : list[0 ]);
677+ T ? result;
678+ final visitor = DataVisitor ((Pointer <Uint8 > dataPtr, int length) {
679+ result = _entity.objectFromFB (store, dataPtr.asTypedList (length));
680+ return false ; // we only want to visit the first element
681+ });
682+
683+ try {
684+ store.runInTransaction (TxMode .read, () {
685+ checkObx (C .query_visit (_cQuery, visitor.fn, visitor.userData));
686+ });
687+ } finally {
688+ visitor.close ();
689+ }
690+
691+ return result;
684692 }
685693
686694 /// Finds Objects matching the query and returns their IDs.
0 commit comments