sea_orm/dynamic/
execute.rs

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