1use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, QueryTrait};
2use core::fmt::Debug;
3use core::marker::PhantomData;
4use sea_query::{Expr, IntoColumnRef, SelectStatement, SimpleExpr};
5
6#[derive(Clone, Debug)]
8pub struct Select<E>
9where
10 E: EntityTrait,
11{
12 pub(crate) query: SelectStatement,
13 pub(crate) entity: PhantomData<E>,
14}
15
16#[derive(Clone, Debug)]
18pub struct SelectTwo<E, F>
19where
20 E: EntityTrait,
21 F: EntityTrait,
22{
23 pub(crate) query: SelectStatement,
24 pub(crate) entity: PhantomData<(E, F)>,
25}
26
27#[derive(Clone, Debug)]
29pub struct SelectTwoMany<E, F>
30where
31 E: EntityTrait,
32 F: EntityTrait,
33{
34 pub(crate) query: SelectStatement,
35 pub(crate) entity: PhantomData<(E, F)>,
36}
37
38#[derive(Clone, Debug)]
40pub struct SelectThree<E, F, G>
41where
42 E: EntityTrait,
43 F: EntityTrait,
44 G: EntityTrait,
45{
46 pub(crate) query: SelectStatement,
47 pub(crate) entity: PhantomData<(E, F, G)>,
48}
49
50pub trait IntoSimpleExpr {
52 fn into_simple_expr(self) -> SimpleExpr;
54}
55
56macro_rules! impl_query_trait {
57 ( $trait: ident ) => {
58 impl<E> $trait for Select<E>
59 where
60 E: EntityTrait,
61 {
62 type QueryStatement = SelectStatement;
63
64 fn query(&mut self) -> &mut SelectStatement {
65 &mut self.query
66 }
67 }
68
69 impl<E, F> $trait for SelectTwo<E, F>
70 where
71 E: EntityTrait,
72 F: EntityTrait,
73 {
74 type QueryStatement = SelectStatement;
75
76 fn query(&mut self) -> &mut SelectStatement {
77 &mut self.query
78 }
79 }
80
81 impl<E, F> $trait for SelectTwoMany<E, F>
82 where
83 E: EntityTrait,
84 F: EntityTrait,
85 {
86 type QueryStatement = SelectStatement;
87
88 fn query(&mut self) -> &mut SelectStatement {
89 &mut self.query
90 }
91 }
92
93 impl<E, F, G> $trait for SelectThree<E, F, G>
94 where
95 E: EntityTrait,
96 F: EntityTrait,
97 G: EntityTrait,
98 {
99 type QueryStatement = SelectStatement;
100
101 fn query(&mut self) -> &mut SelectStatement {
102 &mut self.query
103 }
104 }
105 };
106}
107
108impl_query_trait!(QuerySelect);
109impl_query_trait!(QueryFilter);
110impl_query_trait!(QueryOrder);
111
112impl<C> IntoSimpleExpr for C
113where
114 C: ColumnTrait,
115{
116 fn into_simple_expr(self) -> SimpleExpr {
117 SimpleExpr::Column(self.as_column_ref().into_column_ref())
118 }
119}
120
121impl IntoSimpleExpr for Expr {
122 fn into_simple_expr(self) -> SimpleExpr {
123 self.into()
124 }
125}
126
127impl IntoSimpleExpr for SimpleExpr {
128 fn into_simple_expr(self) -> SimpleExpr {
129 self
130 }
131}
132
133impl<E> Select<E>
134where
135 E: EntityTrait,
136{
137 pub(crate) fn new() -> Self {
138 Self {
139 query: SelectStatement::new(),
140 entity: PhantomData,
141 }
142 .prepare_select()
143 .prepare_from()
144 }
145
146 fn prepare_select(mut self) -> Self {
147 self.query.exprs(self.column_list());
148 self
149 }
150
151 fn column_list(&self) -> Vec<SimpleExpr> {
152 E::Column::iter()
153 .map(|col| col.select_as(col.into_expr()))
154 .collect()
155 }
156
157 fn prepare_from(mut self) -> Self {
158 self.query.from(E::default().table_ref());
159 self
160 }
161}
162
163impl<E> QueryTrait for Select<E>
164where
165 E: EntityTrait,
166{
167 type QueryStatement = SelectStatement;
168 fn query(&mut self) -> &mut SelectStatement {
169 &mut self.query
170 }
171 fn as_query(&self) -> &SelectStatement {
172 &self.query
173 }
174 fn into_query(self) -> SelectStatement {
175 self.query
176 }
177}
178
179macro_rules! select_two {
180 ( $selector: ident ) => {
181 impl<E, F> QueryTrait for $selector<E, F>
182 where
183 E: EntityTrait,
184 F: EntityTrait,
185 {
186 type QueryStatement = SelectStatement;
187 fn query(&mut self) -> &mut SelectStatement {
188 &mut self.query
189 }
190 fn as_query(&self) -> &SelectStatement {
191 &self.query
192 }
193 fn into_query(self) -> SelectStatement {
194 self.query
195 }
196 }
197 };
198}
199
200select_two!(SelectTwo);
201select_two!(SelectTwoMany);
202
203impl<E, F, G> QueryTrait for SelectThree<E, F, G>
204where
205 E: EntityTrait,
206 F: EntityTrait,
207 G: EntityTrait,
208{
209 type QueryStatement = SelectStatement;
210 fn query(&mut self) -> &mut SelectStatement {
211 &mut self.query
212 }
213 fn as_query(&self) -> &SelectStatement {
214 &self.query
215 }
216 fn into_query(self) -> SelectStatement {
217 self.query
218 }
219}