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, 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, Clone)]
47pub struct TopologyStar;
48
49#[derive(Debug, Clone)]
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 IntoSimpleExpr for FunctionCall {
214 fn into_simple_expr(self) -> SimpleExpr {
215 SimpleExpr::FunctionCall(self)
216 }
217}
218
219impl<E> Select<E>
220where
221 E: EntityTrait,
222{
223 pub(crate) fn new() -> Self {
224 Self {
225 query: SelectStatement::new(),
226 entity: PhantomData,
227 linked_index: 0,
228 }
229 .prepare_select()
230 .prepare_from()
231 }
232
233 fn prepare_select(mut self) -> Self {
234 self.query.exprs(self.column_list());
235 self
236 }
237
238 fn column_list(&self) -> Vec<SimpleExpr> {
239 E::Column::iter()
240 .map(|col| col.select_as(col.into_expr()))
241 .collect()
242 }
243
244 fn prepare_from(mut self) -> Self {
245 self.query.from(E::default().table_ref());
246 self
247 }
248
249 pub fn order_by_id_asc(self) -> Self {
251 self.order_by_id(Order::Asc)
252 }
253
254 pub fn order_by_id_desc(self) -> Self {
256 self.order_by_id(Order::Desc)
257 }
258
259 pub fn order_by_id(mut self, order: Order) -> Self {
261 for key in E::PrimaryKey::iter() {
262 let col = key.into_column();
263 self.query
264 .order_by_expr(col.into_simple_expr(), order.clone());
265 }
266 self
267 }
268}
269
270impl<E> QueryTrait for Select<E>
271where
272 E: EntityTrait,
273{
274 type QueryStatement = SelectStatement;
275 fn query(&mut self) -> &mut SelectStatement {
276 &mut self.query
277 }
278 fn as_query(&self) -> &SelectStatement {
279 &self.query
280 }
281 fn into_query(self) -> SelectStatement {
282 self.query
283 }
284}
285
286macro_rules! select_two {
287 ( $selector: ident ) => {
288 impl<E, F> QueryTrait for $selector<E, F>
289 where
290 E: EntityTrait,
291 F: EntityTrait,
292 {
293 type QueryStatement = SelectStatement;
294 fn query(&mut self) -> &mut SelectStatement {
295 &mut self.query
296 }
297 fn as_query(&self) -> &SelectStatement {
298 &self.query
299 }
300 fn into_query(self) -> SelectStatement {
301 self.query
302 }
303 }
304 };
305}
306
307select_two!(SelectTwo);
308select_two!(SelectTwoMany);