odbc-api
odbc-api copied to clipboard
`Connection::into_cursor` does not provide strong exception safety.
pub fn into_cursor(
self,
query: &str,
params: impl ParameterCollectionRef,
) -> Result<Option<CursorImpl<StatementConnection<'c>>>, Error> {
let cursor = match self.execute(query, params) {
Ok(Some(cursor)) => cursor,
Ok(None) => return Ok(None),
Err(e) => return Err(e),
};
// The rust compiler needs some help here. It assumes otherwise that the lifetime of the
// resulting cursor would depend on the lifetime of `params`.
let mut cursor = ManuallyDrop::new(cursor);
let handle = cursor.as_sys();
// Safe: `handle` is a valid statement, and we are giving up ownership of `self`.
let statement = unsafe { StatementConnection::new(handle, self) };
// Safe: `statement is in the cursor state`.
let cursor = unsafe { CursorImpl::new(statement) };
Ok(Some
Should into_cursor fail, the Connection is lost and cleaned up. The user can not try again without a new connection.
Should we return the connection together with the error in case of failure? It could introduce some friction if the questionmark ? operator does not simply work. Maybe another error type instead of a tuple?.
Should we start from CursorImpl. Yet how would the compiler be than able to verify that the cursor has been created with the same connection?