madsim_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    /// Returns a reference to the underlying `Client`.
73    fn client(&self) -> &Client;
74}
75
76impl private::Sealed for Client {}
77
78#[async_trait]
79impl GenericClient for Client {
80    async fn execute<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
81    where
82        T: ?Sized + ToStatement + Sync + Send,
83    {
84        self.execute(query, params).await
85    }
86
87    async fn execute_raw<P, I, T>(&self, statement: &T, params: I) -> Result<u64, Error>
88    where
89        T: ?Sized + ToStatement + Sync + Send,
90        P: BorrowToSql,
91        I: IntoIterator<Item = P> + Sync + Send,
92        I::IntoIter: ExactSizeIterator,
93    {
94        self.execute_raw(statement, params).await
95    }
96
97    async fn query<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
98    where
99        T: ?Sized + ToStatement + Sync + Send,
100    {
101        self.query(query, params).await
102    }
103
104    async fn query_one<T>(
105        &self,
106        statement: &T,
107        params: &[&(dyn ToSql + Sync)],
108    ) -> Result<Row, Error>
109    where
110        T: ?Sized + ToStatement + Sync + Send,
111    {
112        self.query_one(statement, params).await
113    }
114
115    async fn query_opt<T>(
116        &self,
117        statement: &T,
118        params: &[&(dyn ToSql + Sync)],
119    ) -> Result<Option<Row>, Error>
120    where
121        T: ?Sized + ToStatement + Sync + Send,
122    {
123        self.query_opt(statement, params).await
124    }
125
126    async fn query_raw<T, P, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
127    where
128        T: ?Sized + ToStatement + Sync + Send,
129        P: BorrowToSql,
130        I: IntoIterator<Item = P> + Sync + Send,
131        I::IntoIter: ExactSizeIterator,
132    {
133        self.query_raw(statement, params).await
134    }
135
136    async fn prepare(&self, query: &str) -> Result<Statement, Error> {
137        self.prepare(query).await
138    }
139
140    async fn prepare_typed(
141        &self,
142        query: &str,
143        parameter_types: &[Type],
144    ) -> Result<Statement, Error> {
145        self.prepare_typed(query, parameter_types).await
146    }
147
148    async fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
149        self.transaction().await
150    }
151
152    fn client(&self) -> &Client {
153        self
154    }
155}
156
157impl private::Sealed for Transaction<'_> {}
158
159#[async_trait]
160#[allow(clippy::needless_lifetimes)]
161impl GenericClient for Transaction<'_> {
162    async fn execute<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
163    where
164        T: ?Sized + ToStatement + Sync + Send,
165    {
166        self.execute(query, params).await
167    }
168
169    async fn execute_raw<P, I, T>(&self, statement: &T, params: I) -> Result<u64, Error>
170    where
171        T: ?Sized + ToStatement + Sync + Send,
172        P: BorrowToSql,
173        I: IntoIterator<Item = P> + Sync + Send,
174        I::IntoIter: ExactSizeIterator,
175    {
176        self.execute_raw(statement, params).await
177    }
178
179    async fn query<T>(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
180    where
181        T: ?Sized + ToStatement + Sync + Send,
182    {
183        self.query(query, params).await
184    }
185
186    async fn query_one<T>(
187        &self,
188        statement: &T,
189        params: &[&(dyn ToSql + Sync)],
190    ) -> Result<Row, Error>
191    where
192        T: ?Sized + ToStatement + Sync + Send,
193    {
194        self.query_one(statement, params).await
195    }
196
197    async fn query_opt<T>(
198        &self,
199        statement: &T,
200        params: &[&(dyn ToSql + Sync)],
201    ) -> Result<Option<Row>, Error>
202    where
203        T: ?Sized + ToStatement + Sync + Send,
204    {
205        self.query_opt(statement, params).await
206    }
207
208    async fn query_raw<T, P, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
209    where
210        T: ?Sized + ToStatement + Sync + Send,
211        P: BorrowToSql,
212        I: IntoIterator<Item = P> + Sync + Send,
213        I::IntoIter: ExactSizeIterator,
214    {
215        self.query_raw(statement, params).await
216    }
217
218    async fn prepare(&self, query: &str) -> Result<Statement, Error> {
219        self.prepare(query).await
220    }
221
222    async fn prepare_typed(
223        &self,
224        query: &str,
225        parameter_types: &[Type],
226    ) -> Result<Statement, Error> {
227        self.prepare_typed(query, parameter_types).await
228    }
229
230    #[allow(clippy::needless_lifetimes)]
231    async fn transaction<'a>(&'a mut self) -> Result<Transaction<'a>, Error> {
232        self.transaction().await
233    }
234
235    fn client(&self) -> &Client {
236        self.client()
237    }
238}