1use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, QueryTrait};
2use core::fmt::Debug;
3use core::marker::PhantomData;
4use sea_query::{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
56pub trait ColumnAsExpr: IntoSimpleExpr {
58 fn into_column_as_expr(self) -> SimpleExpr;
61}
62
63macro_rules! impl_query_trait {
64 ( $trait: ident ) => {
65 impl<E> $trait for Select<E>
66 where
67 E: EntityTrait,
68 {
69 type QueryStatement = SelectStatement;
70
71 fn query(&mut self) -> &mut SelectStatement {
72 &mut self.query
73 }
74 }
75
76 impl<E, F> $trait for SelectTwo<E, F>
77 where
78 E: EntityTrait,
79 F: EntityTrait,
80 {
81 type QueryStatement = SelectStatement;
82
83 fn query(&mut self) -> &mut SelectStatement {
84 &mut self.query
85 }
86 }
87
88 impl<E, F> $trait for SelectTwoMany<E, F>
89 where
90 E: EntityTrait,
91 F: EntityTrait,
92 {
93 type QueryStatement = SelectStatement;
94
95 fn query(&mut self) -> &mut SelectStatement {
96 &mut self.query
97 }
98 }
99
100 impl<E, F, G> $trait for SelectThree<E, F, G>
101 where
102 E: EntityTrait,
103 F: EntityTrait,
104 G: EntityTrait,
105 {
106 type QueryStatement = SelectStatement;
107
108 fn query(&mut self) -> &mut SelectStatement {
109 &mut self.query
110 }
111 }
112 };
113}
114
115impl_query_trait!(QuerySelect);
116impl_query_trait!(QueryFilter);
117impl_query_trait!(QueryOrder);
118
119impl<C> ColumnAsExpr for C
120where
121 C: ColumnTrait,
122{
123 fn into_column_as_expr(self) -> SimpleExpr {
124 self.select_as(self.as_column_ref().into_column_ref().into())
125 }
126}
127
128impl ColumnAsExpr for SimpleExpr {
129 fn into_column_as_expr(self) -> SimpleExpr {
130 self.into_simple_expr()
131 }
132}
133
134impl<C> IntoSimpleExpr for C
135where
136 C: ColumnTrait,
137{
138 fn into_simple_expr(self) -> SimpleExpr {
139 SimpleExpr::Column(self.as_column_ref().into_column_ref())
140 }
141}
142
143impl IntoSimpleExpr for SimpleExpr {
144 fn into_simple_expr(self) -> SimpleExpr {
145 self
146 }
147}
148
149impl<E> Select<E>
150where
151 E: EntityTrait,
152{
153 pub(crate) fn new() -> Self {
154 Self {
155 query: SelectStatement::new(),
156 entity: PhantomData,
157 }
158 .prepare_select()
159 .prepare_from()
160 }
161
162 fn prepare_select(mut self) -> Self {
163 self.query.exprs(self.column_list());
164 self
165 }
166
167 fn column_list(&self) -> Vec<SimpleExpr> {
168 E::Column::iter()
169 .map(|col| col.select_as(col.into_expr()))
170 .collect()
171 }
172
173 fn prepare_from(mut self) -> Self {
174 self.query.from(E::default().table_ref());
175 self
176 }
177}
178
179impl<E> QueryTrait for Select<E>
180where
181 E: EntityTrait,
182{
183 type QueryStatement = SelectStatement;
184 fn query(&mut self) -> &mut SelectStatement {
185 &mut self.query
186 }
187 fn as_query(&self) -> &SelectStatement {
188 &self.query
189 }
190 fn into_query(self) -> SelectStatement {
191 self.query
192 }
193}
194
195macro_rules! select_two {
196 ( $selector: ident ) => {
197 impl<E, F> QueryTrait for $selector<E, F>
198 where
199 E: EntityTrait,
200 F: EntityTrait,
201 {
202 type QueryStatement = SelectStatement;
203 fn query(&mut self) -> &mut SelectStatement {
204 &mut self.query
205 }
206 fn as_query(&self) -> &SelectStatement {
207 &self.query
208 }
209 fn into_query(self) -> SelectStatement {
210 self.query
211 }
212 }
213 };
214}
215
216select_two!(SelectTwo);
217select_two!(SelectTwoMany);
218
219impl<E, F, G> QueryTrait for SelectThree<E, F, G>
220where
221 E: EntityTrait,
222 F: EntityTrait,
223 G: EntityTrait,
224{
225 type QueryStatement = SelectStatement;
226 fn query(&mut self) -> &mut SelectStatement {
227 &mut self.query
228 }
229 fn as_query(&self) -> &SelectStatement {
230 &self.query
231 }
232 fn into_query(self) -> SelectStatement {
233 self.query
234 }
235}