odbc-api icon indicating copy to clipboard operation
odbc-api copied to clipboard

`Connection::into_cursor` does not provide strong exception safety.

Open pacman82 opened this issue 1 year ago • 0 comments

    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?

pacman82 avatar Jun 23 '24 17:06 pacman82