Skip to content

Commit

Permalink
Avoid async overhead for sync reads
Browse files Browse the repository at this point in the history
  • Loading branch information
simolus3 committed Feb 8, 2024
1 parent 882aad1 commit 4912bad
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 6 deletions.
2 changes: 1 addition & 1 deletion drift/lib/src/runtime/api/connection_user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ abstract class DatabaseConnectionUser {

/// A [SqlTypes] mapping configuration to use when mapping values between Dart
/// and SQL.
SqlTypes get typeMapping => options.createTypeMapping(executor.dialect);
late final SqlTypes typeMapping = options.createTypeMapping(executor.dialect);

/// The database class that this user is attached to.
@visibleForOverriding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ class SimpleSelectStatement<T extends HasResultSet, D> extends Query<T, D>
return table.map(row);
}

Future<List<D>> _mapResponse(List<Map<String, Object?>> rows) {
return rows.mapAsyncAndAwait(_mapRow);
FutureOr<List<D>> _mapResponse(List<Map<String, Object?>> rows) {
return rows.mapAsyncAndAwait(table.map);
}

/// Creates a select statement that operates on more than one table by
Expand Down
7 changes: 6 additions & 1 deletion drift/lib/src/utils/async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import 'package:meta/meta.dart';
/// Drift-internal utilities to map potentially async operations.
extension MapAndAwait<T> on Iterable<T> {
/// A variant of [Future.wait] that also works for [FutureOr].
Future<List<R>> mapAsyncAndAwait<R>(FutureOr<R> Function(T) mapper) {
FutureOr<List<R>> mapAsyncAndAwait<R>(FutureOr<R> Function(T) mapper) {
if (mapper is R Function(T)) {
// It's actually all synchronous
return map(mapper).toList();
}

return Future.wait(map((e) => Future.sync(() => mapper(e))));
}
}
4 changes: 2 additions & 2 deletions drift/lib/src/utils/async_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ extension AsyncMapPerSubscription<S> on Stream<S> {
/// controller. Since we need the behavior of `asyncMap` internally though, we
/// re-implement it in a simple variant that transforms each subscription
/// individually.
Stream<T> asyncMapPerSubscription<T>(Future<T> Function(S) mapper) {
Stream<T> asyncMapPerSubscription<T>(FutureOr<T> Function(S) mapper) {
return Stream.multi(
(listener) {
late StreamSubscription<S> subscription;

void onData(S original) {
subscription.pause();
mapper(original)
Future.sync(() => mapper(original))
.then(listener.addSync, onError: listener.addErrorSync)
.whenComplete(subscription.resume);
}
Expand Down

0 comments on commit 4912bad

Please sign in to comment.