sea_orm/executor/select/
four.rs

1use super::*;
2use crate::{
3    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,
4    SelectC, SelectFive, SelectFour, Topology, TopologyStar,
5    combine::{SelectD, prepare_select_col},
6};
7
8impl<E, F, G, H, TOP> SelectFour<E, F, G, H, TOP>
9where
10    E: EntityTrait,
11    F: EntityTrait,
12    G: EntityTrait,
13    H: EntityTrait,
14    TOP: Topology,
15{
16    pub(crate) fn new(query: SelectStatement) -> Self {
17        Self::new_without_prepare(query).prepare_select()
18    }
19
20    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {
21        Self {
22            query,
23            entity: PhantomData,
24        }
25    }
26
27    fn prepare_select(mut self) -> Self {
28        prepare_select_col::<H, _, _>(&mut self, SelectD);
29        self
30    }
31
32    /// Left Join with a Related Entity and select all Entities.
33    pub fn find_also<T, I>(self, _: T, _: I) -> SelectFive<E, F, G, H, I, TopologyStar>
34    where
35        I: EntityTrait,
36        T: EntityTrait + Related<I>,
37    {
38        SelectFive::new(
39            self.join_join(JoinType::LeftJoin, T::to(), T::via())
40                .into_query(),
41        )
42    }
43}
44
45macro_rules! impl_query_trait {
46    ( $trait: ident ) => {
47        impl<E, F, G, H, TOP> $trait for SelectFour<E, F, G, H, TOP>
48        where
49            E: EntityTrait,
50            F: EntityTrait,
51            G: EntityTrait,
52            H: EntityTrait,
53            TOP: Topology,
54        {
55            type QueryStatement = SelectStatement;
56
57            fn query(&mut self) -> &mut SelectStatement {
58                &mut self.query
59            }
60        }
61    };
62}
63
64impl<E, F, G, H, TOP> QueryTrait for SelectFour<E, F, G, H, TOP>
65where
66    E: EntityTrait,
67    F: EntityTrait,
68    G: EntityTrait,
69    H: EntityTrait,
70    TOP: Topology,
71{
72    type QueryStatement = SelectStatement;
73    fn query(&mut self) -> &mut SelectStatement {
74        &mut self.query
75    }
76    fn as_query(&self) -> &SelectStatement {
77        &self.query
78    }
79    fn into_query(self) -> SelectStatement {
80        self.query
81    }
82}
83
84impl_query_trait!(QuerySelect);
85impl_query_trait!(QueryFilter);
86impl_query_trait!(QueryOrder);
87
88impl<M, N, O, P> SelectorTrait for SelectFourModel<M, N, O, P>
89where
90    M: FromQueryResult + Sized,
91    N: FromQueryResult + Sized,
92    O: FromQueryResult + Sized,
93    P: FromQueryResult + Sized,
94{
95    type Item = (M, Option<N>, Option<O>, Option<P>);
96
97    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
98        Ok((
99            M::from_query_result(&res, SelectA.as_str())?,
100            N::from_query_result_optional(&res, SelectB.as_str())?,
101            O::from_query_result_optional(&res, SelectC.as_str())?,
102            P::from_query_result_optional(&res, SelectD.as_str())?,
103        ))
104    }
105}
106
107impl<E, F, G, H, TOP> SelectFour<E, F, G, H, TOP>
108where
109    E: EntityTrait,
110    F: EntityTrait,
111    G: EntityTrait,
112    H: EntityTrait,
113    TOP: Topology,
114{
115    /// Perform a conversion into a [SelectFourModel]
116    pub fn into_model<M, N, O, P>(self) -> Selector<SelectFourModel<M, N, O, P>>
117    where
118        M: FromQueryResult,
119        N: FromQueryResult,
120        O: FromQueryResult,
121        P: FromQueryResult,
122    {
123        Selector {
124            query: self.query,
125            selector: PhantomData,
126        }
127    }
128
129    /// Perform a conversion into a [SelectFourModel] with [PartialModel](PartialModelTrait)
130    pub fn into_partial_model<M, N, O, P>(self) -> Selector<SelectFourModel<M, N, O, P>>
131    where
132        M: PartialModelTrait,
133        N: PartialModelTrait,
134        O: PartialModelTrait,
135        P: PartialModelTrait,
136    {
137        let select = QuerySelect::select_only(self);
138        let select = M::select_cols(select);
139        let select = N::select_cols(select);
140        let select = O::select_cols(select);
141        let select = P::select_cols(select);
142        select.into_model::<M, N, O, P>()
143    }
144
145    /// Convert the Models into JsonValue
146    #[cfg(feature = "with-json")]
147    pub fn into_json(
148        self,
149    ) -> Selector<SelectFourModel<JsonValue, JsonValue, JsonValue, JsonValue>> {
150        Selector {
151            query: self.query,
152            selector: PhantomData,
153        }
154    }
155
156    /// Get one Model from the Select query
157    pub fn one<C>(
158        self,
159        db: &C,
160    ) -> Result<
161        Option<(
162            E::Model,
163            Option<F::Model>,
164            Option<G::Model>,
165            Option<H::Model>,
166        )>,
167        DbErr,
168    >
169    where
170        C: ConnectionTrait,
171    {
172        self.into_model().one(db)
173    }
174
175    /// Get all Models from the Select query
176    pub fn all<C>(
177        self,
178        db: &C,
179    ) -> Result<
180        Vec<(
181            E::Model,
182            Option<F::Model>,
183            Option<G::Model>,
184            Option<H::Model>,
185        )>,
186        DbErr,
187    >
188    where
189        C: ConnectionTrait,
190    {
191        self.into_model().all(db)
192    }
193
194    /// Stream the results of a Select operation on a Model
195    pub fn stream<'a: 'b, 'b, C>(
196        self,
197        db: &'a C,
198    ) -> Result<
199        impl Iterator<
200            Item = Result<
201                (
202                    E::Model,
203                    Option<F::Model>,
204                    Option<G::Model>,
205                    Option<H::Model>,
206                ),
207                DbErr,
208            >,
209        > + 'b,
210        DbErr,
211    >
212    where
213        C: ConnectionTrait + StreamTrait,
214    {
215        self.into_model().stream(db)
216    }
217
218    /// Stream the result of the operation with PartialModel
219    pub fn stream_partial_model<'a: 'b, 'b, C, M, N, O, P>(
220        self,
221        db: &'a C,
222    ) -> Result<impl Iterator<Item = Result<(M, Option<N>, Option<O>, Option<P>), DbErr>> + 'b, DbErr>
223    where
224        C: ConnectionTrait + StreamTrait,
225        M: PartialModelTrait + 'b,
226        N: PartialModelTrait + 'b,
227        O: PartialModelTrait + 'b,
228        P: PartialModelTrait + 'b,
229    {
230        self.into_partial_model().stream(db)
231    }
232}
233
234impl<'db, C, EE, FF, GG, HH, E, F, G, H, TOP> PaginatorTrait<'db, C> for SelectFour<E, F, G, H, TOP>
235where
236    C: ConnectionTrait,
237    E: EntityTrait<Model = EE>,
238    F: EntityTrait<Model = FF>,
239    G: EntityTrait<Model = GG>,
240    H: EntityTrait<Model = HH>,
241    EE: FromQueryResult + Sized + 'db,
242    FF: FromQueryResult + Sized + 'db,
243    GG: FromQueryResult + Sized + 'db,
244    HH: FromQueryResult + Sized + 'db,
245    TOP: Topology,
246{
247    type Selector = SelectFourModel<EE, FF, GG, HH>;
248
249    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {
250        self.into_model().paginate(db, page_size)
251    }
252}