1mod cache;
4
5pub use cache::Caching;
6
7use async_trait::async_trait;
8use postgres_types::ToSql;
9use tokio_postgres::{error::Error as SqlError, Client, RowStream, Statement, Transaction};
10
11#[async_trait]
13pub trait GenericClient {
14 async fn prepare(&self, sql: &str) -> Result<Statement, SqlError>;
19
20 async fn prepare_static(&self, sql: &'static str) -> Result<Statement, SqlError> {
28 self.prepare(sql).await
29 }
30
31 async fn execute_raw<'a>(
37 &'a self,
38 statement: &Statement,
39 parameters: &[&'a (dyn ToSql + Sync)],
40 ) -> Result<u64, SqlError>;
41
42 async fn query_raw<'a>(
48 &'a self,
49 statement: &Statement,
50 parameters: &[&'a (dyn ToSql + Sync)],
51 ) -> Result<RowStream, SqlError>;
52}
53
54fn slice_iter<'a>(
55 s: &'a [&'a (dyn ToSql + Sync)],
56) -> impl ExactSizeIterator<Item = &'a dyn ToSql> + 'a {
57 s.iter().map(|s| *s as _)
58}
59
60#[async_trait]
61impl GenericClient for Client {
62 async fn prepare(&self, sql: &str) -> Result<Statement, SqlError> {
63 Client::prepare(self, sql).await
64 }
65
66 async fn execute_raw<'a>(
67 &'a self,
68 statement: &Statement,
69 parameters: &[&'a (dyn ToSql + Sync)],
70 ) -> Result<u64, SqlError> {
71 Client::execute_raw(self, statement, slice_iter(parameters)).await
72 }
73
74 async fn query_raw<'a>(
75 &'a self,
76 statement: &Statement,
77 parameters: &[&'a (dyn ToSql + Sync)],
78 ) -> Result<RowStream, SqlError> {
79 Client::query_raw(self, statement, slice_iter(parameters)).await
80 }
81}
82
83#[async_trait]
84impl GenericClient for Transaction<'_> {
85 async fn prepare(&self, sql: &str) -> Result<Statement, SqlError> {
86 Transaction::prepare(self, sql).await
87 }
88
89 async fn execute_raw<'a>(
90 &'a self,
91 statement: &Statement,
92 parameters: &[&'a (dyn ToSql + Sync)],
93 ) -> Result<u64, SqlError> {
94 Transaction::execute_raw::<_, Statement>(self, statement, slice_iter(parameters)).await
95 }
96
97 async fn query_raw<'a>(
98 &'a self,
99 statement: &Statement,
100 parameters: &[&'a (dyn ToSql + Sync)],
101 ) -> Result<RowStream, SqlError> {
102 Transaction::query_raw(self, statement, slice_iter(parameters)).await
103 }
104}
105
106macro_rules! client_deref_impl {
107 ($($target:tt)+) => {
108 #[async_trait]
109 impl<T> GenericClient for $($target)+ where T: GenericClient + Sync {
110 async fn prepare(&self, sql: &str) -> Result<Statement, SqlError> {
111 T::prepare(self, sql).await
112 }
113
114 async fn execute_raw<'a>(
115 &'a self,
116 statement: &Statement,
117 parameters: &[&'a (dyn ToSql + Sync)],
118 ) -> Result<u64, SqlError> {
119 T::execute_raw(self, statement, parameters).await
120 }
121
122 async fn query_raw<'a>(
123 &'a self,
124 statement: &Statement,
125 parameters: &[&'a (dyn ToSql + Sync)],
126 ) -> Result<RowStream, SqlError> {
127 T::query_raw(self, statement, parameters).await
128 }
129 }
130 }
131}
132
133client_deref_impl!(&T);