run<R> method

Future<R> run<R>(
  1. Future<R> action(
    1. SqlConnection
    ), {
  2. AcquisitionOptions acquire = const AcquisitionOptions(),
  3. OrmException? acquisitionTimeoutError,
})

Runs action with an acquired or already leased connection.

This does not start a transaction. acquire limits only connection waiting; the connection must not escape action. Prefer execute for one command.

Implementation

Future<R> run<R>(
  Future<R> Function(SqlConnection) action, {
  AcquisitionOptions acquire = const AcquisitionOptions(),
  OrmException? acquisitionTimeoutError,
}) {
  checkActive();
  acquire.check();
  final connection = _connection == null
      ? null
      : _sessionConnection(_connection);
  final observer = onAcquire;
  final clock = observer == null || connection != null
      ? null
      : (Stopwatch()..start());
  var entered = false;
  void report(Object? error) {
    clock?.stop();
    try {
      observer?.call(
        AcquisitionEvent(
          elapsed: clock?.elapsed ?? Duration.zero,
          reusedConnection: connection != null,
          error: error,
        ),
      );
    } catch (_) {}
  }

  Future<R> enter(SqlConnection value) {
    entered = true;
    report(null);
    return action(value);
  }

  Future<R> observed(Future<R> result) => observer == null
      ? result
      : result.onError((Object error, StackTrace stack) {
          if (!entered) report(error);
          Error.throwWithStackTrace(error, stack);
        });
  final callback = observer == null ? action : enter;
  if (connection == null &&
      (acquire.timeout != null || acquire.cancellation != null)) {
    final wait = ConnectionWait(
      driver,
      callback,
      acquire,
      timeoutError: acquisitionTimeoutError,
    );
    _track(wait.drained);
    return observed(wait.result);
  }
  final result = connection != null
      ? Future.sync(() => callback(connection))
      : observer == null
      ? driver.run(action)
      : Future.sync(() => driver.run(callback));
  final done = result.then<void>(
    (_) {},
    onError: (Object _, StackTrace _) {},
  );
  _track(done);
  return observed(result);
}