easy_sqlite/traits/
repo.rs

1#[cfg(feature = "async")]
2use std::future::Future;
3#[cfg(feature = "async")]
4use std::pin::Pin;
5
6use rusqlite::{Connection, Row, ToSql};
7
8use crate::entities::errors::DbResult;
9
10#[cfg(feature = "async")]
11pub(crate) type DynFut<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
12#[cfg(feature = "async")]
13pub(crate) type DynFutDbRes<T> = Pin<Box<dyn Future<Output = DbResult<T>> + Send + 'static>>;
14
15pub trait IConnection {
16    type Locked: IConnection;
17
18    fn lock_sync(&self) -> DbResult<Self::Locked>;
19    fn with<T, F: FnOnce(&Connection) -> DbResult<T>>(&self, fun: F) -> DbResult<T>;
20}
21
22#[cfg(feature = "async")]
23pub trait IAsyncConnection {
24    type Locked: IConnection;
25
26    fn lock_sync(&self) -> DynFut<Self::Locked>;
27    fn with<
28        T: Send + Sync + 'static,
29        F: FnOnce(&Connection) -> DbResult<T> + Send + Sync + 'static,
30    >(
31        &self,
32        fun: F,
33    ) -> DynFutDbRes<T>;
34}
35
36pub trait INewDbRepo<Connection> {
37    fn create(connect: Connection) -> Self;
38}
39
40pub trait IDbRepo {
41    fn as_super(&self) -> &dyn IDbRepo {
42        unimplemented!()
43    }
44    fn init(&self) -> DbResult<()> {
45        self.as_super().init()
46    }
47    fn recreate_tables(&self) -> DbResult<()> {
48        // self.as_super().recreate_table()
49        self.drop()?;
50        self.init()
51    }
52    fn drop(&self) -> DbResult<()> {
53        self.as_super().drop()
54    }
55    fn set_indexes(&self) -> DbResult<()> {
56        self.as_super().set_indexes()
57    }
58    fn drop_indexes(&self) -> DbResult<()> {
59        self.as_super().drop_indexes()
60    }
61    fn get_size(&self) -> DbResult<usize> {
62        self.as_super().get_size()
63    }
64}
65/*
66#[cfg(feature = "async")]
67pub trait IAsyncDbRepo {
68    fn as_super(&self) -> &dyn IAsyncDbRepo {
69        unimplemented!()
70    }
71    fn init(&self) -> DynFutDbRes<()> {
72        self.as_super().init()
73    }
74    fn recreate_tables(&self) -> DynFutDbRes<()> {
75        async fn seq(drop: DynFutDbRes<()>, init: DynFutDbRes<()>) -> DbResult<()> {
76            drop.await?;
77            init.await
78        }
79
80        Box::pin(seq(self.drop(), self.init()))
81    }
82    fn drop(&self) -> DynFutDbRes<()> {
83        self.as_super().drop()
84    }
85    fn set_indexes(&self) -> DynFutDbRes<()> {
86        self.as_super().set_indexes()
87    }
88    fn drop_indexes(&self) -> DynFutDbRes<()> {
89        self.as_super().drop_indexes()
90    }
91    fn get_size(&self) -> DynFutDbRes<usize> {
92        self.as_super().get_size()
93    }
94}
95*/
96
97pub trait IExecutor {
98    type Locked: IExecutor;
99
100    fn lock(&self) -> DbResult<Self::Locked>;
101    fn get_one<T, F: FnMut(&rusqlite::Row<'_>) -> DbResult<T>>(
102        &self,
103        query: &str,
104        params: &[&dyn ToSql],
105        serializer: F,
106    ) -> DbResult<T>;
107    fn get_many<T, F: FnMut(&rusqlite::Row<'_>) -> DbResult<T>>(
108        &self,
109        query: &str,
110        params: &[&dyn ToSql],
111        serializer: F,
112    ) -> DbResult<Vec<T>>;
113    fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<()>;
114    fn execute_return_id(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<i64>;
115}
116
117#[cfg(feature = "async")]
118pub trait IAsyncExecutor {
119    type Locked: IExecutor;
120
121    fn lock(&self) -> DynFut<Self::Locked>;
122    fn get_one<
123        T: Send + Sync + 'static,
124        F: FnMut(&rusqlite::Row<'_>) -> DbResult<T> + Send + Sync + 'static,
125    >(
126        &self,
127        query: &str,
128        params: &[&dyn ToSql],
129        serializer: F,
130    ) -> DynFutDbRes<T>;
131    fn get_many<
132        T: Send + Sync + 'static,
133        F: FnMut(&rusqlite::Row<'_>) -> DbResult<T> + Send + Sync + 'static,
134    >(
135        &self,
136        query: &str,
137        params: &[&dyn ToSql],
138        serializer: F,
139    ) -> DynFutDbRes<Vec<T>>;
140    fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DynFutDbRes<()>;
141}
142
143// ---------------------------
144// ------ IMPLS --------------
145// ---------------------------
146
147impl IConnection for Connection {
148    type Locked = Self;
149
150    fn lock_sync(&self) -> DbResult<Self::Locked> {
151        panic!("Can not lock bare connection")
152    }
153
154    fn with<T, F: FnOnce(&Connection) -> DbResult<T>>(&self, fun: F) -> DbResult<T> {
155        fun(self)
156    }
157}
158
159#[cfg(feature = "async")]
160impl IAsyncConnection for Connection {
161    type Locked = Self;
162
163    fn lock_sync(&self) -> DynFut<Self::Locked> {
164        panic!("Can not lock bare connection")
165    }
166
167    fn with<
168        T: Send + Sync + 'static,
169        F: FnOnce(&Connection) -> DbResult<T> + Send + Sync + 'static,
170    >(
171        &self,
172        fun: F,
173    ) -> DynFutDbRes<T> {
174        let res = fun(self);
175        Box::pin(async move { res })
176    }
177}
178
179impl<Cnn: IConnection> IConnection for &Cnn {
180    type Locked = Cnn::Locked;
181
182    fn lock_sync(&self) -> DbResult<Self::Locked> {
183        (**self).lock_sync()
184    }
185
186    fn with<T, F: FnOnce(&Connection) -> DbResult<T>>(&self, fun: F) -> DbResult<T> {
187        (**self).with(fun)
188    }
189}
190
191#[cfg(feature = "async")]
192impl<Cnn: IAsyncConnection> IAsyncConnection for &Cnn {
193    type Locked = Cnn::Locked;
194
195    fn lock_sync(&self) -> DynFut<Self::Locked> {
196        (**self).lock_sync()
197    }
198
199    fn with<
200        T: Send + Sync + 'static,
201        F: FnOnce(&Connection) -> DbResult<T> + Send + Sync + 'static,
202    >(
203        &self,
204        fun: F,
205    ) -> DynFutDbRes<T> {
206        (**self).with(fun)
207    }
208}
209
210impl<Ex: IExecutor> IExecutor for &Ex {
211    type Locked = Ex::Locked;
212
213    fn lock(&self) -> DbResult<Self::Locked> {
214        (**self).lock()
215    }
216
217    fn get_one<T, F: FnMut(&Row<'_>) -> DbResult<T>>(
218        &self,
219        query: &str,
220        params: &[&dyn ToSql],
221        serializer: F,
222    ) -> DbResult<T> {
223        (**self).get_one(query, params, serializer)
224    }
225
226    fn get_many<T, F: FnMut(&Row<'_>) -> DbResult<T>>(
227        &self,
228        query: &str,
229        params: &[&dyn ToSql],
230        serializer: F,
231    ) -> DbResult<Vec<T>> {
232        (**self).get_many(query, params, serializer)
233    }
234
235    fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<()> {
236        (**self).execute(query, params)
237    }
238
239    fn execute_return_id(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<i64> {
240        (**self).execute_return_id(query, params)
241    }
242}
243
244#[cfg(feature = "async")]
245impl<Ex: IAsyncExecutor> IAsyncExecutor for &Ex {
246    type Locked = Ex::Locked;
247
248    fn lock(&self) -> DynFut<Self::Locked> {
249        (**self).lock()
250    }
251
252    fn get_one<
253        T: Send + Sync + 'static,
254        F: FnMut(&Row<'_>) -> DbResult<T> + Send + Sync + 'static,
255    >(
256        &self,
257        query: &str,
258        params: &[&dyn ToSql],
259        serializer: F,
260    ) -> DynFutDbRes<T> {
261        (**self).get_one(query, params, serializer)
262    }
263
264    fn get_many<
265        T: Send + Sync + 'static,
266        F: FnMut(&Row<'_>) -> DbResult<T> + Send + Sync + 'static,
267    >(
268        &self,
269        query: &str,
270        params: &[&dyn ToSql],
271        serializer: F,
272    ) -> DynFutDbRes<Vec<T>> {
273        (**self).get_many(query, params, serializer)
274    }
275
276    fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DynFutDbRes<()> {
277        (**self).execute(query, params)
278    }
279}