sea_orm/dynamic/
execute.rs1use 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 pub fn into_statement(self, builder: DbBackend) -> Statement {
78 builder.build(&self.query)
79 }
80
81 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 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}