sqlx_core/executor.rs
1use crate::database::Database;
2use crate::error::{BoxDynError, Error};
3use crate::sql_str::{SqlSafeStr, SqlStr};
4
5use either::Either;
6use futures_core::future::BoxFuture;
7use futures_core::stream::BoxStream;
8use futures_util::{FutureExt, StreamExt, TryFutureExt, TryStreamExt};
9use std::{fmt::Debug, future};
10
11/// A type that contains or can provide a database
12/// connection to use for executing queries against the database.
13///
14/// No guarantees are provided that successive queries run on the same
15/// physical database connection.
16///
17/// A [`Connection`](crate::connection::Connection) is an `Executor` that guarantees that
18/// successive queries are ran on the same physical database connection.
19///
20/// Implemented for the following:
21///
22/// * [`&Pool`](super::pool::Pool)
23/// * [`&mut Connection`](super::connection::Connection)
24///
25/// The [`Executor`] impls for [`Transaction`](crate::transaction::Transaction)
26/// and [`PoolConnection`](crate::pool::PoolConnection) have been deleted because they
27/// cannot exist in the new crate architecture without rewriting the Executor trait entirely.
28/// To fix this breakage, simply add a dereference where an impl [`Executor`] is expected, as
29/// they both dereference to the inner connection type which will still implement it:
30/// * `&mut transaction` -> `&mut *transaction`
31/// * `&mut connection` -> `&mut *connection`
32///
33pub trait Executor<'c>: Send + Debug + Sized {
34 type Database: Database;
35
36 /// Execute the query and return the total number of rows affected.
37 fn execute<'e, 'q: 'e, E>(
38 self,
39 query: E,
40 ) -> BoxFuture<'e, Result<<Self::Database as Database>::QueryResult, Error>>
41 where
42 'c: 'e,
43 E: 'q + Execute<'q, Self::Database>,
44 {
45 self.execute_many(query).try_collect().boxed()
46 }
47
48 /// Execute multiple queries and return the rows affected from each query, in a stream.
49 fn execute_many<'e, 'q: 'e, E>(
50 self,
51 query: E,
52 ) -> BoxStream<'e, Result<<Self::Database as Database>::QueryResult, Error>>
53 where
54 'c: 'e,
55 E: 'q + Execute<'q, Self::Database>,
56 {
57 self.fetch_many(query)
58 .try_filter_map(|step| async move {
59 Ok(match step {
60 Either::Left(rows) => Some(rows),
61 Either::Right(_) => None,
62 })
63 })
64 .boxed()
65 }
66
67 /// Execute the query and return the generated results as a stream.
68 fn fetch<'e, 'q: 'e, E>(
69 self,
70 query: E,
71 ) -> BoxStream<'e, Result<<Self::Database as Database>::Row, Error>>
72 where
73 'c: 'e,
74 E: 'q + Execute<'q, Self::Database>,
75 {
76 self.fetch_many(query)
77 .try_filter_map(|step| async move {
78 Ok(match step {
79 Either::Left(_) => None,
80 Either::Right(row) => Some(row),
81 })
82 })
83 .boxed()
84 }
85
86 /// Execute multiple queries and return the generated results as a stream
87 /// from each query, in a stream.
88 fn fetch_many<'e, 'q: 'e, E>(
89 self,
90 query: E,
91 ) -> BoxStream<
92 'e,
93 Result<
94 Either<<Self::Database as Database>::QueryResult, <Self::Database as Database>::Row>,
95 Error,
96 >,
97 >
98 where
99 'c: 'e,
100 E: 'q + Execute<'q, Self::Database>;
101
102 /// Execute the query and return all the generated results, collected into a [`Vec`].
103 fn fetch_all<'e, 'q: 'e, E>(
104 self,
105 query: E,
106 ) -> BoxFuture<'e, Result<Vec<<Self::Database as Database>::Row>, Error>>
107 where
108 'c: 'e,
109 E: 'q + Execute<'q, Self::Database>,
110 {
111 self.fetch(query).try_collect().boxed()
112 }
113
114 /// Execute the query and returns exactly one row.
115 fn fetch_one<'e, 'q: 'e, E>(
116 self,
117 query: E,
118 ) -> BoxFuture<'e, Result<<Self::Database as Database>::Row, Error>>
119 where
120 'c: 'e,
121 E: 'q + Execute<'q, Self::Database>,
122 {
123 self.fetch_optional(query)
124 .and_then(|row| {
125 future::ready(match row {
126 Some(row) => Ok(row),
127 None => Err(Error::RowNotFound),
128 })
129 })
130 .boxed()
131 }
132
133 /// Execute the query and returns at most one row.
134 fn fetch_optional<'e, 'q: 'e, E>(
135 self,
136 query: E,
137 ) -> BoxFuture<'e, Result<Option<<Self::Database as Database>::Row>, Error>>
138 where
139 'c: 'e,
140 E: 'q + Execute<'q, Self::Database>;
141
142 /// Prepare the SQL query to inspect the type information of its parameters
143 /// and results.
144 ///
145 /// Be advised that when using the `query`, `query_as`, or `query_scalar` functions, the query
146 /// is transparently prepared and executed.
147 ///
148 /// This explicit API is provided to allow access to the statement metadata available after
149 /// it prepared but before the first row is returned.
150 #[inline]
151 fn prepare<'e>(
152 self,
153 query: SqlStr,
154 ) -> BoxFuture<'e, Result<<Self::Database as Database>::Statement, Error>>
155 where
156 'c: 'e,
157 {
158 self.prepare_with(query, &[])
159 }
160
161 /// Prepare the SQL query, with parameter type information, to inspect the
162 /// type information about its parameters and results.
163 ///
164 /// Only some database drivers (PostgreSQL, MSSQL) can take advantage of
165 /// this extra information to influence parameter type inference.
166 fn prepare_with<'e>(
167 self,
168 sql: SqlStr,
169 parameters: &'e [<Self::Database as Database>::TypeInfo],
170 ) -> BoxFuture<'e, Result<<Self::Database as Database>::Statement, Error>>
171 where
172 'c: 'e;
173
174 /// Describe the SQL query and return type information about its parameters
175 /// and results.
176 ///
177 /// This is used by compile-time verification in the query macros to
178 /// power their type inference.
179 #[doc(hidden)]
180 #[cfg(feature = "offline")]
181 fn describe<'e>(
182 self,
183 sql: SqlStr,
184 ) -> BoxFuture<'e, Result<crate::describe::Describe<Self::Database>, Error>>
185 where
186 'c: 'e;
187}
188
189/// A type that may be executed against a database connection.
190///
191/// Implemented for the following:
192///
193/// * [`&str`](std::str)
194/// * [`Query`](super::query::Query)
195///
196pub trait Execute<'q, DB: Database>: Send + Sized {
197 /// Gets the SQL that will be executed.
198 fn sql(self) -> SqlStr;
199
200 /// Gets the previously cached statement, if available.
201 fn statement(&self) -> Option<&DB::Statement>;
202
203 /// Returns the arguments to be bound against the query string.
204 ///
205 /// Returning `Ok(None)` for `Arguments` indicates to use a "simple" query protocol and to not
206 /// prepare the query. Returning `Ok(Some(Default::default()))` is an empty arguments object that
207 /// will be prepared (and cached) before execution.
208 ///
209 /// Returns `Err` if encoding any of the arguments failed.
210 fn take_arguments(&mut self) -> Result<Option<<DB as Database>::Arguments>, BoxDynError>;
211
212 /// Returns `true` if the statement should be cached.
213 fn persistent(&self) -> bool;
214}
215
216impl<DB: Database, T> Execute<'_, DB> for T
217where
218 T: SqlSafeStr + Send,
219{
220 #[inline]
221 fn sql(self) -> SqlStr {
222 self.into_sql_str()
223 }
224
225 #[inline]
226 fn statement(&self) -> Option<&DB::Statement> {
227 None
228 }
229
230 #[inline]
231 fn take_arguments(&mut self) -> Result<Option<<DB as Database>::Arguments>, BoxDynError> {
232 Ok(None)
233 }
234
235 #[inline]
236 fn persistent(&self) -> bool {
237 true
238 }
239}
240
241impl<DB: Database, T> Execute<'_, DB> for (T, Option<<DB as Database>::Arguments>)
242where
243 T: SqlSafeStr + Send,
244{
245 #[inline]
246 fn sql(self) -> SqlStr {
247 self.0.into_sql_str()
248 }
249
250 #[inline]
251 fn statement(&self) -> Option<&DB::Statement> {
252 None
253 }
254
255 #[inline]
256 fn take_arguments(&mut self) -> Result<Option<<DB as Database>::Arguments>, BoxDynError> {
257 Ok(self.1.take())
258 }
259
260 #[inline]
261 fn persistent(&self) -> bool {
262 true
263 }
264}