1use crate::{
2 ColumnTrait, EntityTrait, Iterable, Order, PrimaryKeyToColumn, QueryFilter, QueryOrder,
3 QuerySelect, QueryTrait,
4};
5use core::fmt::Debug;
6use core::marker::PhantomData;
7use sea_query::{FunctionCall, IntoColumnRef, IntoIden, SelectExpr, SelectStatement, SimpleExpr};
8
9#[derive(Clone, Debug)]
15pub struct Select<E>
16where
17 E: EntityTrait,
18{
19 pub(crate) query: SelectStatement,
20 pub(crate) entity: PhantomData<E>,
21 pub(crate) linked_index: usize,
22}
23
24#[derive(Clone, Debug)]
28pub struct SelectTwo<E, F>
29where
30 E: EntityTrait,
31 F: EntityTrait,
32{
33 pub(crate) query: SelectStatement,
34 pub(crate) entity: PhantomData<(E, F)>,
35}
36
37#[derive(Clone, Debug)]
41pub struct SelectTwoMany<E, F>
42where
43 E: EntityTrait,
44 F: EntityTrait,
45{
46 pub(crate) query: SelectStatement,
47 pub(crate) entity: PhantomData<(E, F)>,
48}
49
50#[derive(Clone, Debug)]
53pub struct SelectTwoRequired<E, F>
54where
55 E: EntityTrait,
56 F: EntityTrait,
57{
58 pub(crate) query: SelectStatement,
59 pub(crate) entity: PhantomData<(E, F)>,
60}
61
62pub trait Topology {}
66
67#[derive(Debug, Clone)]
69pub struct TopologyStar;
70
71#[derive(Debug, Clone)]
73pub struct TopologyChain;
74
75impl Topology for TopologyStar {}
76impl Topology for TopologyChain {}
77
78#[derive(Clone, Debug)]
81pub struct SelectThree<E, F, G, TOP>
82where
83 E: EntityTrait,
84 F: EntityTrait,
85 G: EntityTrait,
86 TOP: Topology,
87{
88 pub(crate) query: SelectStatement,
89 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
90}
91
92#[derive(Clone, Debug)]
95pub struct SelectThreeMany<E, F, G, TOP>
96where
97 E: EntityTrait,
98 F: EntityTrait,
99 G: EntityTrait,
100 TOP: Topology,
101{
102 pub(crate) query: SelectStatement,
103 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
104}
105
106#[derive(Clone, Debug)]
108pub struct SelectFour<E, F, G, H, TOP>
109where
110 E: EntityTrait,
111 F: EntityTrait,
112 G: EntityTrait,
113 H: EntityTrait,
114 TOP: Topology,
115{
116 pub(crate) query: SelectStatement,
117 pub(crate) entity: PhantomData<(E, F, G, H, TOP)>,
118}
119
120#[derive(Clone, Debug)]
122pub struct SelectFourMany<E, F, G, H, TOP>
123where
124 E: EntityTrait,
125 F: EntityTrait,
126 G: EntityTrait,
127 H: EntityTrait,
128 TOP: Topology,
129{
130 pub(crate) query: SelectStatement,
131 pub(crate) entity: PhantomData<(E, F, G, H, TOP)>,
132}
133
134#[derive(Clone, Debug)]
136pub struct SelectFive<E, F, G, H, I, TOP>
137where
138 E: EntityTrait,
139 F: EntityTrait,
140 G: EntityTrait,
141 H: EntityTrait,
142 I: EntityTrait,
143 TOP: Topology,
144{
145 pub(crate) query: SelectStatement,
146 pub(crate) entity: PhantomData<(E, F, G, H, I, TOP)>,
147}
148
149#[derive(Clone, Debug)]
151pub struct SelectSix<E, F, G, H, I, J, TOP>
152where
153 E: EntityTrait,
154 F: EntityTrait,
155 G: EntityTrait,
156 H: EntityTrait,
157 I: EntityTrait,
158 J: EntityTrait,
159 TOP: Topology,
160{
161 pub(crate) query: SelectStatement,
162 pub(crate) entity: PhantomData<(E, F, G, H, I, J, TOP)>,
163}
164
165pub trait IntoSimpleExpr {
168 fn into_simple_expr(self) -> SimpleExpr;
170}
171
172pub trait ColumnAsExpr: IntoSimpleExpr {
175 fn into_column_as_expr(self) -> SimpleExpr;
178}
179
180macro_rules! impl_query_trait {
181 ( $trait: ident ) => {
182 impl<E> $trait for Select<E>
183 where
184 E: EntityTrait,
185 {
186 type QueryStatement = SelectStatement;
187
188 fn query(&mut self) -> &mut SelectStatement {
189 &mut self.query
190 }
191 }
192
193 impl<E, F> $trait for SelectTwo<E, F>
194 where
195 E: EntityTrait,
196 F: EntityTrait,
197 {
198 type QueryStatement = SelectStatement;
199
200 fn query(&mut self) -> &mut SelectStatement {
201 &mut self.query
202 }
203 }
204
205 impl<E, F> $trait for SelectTwoMany<E, F>
206 where
207 E: EntityTrait,
208 F: EntityTrait,
209 {
210 type QueryStatement = SelectStatement;
211
212 fn query(&mut self) -> &mut SelectStatement {
213 &mut self.query
214 }
215 }
216
217 impl<E, F> $trait for SelectTwoRequired<E, F>
218 where
219 E: EntityTrait,
220 F: EntityTrait,
221 {
222 type QueryStatement = SelectStatement;
223
224 fn query(&mut self) -> &mut SelectStatement {
225 &mut self.query
226 }
227 }
228 };
229}
230
231impl_query_trait!(QuerySelect);
232impl_query_trait!(QueryFilter);
233impl_query_trait!(QueryOrder);
234
235impl<C> ColumnAsExpr for C
236where
237 C: ColumnTrait,
238{
239 fn into_column_as_expr(self) -> SimpleExpr {
240 self.select_as(self.as_column_ref().into_column_ref().into())
241 }
242}
243
244impl ColumnAsExpr for SimpleExpr {
245 fn into_column_as_expr(self) -> SimpleExpr {
246 self.into_simple_expr()
247 }
248}
249
250impl<C> IntoSimpleExpr for C
251where
252 C: ColumnTrait,
253{
254 fn into_simple_expr(self) -> SimpleExpr {
255 SimpleExpr::Column(self.as_column_ref().into_column_ref())
256 }
257}
258
259impl IntoSimpleExpr for SimpleExpr {
260 fn into_simple_expr(self) -> SimpleExpr {
261 self
262 }
263}
264
265impl IntoSimpleExpr for FunctionCall {
266 fn into_simple_expr(self) -> SimpleExpr {
267 SimpleExpr::FunctionCall(self)
268 }
269}
270
271pub(crate) trait ColumnSelectExt: ColumnTrait {
272 fn into_select_expr(self) -> SelectExpr;
273}
274
275impl<C> ColumnSelectExt for C
276where
277 C: ColumnTrait,
278{
279 fn into_select_expr(self) -> SelectExpr {
280 let column = self.into_expr();
281 let expr = self.select_as(column.clone());
282
283 let alias = match &expr {
284 SimpleExpr::Column(_) if expr == column => None,
285 SimpleExpr::AsEnum(_, inner) if inner.as_ref() == &column => None,
286 _ => Some(self.as_str().into_iden()),
287 };
288
289 SelectExpr {
290 expr,
291 alias,
292 window: None,
293 }
294 }
295}
296
297impl<E> Select<E>
298where
299 E: EntityTrait,
300{
301 pub(crate) fn new() -> Self {
302 Self {
303 query: SelectStatement::new(),
304 entity: PhantomData,
305 linked_index: 0,
306 }
307 .prepare_select()
308 .prepare_from()
309 }
310
311 fn prepare_select(mut self) -> Self {
312 self.query.exprs(self.column_list());
313 self
314 }
315
316 fn column_list(&self) -> Vec<SelectExpr> {
317 E::Column::iter()
318 .map(ColumnSelectExt::into_select_expr)
319 .collect()
320 }
321
322 fn prepare_from(mut self) -> Self {
323 self.query.from(E::default().table_ref());
324 self
325 }
326
327 pub fn order_by_id_asc(self) -> Self {
329 self.order_by_id(Order::Asc)
330 }
331
332 pub fn order_by_id_desc(self) -> Self {
334 self.order_by_id(Order::Desc)
335 }
336
337 pub fn order_by_id(mut self, order: Order) -> Self {
339 for key in E::PrimaryKey::iter() {
340 let col = key.into_column();
341 self.query
342 .order_by_expr(col.into_simple_expr(), order.clone());
343 }
344 self
345 }
346}
347
348impl<E> QueryTrait for Select<E>
349where
350 E: EntityTrait,
351{
352 type QueryStatement = SelectStatement;
353 fn query(&mut self) -> &mut SelectStatement {
354 &mut self.query
355 }
356 fn as_query(&self) -> &SelectStatement {
357 &self.query
358 }
359 fn into_query(self) -> SelectStatement {
360 self.query
361 }
362}
363
364macro_rules! select_two {
365 ( $selector: ident ) => {
366 impl<E, F> QueryTrait for $selector<E, F>
367 where
368 E: EntityTrait,
369 F: EntityTrait,
370 {
371 type QueryStatement = SelectStatement;
372 fn query(&mut self) -> &mut SelectStatement {
373 &mut self.query
374 }
375 fn as_query(&self) -> &SelectStatement {
376 &self.query
377 }
378 fn into_query(self) -> SelectStatement {
379 self.query
380 }
381 }
382 };
383}
384
385select_two!(SelectTwo);
386select_two!(SelectTwoMany);
387select_two!(SelectTwoRequired);