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::{IntoColumnRef, SelectStatement, SimpleExpr};
8
9#[derive(Clone, Debug)]
11pub struct Select<E>
12where
13 E: EntityTrait,
14{
15 pub(crate) query: SelectStatement,
16 pub(crate) entity: PhantomData<E>,
17 pub(crate) linked_index: usize,
18}
19
20#[derive(Clone, Debug)]
22pub struct SelectTwo<E, F>
23where
24 E: EntityTrait,
25 F: EntityTrait,
26{
27 pub(crate) query: SelectStatement,
28 pub(crate) entity: PhantomData<(E, F)>,
29}
30
31#[derive(Clone, Debug)]
33pub struct SelectTwoMany<E, F>
34where
35 E: EntityTrait,
36 F: EntityTrait,
37{
38 pub(crate) query: SelectStatement,
39 pub(crate) entity: PhantomData<(E, F)>,
40}
41
42pub trait Topology {}
44
45#[derive(Debug)]
47pub struct TopologyStar;
48
49#[derive(Debug)]
51pub struct TopologyChain;
52
53impl Topology for TopologyStar {}
54impl Topology for TopologyChain {}
55
56#[derive(Clone, Debug)]
58pub struct SelectThree<E, F, G, TOP>
59where
60 E: EntityTrait,
61 F: EntityTrait,
62 G: EntityTrait,
63 TOP: Topology,
64{
65 pub(crate) query: SelectStatement,
66 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
67}
68
69#[derive(Clone, Debug)]
71pub struct SelectThreeMany<E, F, G, TOP>
72where
73 E: EntityTrait,
74 F: EntityTrait,
75 G: EntityTrait,
76 TOP: Topology,
77{
78 pub(crate) query: SelectStatement,
79 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
80}
81
82#[derive(Clone, Debug)]
84pub struct SelectFour<E, F, G, H, TOP>
85where
86 E: EntityTrait,
87 F: EntityTrait,
88 G: EntityTrait,
89 H: EntityTrait,
90 TOP: Topology,
91{
92 pub(crate) query: SelectStatement,
93 pub(crate) entity: PhantomData<(E, F, G, H, TOP)>,
94}
95
96#[derive(Clone, Debug)]
98pub struct SelectFive<E, F, G, H, I, TOP>
99where
100 E: EntityTrait,
101 F: EntityTrait,
102 G: EntityTrait,
103 H: EntityTrait,
104 I: EntityTrait,
105 TOP: Topology,
106{
107 pub(crate) query: SelectStatement,
108 pub(crate) entity: PhantomData<(E, F, G, H, I, TOP)>,
109}
110
111#[derive(Clone, Debug)]
113pub struct SelectSix<E, F, G, H, I, J, TOP>
114where
115 E: EntityTrait,
116 F: EntityTrait,
117 G: EntityTrait,
118 H: EntityTrait,
119 I: EntityTrait,
120 J: EntityTrait,
121 TOP: Topology,
122{
123 pub(crate) query: SelectStatement,
124 pub(crate) entity: PhantomData<(E, F, G, H, I, J, TOP)>,
125}
126
127pub trait IntoSimpleExpr {
129 fn into_simple_expr(self) -> SimpleExpr;
131}
132
133pub trait ColumnAsExpr: IntoSimpleExpr {
135 fn into_column_as_expr(self) -> SimpleExpr;
138}
139
140macro_rules! impl_query_trait {
141 ( $trait: ident ) => {
142 impl<E> $trait for Select<E>
143 where
144 E: EntityTrait,
145 {
146 type QueryStatement = SelectStatement;
147
148 fn query(&mut self) -> &mut SelectStatement {
149 &mut self.query
150 }
151 }
152
153 impl<E, F> $trait for SelectTwo<E, F>
154 where
155 E: EntityTrait,
156 F: EntityTrait,
157 {
158 type QueryStatement = SelectStatement;
159
160 fn query(&mut self) -> &mut SelectStatement {
161 &mut self.query
162 }
163 }
164
165 impl<E, F> $trait for SelectTwoMany<E, F>
166 where
167 E: EntityTrait,
168 F: EntityTrait,
169 {
170 type QueryStatement = SelectStatement;
171
172 fn query(&mut self) -> &mut SelectStatement {
173 &mut self.query
174 }
175 }
176 };
177}
178
179impl_query_trait!(QuerySelect);
180impl_query_trait!(QueryFilter);
181impl_query_trait!(QueryOrder);
182
183impl<C> ColumnAsExpr for C
184where
185 C: ColumnTrait,
186{
187 fn into_column_as_expr(self) -> SimpleExpr {
188 self.select_as(self.as_column_ref().into_column_ref().into())
189 }
190}
191
192impl ColumnAsExpr for SimpleExpr {
193 fn into_column_as_expr(self) -> SimpleExpr {
194 self.into_simple_expr()
195 }
196}
197
198impl<C> IntoSimpleExpr for C
199where
200 C: ColumnTrait,
201{
202 fn into_simple_expr(self) -> SimpleExpr {
203 SimpleExpr::Column(self.as_column_ref().into_column_ref())
204 }
205}
206
207impl IntoSimpleExpr for SimpleExpr {
208 fn into_simple_expr(self) -> SimpleExpr {
209 self
210 }
211}
212
213impl<E> Select<E>
214where
215 E: EntityTrait,
216{
217 pub(crate) fn new() -> Self {
218 Self {
219 query: SelectStatement::new(),
220 entity: PhantomData,
221 linked_index: 0,
222 }
223 .prepare_select()
224 .prepare_from()
225 }
226
227 fn prepare_select(mut self) -> Self {
228 self.query.exprs(self.column_list());
229 self
230 }
231
232 fn column_list(&self) -> Vec<SimpleExpr> {
233 E::Column::iter()
234 .map(|col| col.select_as(col.into_expr()))
235 .collect()
236 }
237
238 fn prepare_from(mut self) -> Self {
239 self.query.from(E::default().table_ref());
240 self
241 }
242
243 pub fn order_by_id_asc(self) -> Self {
245 self.order_by_id(Order::Asc)
246 }
247
248 pub fn order_by_id_desc(self) -> Self {
250 self.order_by_id(Order::Desc)
251 }
252
253 pub fn order_by_id(mut self, order: Order) -> Self {
255 for key in E::PrimaryKey::iter() {
256 let col = key.into_column();
257 self.query
258 .order_by_expr(col.into_simple_expr(), order.clone());
259 }
260 self
261 }
262}
263
264impl<E> QueryTrait for Select<E>
265where
266 E: EntityTrait,
267{
268 type QueryStatement = SelectStatement;
269 fn query(&mut self) -> &mut SelectStatement {
270 &mut self.query
271 }
272 fn as_query(&self) -> &SelectStatement {
273 &self.query
274 }
275 fn into_query(self) -> SelectStatement {
276 self.query
277 }
278}
279
280macro_rules! select_two {
281 ( $selector: ident ) => {
282 impl<E, F> QueryTrait for $selector<E, F>
283 where
284 E: EntityTrait,
285 F: EntityTrait,
286 {
287 type QueryStatement = SelectStatement;
288 fn query(&mut self) -> &mut SelectStatement {
289 &mut self.query
290 }
291 fn as_query(&self) -> &SelectStatement {
292 &self.query
293 }
294 fn into_query(self) -> SelectStatement {
295 self.query
296 }
297 }
298 };
299}
300
301select_two!(SelectTwo);
302select_two!(SelectTwoMany);