Struct odbc_api::CursorPolling

source ·
pub struct CursorPolling<Stmt: AsStatementRef> { /* private fields */ }
Expand description

The asynchronous sibiling of CursorImpl. Use this to fetch results in asynchronous code.

Like CursorImpl this is an ODBC statement handle in cursor state. However unlike its synchronous sibling this statement handle is in asynchronous polling mode.

Implementations§

Users of this library are encouraged not to call this constructor directly. This method is pubilc so users with an understanding of the raw ODBC C-API have a way to create an asynchronous cursor, after they left the safety rails of the Rust type System, in order to implement a use case not covered yet, by the safe abstractions within this crate.

Safety

statement must be in Cursor state, for the invariants of this type to hold. Preferable statement should also have asynchrous mode enabled, otherwise constructing a synchronous CursorImpl is more suitable.

Examples found in repository?
src/execute.rs (line 186)
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
pub async unsafe fn execute_polling<S>(
    mut statement: S,
    query: Option<&SqlText<'_>>,
    mut sleep: impl Sleep,
) -> Result<Option<CursorPolling<S>>, Error>
where
    S: AsStatementRef,
{
    let mut stmt = statement.as_stmt_ref();
    let result = if let Some(sql) = query {
        // We execute an unprepared "one shot query"
        wait_for(|| stmt.exec_direct(sql), &mut sleep).await
    } else {
        // We execute a prepared query
        wait_for(|| stmt.execute(), &mut sleep).await
    };

    // If delayed parameters (e.g. input streams) are bound we might need to put data in order to
    // execute.
    let need_data =
        result
            .on_success(|| false)
            .into_result_with(&stmt, false, Some(false), Some(true))?;

    if need_data {
        // Check if any delayed parameters have been bound which stream data to the database at
        // statement execution time. Loops over each bound stream.
        while let Some(blob_ptr) = stmt.param_data().into_result(&stmt)? {
            // The safe interfaces currently exclusively bind pointers to `Blob` trait objects
            let blob_ptr: *mut &mut dyn Blob = transmute(blob_ptr);
            let blob_ref = &mut *blob_ptr;
            // Loop over all batches within each blob
            while let Some(batch) = blob_ref.next_batch().map_err(Error::FailedReadingInput)? {
                let result = wait_for(|| stmt.put_binary_batch(batch), &mut sleep).await;
                result.into_result(&stmt)?;
            }
        }
    }

    // Check if a result set has been created.
    let num_result_cols = wait_for(|| stmt.num_result_cols(), &mut sleep)
        .await
        .into_result(&stmt)?;
    if num_result_cols == 0 {
        Ok(None)
    } else {
        // Safe: `statement` is in cursor state.
        let cursor = CursorPolling::new(statement);
        Ok(Some(cursor))
    }
}

Binds this cursor to a buffer holding a row set.

Trait Implementations§

Get an exclusive reference to the underlying statement handle. This method is used to implement other more higher level methods on top of it. It is not intended to be called by users of this crate directly, yet it may serve as an escape hatch for low level usecases.
Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.