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§
source§impl<S> CursorPolling<S>where
S: AsStatementRef,
impl<S> CursorPolling<S>where
S: AsStatementRef,
sourcepub unsafe fn new(statement: S) -> Self
pub unsafe fn new(statement: S) -> Self
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?
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))
}
}sourcepub fn bind_buffer<B>(
self,
row_set_buffer: B
) -> Result<BlockCursorPolling<Self, B>, Error>where
B: RowSetBuffer,
pub fn bind_buffer<B>(
self,
row_set_buffer: B
) -> Result<BlockCursorPolling<Self, B>, Error>where
B: RowSetBuffer,
Binds this cursor to a buffer holding a row set.