taitan_orm/executors/
sql_generic_executor.rs

1use sqlx::query::Query;
2use sqlx::{Database, Executor, IntoArguments, Type};
3use std::marker::PhantomData;
4
5use taitan_orm_trait::error::TaitanOrmError;
6use taitan_orm_trait::result::Result;
7use taitan_orm_trait::traits::Selected;
8/**
9本模块提供2个维度的封装
101. 结果的转化,上层抽象不再感知Row和QueryResult的存在
11QueryResult -> u64
12Vec<Row>    -> Vec<SE>
13Row         -> SE
14Option<Row> -> Option<SE>
15Option<Row> -> bool
162. sqlx::query::Query结构体的封装,上层抽象不再感知这个结构体的存在
17
18本模块提供以下泛型接口函数
19
20
21generic_execute           (ex, stmt, args) -> Result<u64>
22generic_execute_plain     (ex, stmt, _   ) -> Result<u64>
23
24generic_exists            (ex, stmt, args) -> Result<bool>
25generic_exists_plain      (ex, stmt, _   ) -> Result<bool>
26generic_count            (ex, stmt, args) -> Result<bool>
27generic_count_plain      (ex, stmt, _   ) -> Result<bool>
28
29generic_fetch_all         (ex, stmt, selection, args) -> Result<Vec<SE>>
30generic_fetch_all_plain   (ex, stmt, selection, _   ) -> Result<Vec<SE>>
31generic_fetch_one         (ex, stmt, selection, args) -> Result<SE>
32generic_fetch_one_plain   (ex, stmt, selection, _   ) -> Result<SE>
33generic_fetch_option      (ex, stmt, selection, args) -> Result<Option<SE>>
34generic_fetch_option_plain(ex, stmt, selection, _   ) -> Result<Option<SE>>
35
36generic_fetch_all_         (ex, stmt, se, args) -> Result<Vec<SE>>
37generic_fetch_all_plain_   (ex, stmt, se, _   ) -> Result<Vec<SE>>
38generic_fetch_one_         (ex, stmt, se, args) -> Result<SE>
39generic_fetch_one_plain_   (ex, stmt, se, _   ) -> Result<SE>
40generic_fetch_option_      (ex, stmt, se, args) -> Result<Option<SE>>
41generic_fetch_option_plain_(ex, stmt, se, _   ) -> Result<Option<SE>>
42
43
44generic_fetch_all_full         (ex, stmt, args) -> Result<Vec<SE>>
45generic_fetch_all_full_plain   (ex, stmt, _   ) -> Result<Vec<SE>>
46generic_fetch_one_full         (ex, stmt, args) -> Result<SE>
47generic_fetch_one_full_plain   (ex, stmt, _   ) -> Result<SE>
48generic_fetch_option_full      (ex, stmt, args) -> Result<Option<SE>>
49generic_fetch_option_full_plain(ex, stmt, _   ) -> Result<Option<SE>>
50**/
51
52pub trait SqlGenericExecutor
53where
54    i64: Type<Self::DB>,
55    for<'a> i64: sqlx::Encode<'a, Self::DB>
56{
57    type DB: Database;
58    type CountType: Selected<Self::DB>;
59
60    fn get_affected_rows(query_result: &<Self::DB as Database>::QueryResult) -> u64;
61
62    // 1. generic_exists           (ex, stmt, args) -> Result<bool>
63    async fn generic_exists<'a, EX, A>(ex: EX, stmt: &'a str, args: A) -> Result<bool>
64    where
65        EX: Executor<'a, Database = Self::DB>,
66        A: IntoArguments<'a, Self::DB> + 'a,
67    {
68        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
69        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
70        if let Some(_) = result_opt {
71            Ok(true)
72        } else {
73            Ok(false)
74        }
75    }
76
77    // 2. generic_exists           (ex, stmt, args) -> Result<bool>
78    async fn generic_exists_plain<'a, EX, A>(
79        ex: EX,
80        stmt: &'a str,
81        _args: PhantomData<A>,
82    ) -> Result<bool>
83    where
84        EX: Executor<'a, Database = Self::DB>,
85        A: IntoArguments<'a, Self::DB> + 'a + Default,
86    {
87        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
88        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
89        if let Some(_) = result_opt {
90            Ok(true)
91        } else {
92            Ok(false)
93        }
94    }
95
96    // generic_count            (ex, stmt, args) -> Result<bool>
97    async fn generic_count<'s, 'a, EX, A>(ex: EX, stmt: &'s str, args: A) -> Result<Self::CountType>
98    where
99        's: 'a,
100        EX: Executor<'a, Database = Self::DB>,
101        A: IntoArguments<'a, Self::DB> + 'a,
102    {
103        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
104        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
105        if let Some(row) = result_opt {
106            Ok(Self::CountType::from_row(&Self::CountType::default(), row)?)
107        } else {
108            Ok(Default::default())
109        }
110    }
111
112    // generic_count_plain      (ex, stmt, _   ) -> Result<bool>
113    async fn generic_count_plain<'a, EX, A>(
114        ex: EX,
115        stmt: &'a str,
116        _args: PhantomData<A>,
117    ) -> Result<Self::CountType>
118    where
119        EX: Executor<'a, Database = Self::DB>,
120        A: IntoArguments<'a, Self::DB> + 'a + Default,
121    {
122        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
123        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
124        if let Some(row) = result_opt {
125            Ok(Self::CountType::from_row_full(row)?)
126        } else {
127            Ok(Default::default())
128        }
129    }
130
131    // 3. generic_execute           (ex, stmt, args) -> Result<u64>
132    async fn generic_execute<'a, 'e, EX, A>(ex: EX, query: &'a str, args: A) -> Result<u64>
133    where
134        EX: Executor<'e, Database = Self::DB>,
135        A: IntoArguments<'a, Self::DB> + 'a,
136    {
137        let query: Query<'a, Self::DB, A> = sqlx::query_with(query, args);
138        let result: <Self::DB as Database>::QueryResult = query.execute(ex).await?;
139        Ok(Self::get_affected_rows(&result))
140    }
141
142    // 4. generic_execute_plain     (ex, stmt, _   ) -> Result<u64>
143    async fn generic_execute_plain<'a, EX, A>(
144        ex: EX,
145        query: &'a str,
146        _args: PhantomData<A>,
147    ) -> Result<u64>
148    where
149        EX: Executor<'a, Database = Self::DB>,
150        A: IntoArguments<'a, Self::DB> + 'a + Default,
151    {
152        let query: Query<'a, Self::DB, A> = sqlx::query_with(query, Default::default());
153        let result: <Self::DB as Database>::QueryResult = query.execute(ex).await?;
154        Ok(Self::get_affected_rows(&result))
155    }
156
157    // 5. generic_fetch_all         (ex, stmt, selection, args) -> Result<Vec<SE>>
158    async fn generic_fetch_all<'a, EX, SE, A>(
159        ex: EX,
160        stmt: &'a str,
161        selection: &SE,
162        args: A,
163    ) -> Result<Vec<SE>>
164    where
165        EX: Executor<'a, Database = Self::DB>,
166        SE: Selected<Self::DB> + Send + Unpin,
167        A: IntoArguments<'a, Self::DB> + 'a + Default,
168    {
169        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
170        let result_opt: Vec<<Self::DB as Database>::Row> = query.fetch_all(ex).await?;
171        let mut result: Vec<SE> = Vec::new();
172        for row in result_opt {
173            let selected_result = SE::from_row(selection, row);
174            if let Ok(selected_entity) = selected_result {
175                result.push(selected_entity);
176            } else {
177                return Err(TaitanOrmError::DecodeError("".to_string()));
178            }
179        }
180        Ok(result)
181    }
182
183    async fn generic_fetch_all_<'a, EX, SE, A>(
184        ex: EX,
185        stmt: &'a str,
186        selection: &SE,
187        args: A,
188    ) -> Result<Vec<SE>>
189    where
190        EX: Executor<'a, Database = Self::DB>,
191        SE: Selected<Self::DB> + Send + Unpin,
192        A: IntoArguments<'a, Self::DB> + 'a + Default,
193    {
194        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
195        let result_opt: Vec<<Self::DB as Database>::Row> = query.fetch_all(ex).await?;
196        let mut result: Vec<SE> = Vec::new();
197        for row in result_opt {
198            let selected_result = SE::from_row(selection, row);
199            if let Ok(selected_entity) = selected_result {
200                result.push(selected_entity);
201            } else {
202                return Err(TaitanOrmError::DecodeError("".to_string()));
203            }
204        }
205        Ok(result)
206    }
207
208    // 6. generic_fetch_all_plain   (ex, stmt, selection, _   ) -> Result<Vec<SE>>
209    async fn generic_fetch_all_plain<'a, EX, SE, A>(
210        ex: EX,
211        stmt: &'a str,
212        selection: &SE,
213        _: PhantomData<A>,
214    ) -> Result<Vec<SE>>
215    where
216        EX: Executor<'a, Database = Self::DB>,
217        SE: Selected<Self::DB> + Send + Unpin,
218        A: IntoArguments<'a, Self::DB> + 'a + Default,
219    {
220        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
221        let result_opt: Vec<<Self::DB as Database>::Row> = query.fetch_all(ex).await?;
222        let mut result: Vec<SE> = Vec::new();
223        for row in result_opt {
224            let selected_result = SE::from_row(selection, row);
225            if let Ok(selected_entity) = selected_result {
226                result.push(selected_entity);
227            } else {
228                return Err(TaitanOrmError::DecodeError("".to_string()));
229            }
230        }
231        Ok(result)
232    }
233
234    async fn generic_fetch_all_plain_<'a, EX, SE, A>(
235        ex: EX,
236        stmt: &'a str,
237        selection: &SE,
238        _: PhantomData<A>,
239    ) -> Result<Vec<SE>>
240    where
241        EX: Executor<'a, Database = Self::DB>,
242        SE: Selected<Self::DB> + Send + Unpin,
243        A: IntoArguments<'a, Self::DB> + 'a + Default,
244    {
245        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
246        let result_opt: Vec<<Self::DB as Database>::Row> = query.fetch_all(ex).await?;
247        let mut result: Vec<SE> = Vec::new();
248        for row in result_opt {
249            let selected_result = SE::from_row(selection, row);
250            if let Ok(selected_entity) = selected_result {
251                result.push(selected_entity);
252            } else {
253                return Err(TaitanOrmError::DecodeError("".to_string()));
254            }
255        }
256        Ok(result)
257    }
258
259    // 7. generic_fetch_one         (ex, stmt, selection, args) -> Result<SE>
260    async fn generic_fetch_one<'a, EX, SE, A>(
261        ex: EX,
262        stmt: &'a str,
263        selection: &SE,
264        args: A,
265    ) -> Result<SE>
266    where
267        EX: Executor<'a, Database = Self::DB>,
268        SE: Selected<Self::DB> + Send + Unpin,
269        A: IntoArguments<'a, Self::DB> + 'a,
270    {
271        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
272        let result: <Self::DB as Database>::Row = query.fetch_one(ex).await?;
273        Ok(SE::from_row(selection, result)?)
274    }
275
276    async fn generic_fetch_one_<'a, EX, SE, A>(
277        ex: EX,
278        stmt: &'a str,
279        selection: &SE,
280        args: A,
281    ) -> Result<SE>
282    where
283        EX: Executor<'a, Database = Self::DB>,
284        SE: Selected<Self::DB> + Send + Unpin,
285        A: IntoArguments<'a, Self::DB> + 'a,
286    {
287        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
288        let result: <Self::DB as Database>::Row = query.fetch_one(ex).await?;
289        Ok(SE::from_row(selection, result)?)
290    }
291
292    // 8. generic_fetch_one_plain   (ex, stmt, selection, _   ) -> Result<SE>
293    async fn generic_fetch_one_plain<'a, EX, SE, A>(
294        ex: EX,
295        stmt: &'a str,
296        selection: &SE,
297        _: PhantomData<A>,
298    ) -> Result<SE>
299    where
300        EX: Executor<'a, Database = Self::DB>,
301        SE: Selected<Self::DB> + Send + Unpin,
302        A: IntoArguments<'a, Self::DB> + 'a + Default,
303    {
304        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
305        let result: <Self::DB as Database>::Row = query.fetch_one(ex).await?;
306        Ok(SE::from_row(selection, result)?)
307    }
308
309    async fn generic_fetch_one_plain_<'a, EX, SE, A>(
310        ex: EX,
311        stmt: &'a str,
312        selection: &SE,
313        _: PhantomData<A>,
314    ) -> Result<SE>
315    where
316        EX: Executor<'a, Database = Self::DB>,
317        SE: Selected<Self::DB> + Send + Unpin,
318        A: IntoArguments<'a, Self::DB> + 'a + Default,
319    {
320        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
321        let result: <Self::DB as Database>::Row = query.fetch_one(ex).await?;
322        Ok(SE::from_row(selection, result)?)
323    }
324
325    // 9. generic_fetch_option      (ex, stmt, selection, args) -> Result<Option<SE>>
326    async fn generic_fetch_option<'a, EX, SE, A>(
327        ex: EX,
328        stmt: &'a str,
329        selection: &SE,
330        args: A,
331    ) -> Result<Option<SE>>
332    where
333        EX: Executor<'a, Database = Self::DB>,
334        SE: Selected<Self::DB> + Send + Unpin,
335        A: IntoArguments<'a, Self::DB> + 'a + Default,
336    {
337        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
338        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
339        if let Some(result) = result_opt {
340            Ok(Some(SE::from_row(selection, result)?))
341        } else {
342            Ok(None)
343        }
344    }
345
346    async fn generic_fetch_option_<'a, EX, SE, A>(
347        ex: EX,
348        stmt: &'a str,
349        selection: &SE,
350        args: A,
351    ) -> Result<Option<SE>>
352    where
353        EX: Executor<'a, Database = Self::DB>,
354        SE: Selected<Self::DB> + Send + Unpin,
355        A: IntoArguments<'a, Self::DB> + 'a + Default,
356    {
357        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
358        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
359        if let Some(result) = result_opt {
360            Ok(Some(SE::from_row(selection, result)?))
361        } else {
362            Ok(None)
363        }
364    }
365
366    // 10. generic_fetch_option_plain(ex, stmt, selection, _   ) -> Result<Option<SE>>
367    async fn generic_fetch_option_plain<'a, EX, SE, A>(
368        ex: EX,
369        stmt: &'a str,
370        selection: &SE,
371        _: PhantomData<A>,
372    ) -> Result<Option<SE>>
373    where
374        EX: Executor<'a, Database = Self::DB>,
375        SE: Selected<Self::DB> + Send + Unpin,
376        A: IntoArguments<'a, Self::DB> + 'a + Default,
377    {
378        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
379        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
380        if let Some(result) = result_opt {
381            Ok(Some(SE::from_row(selection, result)?))
382        } else {
383            Ok(None)
384        }
385    }
386
387    async fn generic_fetch_option_plain_<'a, EX, SE, A>(
388        ex: EX,
389        stmt: &'a str,
390        selection: &SE,
391        _: PhantomData<A>,
392    ) -> Result<Option<SE>>
393    where
394        EX: Executor<'a, Database = Self::DB>,
395        SE: Selected<Self::DB> + Send + Unpin,
396        A: IntoArguments<'a, Self::DB> + 'a + Default,
397    {
398        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
399        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
400        if let Some(result) = result_opt {
401            Ok(Some(SE::from_row(selection, result)?))
402        } else {
403            Ok(None)
404        }
405    }
406
407    // 11.  generic_fetch_all_full         (ex, stmt, args) -> Result<Vec<SE>>
408    async fn generic_fetch_all_full<'a, EX, SE, A>(
409        ex: EX,
410        stmt: &'a str,
411        args: A,
412    ) -> Result<Vec<SE>>
413    where
414        EX: Executor<'a, Database = Self::DB>,
415        SE: Selected<Self::DB> + Send + Unpin,
416        A: IntoArguments<'a, Self::DB> + 'a,
417    {
418        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
419        let result_vec: Vec<<Self::DB as Database>::Row> = query.fetch_all(ex).await?;
420        let mut result: Vec<SE> = Vec::new();
421        for row in result_vec {
422            result.push(SE::from_row(&SE::default(), row)?);
423        }
424        Ok(result)
425    }
426
427    // 12. generic_fetch_all_full_plain   (ex, stmt, _   ) -> Result<Vec<SE>>
428    async fn generic_fetch_all_full_plain<'a, EX, SE, A>(
429        ex: EX,
430        stmt: &'a str,
431        _: PhantomData<A>,
432    ) -> Result<Vec<SE>>
433    where
434        EX: Executor<'a, Database = Self::DB>,
435        SE: Selected<Self::DB> + Send + Unpin,
436        A: IntoArguments<'a, Self::DB> + 'a + Default,
437    {
438        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
439        let result_vec: Vec<<Self::DB as Database>::Row> = query.fetch_all(ex).await?;
440        let mut result: Vec<SE> = Vec::new();
441        for row in result_vec {
442            result.push(SE::from_row_full(row)?);
443        }
444        Ok(result)
445    }
446
447    // 13. generic_fetch_one_full         (ex, stmt, args) -> Result<SE>
448    async fn generic_fetch_one_full<'a, EX, SE, A>(ex: EX, stmt: &'a str, args: A) -> Result<SE>
449    where
450        EX: Executor<'a, Database = Self::DB>,
451        SE: Selected<Self::DB> + Send + Unpin,
452        A: IntoArguments<'a, Self::DB> + 'a,
453    {
454        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
455        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
456        if let Some(result) = result_opt {
457            Ok(SE::from_row_full(result)?)
458        } else {
459            Err(sqlx::error::Error::RowNotFound.into())
460        }
461    }
462
463    // 14. generic_fetch_one_full_plain   (ex, stmt, _   ) -> Result<SE>
464    async fn generic_fetch_one_full_plain<'a, EX, SE, A>(
465        ex: EX,
466        stmt: &'a str,
467        _: PhantomData<A>,
468    ) -> Result<SE>
469    where
470        EX: Executor<'a, Database = Self::DB>,
471        SE: Selected<Self::DB> + Send + Unpin,
472        A: IntoArguments<'a, Self::DB> + 'a + Default,
473    {
474        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
475        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
476        if let Some(result) = result_opt {
477            Ok(SE::from_row_full(result)?)
478        } else {
479            Err(sqlx::error::Error::RowNotFound.into())
480        }
481    }
482
483    // 15. generic_fetch_option_full      (ex, stmt, args) -> Result<Option<SE>>
484    async fn generic_fetch_option_full<'a, EX, SE, A>(
485        ex: EX,
486        stmt: &'a str,
487        args: A,
488    ) -> Result<Option<SE>>
489    where
490        EX: Executor<'a, Database = Self::DB>,
491        SE: Selected<Self::DB> + Send + Unpin,
492        A: IntoArguments<'a, Self::DB> + 'a,
493    {
494        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, args);
495        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
496        if let Some(result) = result_opt {
497            Ok(Some(SE::from_row_full(result)?))
498        } else {
499            Ok(None)
500        }
501    }
502
503    // 16. generic_fetch_option_full_plain(ex, stmt, _   ) -> Result<Option<SE>>
504    async fn generic_fetch_option_full_plain<'a, EX, SE, A>(
505        ex: EX,
506        stmt: &'a str,
507        _: PhantomData<A>,
508    ) -> Result<Option<SE>>
509    where
510        EX: Executor<'a, Database = Self::DB>,
511        SE: Selected<Self::DB> + Send + Unpin,
512        A: IntoArguments<'a, Self::DB> + 'a + Default,
513    {
514        let query: Query<'a, Self::DB, A> = sqlx::query_with(stmt, Default::default());
515        let result_opt: Option<<Self::DB as Database>::Row> = query.fetch_optional(ex).await?;
516        if let Some(result) = result_opt {
517            Ok(Some(SE::from_row(&SE::default(), result)?))
518        } else {
519            Ok(None)
520        }
521    }
522}