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