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
42#[derive(Clone, Debug)]
44pub struct SelectTwoRequired<E, F>
45where
46 E: EntityTrait,
47 F: EntityTrait,
48{
49 pub(crate) query: SelectStatement,
50 pub(crate) entity: PhantomData<(E, F)>,
51}
52
53pub trait Topology {}
55
56#[derive(Debug, Clone)]
58pub struct TopologyStar;
59
60#[derive(Debug, Clone)]
62pub struct TopologyChain;
63
64impl Topology for TopologyStar {}
65impl Topology for TopologyChain {}
66
67#[derive(Clone, Debug)]
69pub struct SelectThree<E, F, G, TOP>
70where
71 E: EntityTrait,
72 F: EntityTrait,
73 G: EntityTrait,
74 TOP: Topology,
75{
76 pub(crate) query: SelectStatement,
77 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
78}
79
80#[derive(Clone, Debug)]
82pub struct SelectThreeMany<E, F, G, TOP>
83where
84 E: EntityTrait,
85 F: EntityTrait,
86 G: EntityTrait,
87 TOP: Topology,
88{
89 pub(crate) query: SelectStatement,
90 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
91}
92
93#[derive(Clone, Debug)]
95pub struct SelectFour<E, F, G, H, TOP>
96where
97 E: EntityTrait,
98 F: EntityTrait,
99 G: EntityTrait,
100 H: EntityTrait,
101 TOP: Topology,
102{
103 pub(crate) query: SelectStatement,
104 pub(crate) entity: PhantomData<(E, F, G, H, TOP)>,
105}
106
107#[derive(Clone, Debug)]
109pub struct SelectFive<E, F, G, H, I, TOP>
110where
111 E: EntityTrait,
112 F: EntityTrait,
113 G: EntityTrait,
114 H: EntityTrait,
115 I: EntityTrait,
116 TOP: Topology,
117{
118 pub(crate) query: SelectStatement,
119 pub(crate) entity: PhantomData<(E, F, G, H, I, TOP)>,
120}
121
122#[derive(Clone, Debug)]
124pub struct SelectSix<E, F, G, H, I, J, TOP>
125where
126 E: EntityTrait,
127 F: EntityTrait,
128 G: EntityTrait,
129 H: EntityTrait,
130 I: EntityTrait,
131 J: EntityTrait,
132 TOP: Topology,
133{
134 pub(crate) query: SelectStatement,
135 pub(crate) entity: PhantomData<(E, F, G, H, I, J, TOP)>,
136}
137
138pub trait IntoSimpleExpr {
140 fn into_simple_expr(self) -> SimpleExpr;
142}
143
144pub trait ColumnAsExpr: IntoSimpleExpr {
146 fn into_column_as_expr(self) -> SimpleExpr;
149}
150
151macro_rules! impl_query_trait {
152 ( $trait: ident ) => {
153 impl<E> $trait for Select<E>
154 where
155 E: EntityTrait,
156 {
157 type QueryStatement = SelectStatement;
158
159 fn query(&mut self) -> &mut SelectStatement {
160 &mut self.query
161 }
162 }
163
164 impl<E, F> $trait for SelectTwo<E, F>
165 where
166 E: EntityTrait,
167 F: EntityTrait,
168 {
169 type QueryStatement = SelectStatement;
170
171 fn query(&mut self) -> &mut SelectStatement {
172 &mut self.query
173 }
174 }
175
176 impl<E, F> $trait for SelectTwoMany<E, F>
177 where
178 E: EntityTrait,
179 F: EntityTrait,
180 {
181 type QueryStatement = SelectStatement;
182
183 fn query(&mut self) -> &mut SelectStatement {
184 &mut self.query
185 }
186 }
187
188 impl<E, F> $trait for SelectTwoRequired<E, F>
189 where
190 E: EntityTrait,
191 F: EntityTrait,
192 {
193 type QueryStatement = SelectStatement;
194
195 fn query(&mut self) -> &mut SelectStatement {
196 &mut self.query
197 }
198 }
199 };
200}
201
202impl_query_trait!(QuerySelect);
203impl_query_trait!(QueryFilter);
204impl_query_trait!(QueryOrder);
205
206impl<C> ColumnAsExpr for C
207where
208 C: ColumnTrait,
209{
210 fn into_column_as_expr(self) -> SimpleExpr {
211 self.select_as(self.as_column_ref().into_column_ref().into())
212 }
213}
214
215impl ColumnAsExpr for SimpleExpr {
216 fn into_column_as_expr(self) -> SimpleExpr {
217 self.into_simple_expr()
218 }
219}
220
221impl<C> IntoSimpleExpr for C
222where
223 C: ColumnTrait,
224{
225 fn into_simple_expr(self) -> SimpleExpr {
226 SimpleExpr::Column(self.as_column_ref().into_column_ref())
227 }
228}
229
230impl IntoSimpleExpr for SimpleExpr {
231 fn into_simple_expr(self) -> SimpleExpr {
232 self
233 }
234}
235
236impl IntoSimpleExpr for FunctionCall {
237 fn into_simple_expr(self) -> SimpleExpr {
238 SimpleExpr::FunctionCall(self)
239 }
240}
241
242impl<E> Select<E>
243where
244 E: EntityTrait,
245{
246 pub(crate) fn new() -> Self {
247 Self {
248 query: SelectStatement::new(),
249 entity: PhantomData,
250 linked_index: 0,
251 }
252 .prepare_select()
253 .prepare_from()
254 }
255
256 fn prepare_select(mut self) -> Self {
257 self.query.exprs(self.column_list());
258 self
259 }
260
261 fn column_list(&self) -> Vec<SimpleExpr> {
262 E::Column::iter()
263 .map(|col| col.select_as(col.into_expr()))
264 .collect()
265 }
266
267 fn prepare_from(mut self) -> Self {
268 self.query.from(E::default().table_ref());
269 self
270 }
271
272 pub fn order_by_id_asc(self) -> Self {
274 self.order_by_id(Order::Asc)
275 }
276
277 pub fn order_by_id_desc(self) -> Self {
279 self.order_by_id(Order::Desc)
280 }
281
282 pub fn order_by_id(mut self, order: Order) -> Self {
284 for key in E::PrimaryKey::iter() {
285 let col = key.into_column();
286 self.query
287 .order_by_expr(col.into_simple_expr(), order.clone());
288 }
289 self
290 }
291}
292
293impl<E> QueryTrait for Select<E>
294where
295 E: EntityTrait,
296{
297 type QueryStatement = SelectStatement;
298 fn query(&mut self) -> &mut SelectStatement {
299 &mut self.query
300 }
301 fn as_query(&self) -> &SelectStatement {
302 &self.query
303 }
304 fn into_query(self) -> SelectStatement {
305 self.query
306 }
307}
308
309macro_rules! select_two {
310 ( $selector: ident ) => {
311 impl<E, F> QueryTrait for $selector<E, F>
312 where
313 E: EntityTrait,
314 F: EntityTrait,
315 {
316 type QueryStatement = SelectStatement;
317 fn query(&mut self) -> &mut SelectStatement {
318 &mut self.query
319 }
320 fn as_query(&self) -> &SelectStatement {
321 &self.query
322 }
323 fn into_query(self) -> SelectStatement {
324 self.query
325 }
326 }
327 };
328}
329
330select_two!(SelectTwo);
331select_two!(SelectTwoMany);
332select_two!(SelectTwoRequired);