sea_orm/dynamic/
execute.rs1use crate::{
2 ConnectionTrait, DbBackend, DbErr, EntityTrait, FromQueryResult, QueryResult, Select,
3 Statement, dynamic,
4};
5use itertools::Itertools;
6use sea_query::{DynIden, Expr, IntoIden, SelectStatement};
7use std::marker::PhantomData;
8
9#[derive(Debug)]
10pub struct SelectModelAndDynModel<M>
11where
12 M: FromQueryResult,
13{
14 model: PhantomData<M>,
15 dyn_model: dynamic::ModelType,
16}
17
18#[derive(Clone, Debug)]
19pub struct DynSelector<S>
20where
21 S: DynSelectorTrait,
22{
23 pub(crate) query: SelectStatement,
24 selector: S,
25}
26
27pub trait DynSelectorTrait {
28 type Item: Sized;
29
30 #[allow(clippy::wrong_self_convention)]
31 fn from_raw_query_result(&self, res: QueryResult) -> Result<Self::Item, DbErr>;
32}
33
34impl<M> DynSelectorTrait for SelectModelAndDynModel<M>
35where
36 M: FromQueryResult + Sized,
37{
38 type Item = (M, dynamic::Model);
39
40 fn from_raw_query_result(&self, res: QueryResult) -> Result<Self::Item, DbErr> {
41 Ok((
42 M::from_query_result(&res, "")?,
43 self.dyn_model.from_query_result(&res, "")?,
44 ))
45 }
46}
47
48impl<E> Select<E>
49where
50 E: EntityTrait,
51{
52 pub fn select_also_dyn_model(
53 mut self,
54 table: DynIden,
55 dyn_model: dynamic::ModelType,
56 ) -> DynSelector<SelectModelAndDynModel<E::Model>> {
57 for field in dyn_model.fields.iter() {
58 self.query.expr(Expr::col((
59 table.clone(),
60 field.field().to_owned().into_iden(),
61 )));
62 }
63 DynSelector {
64 query: self.query,
65 selector: SelectModelAndDynModel {
66 model: PhantomData,
67 dyn_model,
68 },
69 }
70 }
71}
72
73impl<S> DynSelector<S>
74where
75 S: DynSelectorTrait,
76{
77 pub fn into_statement(self, builder: DbBackend) -> Statement {
79 builder.build(&self.query)
80 }
81
82 pub fn one<C>(mut self, db: &C) -> Result<Option<S::Item>, DbErr>
84 where
85 C: ConnectionTrait,
86 {
87 self.query.limit(1);
88 let row = db.query_one(&self.query)?;
89 match row {
90 Some(row) => Ok(Some(self.selector.from_raw_query_result(row)?)),
91 None => Ok(None),
92 }
93 }
94
95 pub fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>
97 where
98 C: ConnectionTrait,
99 {
100 db.query_all(&self.query)?
101 .into_iter()
102 .map(|row| self.selector.from_raw_query_result(row))
103 .try_collect()
104 }
105}