withConnection<T> method
Acquires the exclusive handle and invalidates it after action completes.
Callback errors release the queue. Nested acquisition and closing from this callback are rejected to prevent waiting on one's own handle.
Implementation
@override
Future<T> withConnection<T>(
Future<T> Function(Connection connection) action,
) {
if (_closing) {
return Future.error(
StateError('The SQLite driver is closing or closed.'),
);
}
if (Zone.current[_callbackZone] != null) {
return Future.error(
StateError('Nested SQLite acquisition is not supported.'),
);
}
final result = _tail.then((_) async {
final connection = _SqliteConnection(
_database,
capabilities.maxParameters,
);
try {
return await runZoned(
() => action(connection),
zoneValues: {_callbackZone: true},
);
} finally {
connection._active = false;
// Direct driver users must not leak an unfinished transaction to a
// later acquisition. Runtime transactions normally finish explicitly.
if (!_database.autocommit) _database.execute('ROLLBACK');
}
});
_tail = result.then<void>((_) {}, onError: (Object _, StackTrace _) {});
return result;
}