yb_tokio_postgres/
generic_client.rs

1use crate::query::RowStream;
2use crate::types::{BorrowToSql, ToSql, Type};
3use crate::{Client, Error, Row, Statement, ToStatement, Transaction};
4use async_trait::async_trait;
5
6mod private {
7    pub trait Sealed {}
8}
9
10/// A trait allowing abstraction over connections and transactions.
11///
12/// This trait is "sealed", and cannot be implemented outside of this crate.
13#[async_trait]
14pub trait GenericClient: private::Sealed {
15    /// Like `Client::execute`.
16    async fn execute<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
17    where
18        T: ?Sized + ToStatement + Sync + Send;
19
20    /// Like `Client::execute_raw`.
21    async fn execute_raw<P, I, T>(&self, statement: &T, params: I) -> Result<u64, Error>
22    where
23        T: ?Sized + ToStatement + Sync + Send,
24        P: BorrowToSql,
25        I: IntoIterator<Item = P> + Sync + Send,
26        I::IntoIter: ExactSizeIterator;
27
28    /// Like `Client::query`.
29    async fn query<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
30    where
31        T: ?Sized + ToStatement + Sync + Send;
32
33    /// Like `Client::query_one`.
34    async fn query_one<T>(
35        &self,
36        statement: &T,
37        params: &[&(dyn ToSql + Sync)],
38    ) -> Result<Row, Error>
39    where
40        T: ?Sized + ToStatement + Sync + Send;
41
42    /// Like `Client::query_opt`.
43    async fn query_opt<T>(
44        &self,
45        statement: &T,
46        params: &[&(dyn ToSql + Sync)],
47    ) -> Result<Option<Row>, Error>
48    where
49        T: ?Sized + ToStatement + Sync + Send;
50
51    /// Like `Client::query_raw`.
52    async fn query_raw<T, P, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
53    where
54        T: ?Sized + ToStatement + Sync + Send,
55        P: BorrowToSql,
56        I: IntoIterator<Item = P> + Sync + Send,
57        I::IntoIter: ExactSizeIterator;
58
59    /// Like `Client::prepare`.
60    async fn prepare(&self, query: &str) -> Result<Statement, Error>;
61
62    /// Like `Client::prepare_typed`.
63    async fn prepare_typed(
64        &self,
65        query: &str,
66        parameter_types: &[Type],
67    ) -> Result<Statement, Error>;
68
69    /// Like `Client::transaction`.
70    async fn transaction(&mut self) -> Result<Transaction<'_>, Error>;
71
72    /// Like `Client::batch_execute`.
73    async fn batch_execute(&self, query: &str) -> Result<(), Error>;
74
75    /// Returns a reference to the underlying `Client`.
76    fn client(&self) -> &Client;
77}
78
79impl private::Sealed for Client {}
80
81#[async_trait]
82impl GenericClient for Client {
83    async fn execute<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
84    where
85        T: ?Sized + ToStatement + Sync + Send,
86    {
87        self.execute(query, params).await
88    }
89
90    async fn execute_raw<P, I, T>(&self, statement: &T, params: I) -> Result<u64, Error>
91    where
92        T: ?Sized + ToStatement + Sync + Send,
93        P: BorrowToSql,
94        I: IntoIterator<Item = P> + Sync + Send,
95        I::IntoIter: ExactSizeIterator,
96    {
97        self.execute_raw(statement, params).await
98    }
99
100    async fn query<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
101    where
102        T: ?Sized + ToStatement + Sync + Send,
103    {
104        self.query(query, params).await
105    }
106
107    async fn query_one<T>(
108        &self,
109        statement: &T,
110        params: &[&(dyn ToSql + Sync)],
111    ) -> Result<Row, Error>
112    where
113        T: ?Sized + ToStatement + Sync + Send,
114    {
115        self.query_one(statement, params).await
116    }
117
118    async fn query_opt<T>(
119        &self,
120        statement: &T,
121        params: &[&(dyn ToSql + Sync)],
122    ) -> Result<Option<Row>, Error>
123    where
124        T: ?Sized + ToStatement + Sync + Send,
125    {
126        self.query_opt(statement, params).await
127    }
128
129    async fn query_raw<T, P, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
130    where
131        T: ?Sized + ToStatement + Sync + Send,
132        P: BorrowToSql,
133        I: IntoIterator<Item = P> + Sync + Send,
134        I::IntoIter: ExactSizeIterator,
135    {
136        self.query_raw(statement, params).await
137    }
138
139    async fn prepare(&self, query: &str) -> Result<Statement, Error> {
140        self.prepare(query).await
141    }
142
143    async fn prepare_typed(
144        &self,
145        query: &str,
146        parameter_types: &[Type],
147    ) -> Result<Statement, Error> {
148        self.prepare_typed(query, parameter_types).await
149    }
150
151    async fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
152        self.transaction().await
153    }
154
155    async fn batch_execute(&self, query: &str) -> Result<(), Error> {
156        self.batch_execute(query).await
157    }
158
159    fn client(&self) -> &Client {
160        self
161    }
162}
163
164impl private::Sealed for Transaction<'_> {}
165
166#[async_trait]
167#[allow(clippy::needless_lifetimes)]
168impl GenericClient for Transaction<'_> {
169    async fn execute<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
170    where
171        T: ?Sized + ToStatement + Sync + Send,
172    {
173        self.execute(query, params).await
174    }
175
176    async fn execute_raw<P, I, T>(&self, statement: &T, params: I) -> Result<u64, Error>
177    where
178        T: ?Sized + ToStatement + Sync + Send,
179        P: BorrowToSql,
180        I: IntoIterator<Item = P> + Sync + Send,
181        I::IntoIter: ExactSizeIterator,
182    {
183        self.execute_raw(statement, params).await
184    }
185
186    async fn query<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
187    where
188        T: ?Sized + ToStatement + Sync + Send,
189    {
190        self.query(query, params).await
191    }
192
193    async fn query_one<T>(
194        &self,
195        statement: &T,
196        params: &[&(dyn ToSql + Sync)],
197    ) -> Result<Row, Error>
198    where
199        T: ?Sized + ToStatement + Sync + Send,
200    {
201        self.query_one(statement, params).await
202    }
203
204    async fn query_opt<T>(
205        &self,
206        statement: &T,
207        params: &[&(dyn ToSql + Sync)],
208    ) -> Result<Option<Row>, Error>
209    where
210        T: ?Sized + ToStatement + Sync + Send,
211    {
212        self.query_opt(statement, params).await
213    }
214
215    async fn query_raw<T, P, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
216    where
217        T: ?Sized + ToStatement + Sync + Send,
218        P: BorrowToSql,
219        I: IntoIterator<Item = P> + Sync + Send,
220        I::IntoIter: ExactSizeIterator,
221    {
222        self.query_raw(statement, params).await
223    }
224
225    async fn prepare(&self, query: &str) -> Result<Statement, Error> {
226        self.prepare(query).await
227    }
228
229    async fn prepare_typed(
230        &self,
231        query: &str,
232        parameter_types: &[Type],
233    ) -> Result<Statement, Error> {
234        self.prepare_typed(query, parameter_types).await
235    }
236
237    #[allow(clippy::needless_lifetimes)]
238    async fn transaction<'a>(&'a mut self) -> Result<Transaction<'a>, Error> {
239        self.transaction().await
240    }
241
242    async fn batch_execute(&self, query: &str) -> Result<(), Error> {
243        self.batch_execute(query).await
244    }
245
246    fn client(&self) -> &Client {
247        self.client()
248    }
249}