libsql/
statement.rs

1use crate::params::IntoParams;
2use crate::params::Params;
3pub use crate::Column;
4use crate::{Error, Result};
5use crate::{Row, Rows};
6
7#[async_trait::async_trait]
8pub(crate) trait Stmt {
9    fn finalize(&mut self);
10
11    async fn execute(&self, params: &Params) -> Result<usize>;
12
13    async fn query(&self, params: &Params) -> Result<Rows>;
14
15    async fn run(&self, params: &Params) -> Result<()>;
16
17    fn interrupt(&self) -> Result<()>;
18
19    fn reset(&self);
20
21    fn parameter_count(&self) -> usize;
22
23    fn parameter_name(&self, idx: i32) -> Option<&str>;
24
25    fn column_count(&self) -> usize;
26
27    fn columns(&self) -> Vec<Column>;
28}
29
30/// A cached prepared statement.
31pub struct Statement {
32    pub(crate) inner: Box<dyn Stmt + Send + Sync>,
33}
34
35impl Statement {
36    /// Finalize the cached statement.
37    pub fn finalize(&mut self) {
38        self.inner.finalize();
39    }
40
41    /// Execute queries on the statement, check [`Connection::execute`] for usage.
42    pub async fn execute(&self, params: impl IntoParams) -> Result<usize> {
43        tracing::trace!("execute for prepared statement");
44        self.inner.execute(&params.into_params()?).await
45    }
46
47    /// Execute a query on the statement, check [`Connection::query`] for usage.
48    pub async fn query(&self, params: impl IntoParams) -> Result<Rows> {
49        tracing::trace!("query for prepared statement");
50        self.inner.query(&params.into_params()?).await
51    }
52
53    /// Run a query on the statement.
54    ///
55    /// The `execute()` method returns an error if the query returns rows, which makes
56    /// it unsuitable for running any type of SQL queries. Similarly, the `query()` method
57    /// only works on SQL statements that return rows. Therefore, the `run()` method is
58    /// provided to execute any type of SQL statement.
59    ///
60    /// Note: This is an extension to the Rusqlite API.
61    pub async fn run(&self, params: impl IntoParams) -> Result<()> {
62        tracing::trace!("run for prepared statement");
63        self.inner.run(&params.into_params()?).await?;
64        Ok(())
65    }
66
67    /// Interrupt the statement.
68    pub fn interrupt(&self) -> Result<()> {
69        self.inner.interrupt()
70    }
71
72    /// Execute a query that returns the first [`Row`].
73    ///
74    /// # Errors
75    ///
76    /// - Returns `QueryReturnedNoRows` if no rows were returned.
77    pub async fn query_row(&mut self, params: impl IntoParams) -> Result<Row> {
78        let mut rows = self.query(params).await?;
79
80        let row = rows.next().await?.ok_or(Error::QueryReturnedNoRows)?;
81
82        Ok(row)
83    }
84
85    /// Reset the state of this prepared statement.
86    pub fn reset(&self) {
87        self.inner.reset();
88    }
89
90    /// Fetch the amount of parameters in the prepared statement.
91    pub fn parameter_count(&self) -> usize {
92        self.inner.parameter_count()
93    }
94
95    /// Fetch the parameter name at the provided index.
96    pub fn parameter_name(&self, idx: i32) -> Option<&str> {
97        self.inner.parameter_name(idx)
98    }
99
100    /// Fetch the number of columns for the prepared statement.
101    pub fn column_count(&self) -> usize {
102        self.inner.column_count()
103    }
104
105    /// Fetch the list of columns for the prepared statement.
106    pub fn columns(&self) -> Vec<Column> {
107        self.inner.columns()
108    }
109}