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 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 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 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 #[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 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 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 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 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}