odbc_api/preallocated_polling.rs
1use crate::{
2 CursorPolling, Error, ParameterCollectionRef, Sleep,
3 execute::execute_with_parameters_polling,
4 handles::{AsStatementRef, SqlText, StatementRef},
5};
6
7/// Asynchronous sibling of [`crate::Preallocated`] using polling mode for execution. Can be
8/// obtained using [`crate::Preallocated::into_polling`].
9pub struct PreallocatedPolling<S> {
10 /// A valid statement handle in polling mode
11 statement: S,
12}
13
14impl<S> PreallocatedPolling<S> {
15 pub(crate) fn new(statement: S) -> Self {
16 Self { statement }
17 }
18}
19
20impl<S> PreallocatedPolling<S>
21where
22 S: AsStatementRef,
23{
24 /// Executes a statement. This is the fastest way to sequentially execute different SQL
25 /// Statements asynchronously.
26 ///
27 /// # Parameters
28 ///
29 /// * `query`: The text representation of the SQL statement. E.g. "SELECT * FROM my_table;".
30 /// * `params`: `?` may be used as a placeholder in the statement text. You can use `()` to
31 /// represent no parameters. Check the [`crate::parameter`] module level documentation for
32 /// more information on how to pass parameters.
33 /// * `sleep`: Governs the polling intervals
34 ///
35 /// # Return
36 ///
37 /// Returns `Some` if a cursor is created. If `None` is returned no cursor has been created (
38 /// e.g. the query came back empty). Note that an empty query may also create a cursor with zero
39 /// rows. Since we want to reuse the statement handle a returned cursor will not take ownership
40 /// of it and instead burrow it.
41 ///
42 /// # Example
43 ///
44 /// ```
45 /// use odbc_api::{Connection, Error};
46 /// use std::{io::{self, stdin, Read}, time::Duration};
47 ///
48 /// /// Execute many different queries sequentially.
49 /// async fn execute_all(conn: &Connection<'_>, queries: &[&str]) -> Result<(), Error>{
50 /// let mut statement = conn.preallocate()?.into_polling()?;
51 /// let sleep = || tokio::time::sleep(Duration::from_millis(20));
52 /// for query in queries {
53 /// println!("Executing {query}");
54 /// match statement.execute(&query, (), sleep).await {
55 /// Err(e) => println!("{}", e),
56 /// Ok(None) => println!("No results set generated."),
57 /// Ok(Some(cursor)) => {
58 /// // ...print cursor contents...
59 /// },
60 /// }
61 /// }
62 /// Ok(())
63 /// }
64 /// ```
65 pub async fn execute(
66 &mut self,
67 query: &str,
68 params: impl ParameterCollectionRef,
69 sleep: impl Sleep,
70 ) -> Result<Option<CursorPolling<StatementRef<'_>>>, Error> {
71 let query = SqlText::new(query);
72 let stmt = self.statement.as_stmt_ref();
73 execute_with_parameters_polling(stmt, Some(&query), params, sleep).await
74 }
75}
76
77impl<S> AsStatementRef for PreallocatedPolling<S>
78where
79 S: AsStatementRef,
80{
81 fn as_stmt_ref(&mut self) -> StatementRef<'_> {
82 self.statement.as_stmt_ref()
83 }
84}