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 pub(crate) linked_index: usize,
15}
16
17#[derive(Clone, Debug)]
19pub struct SelectTwo<E, F>
20where
21 E: EntityTrait,
22 F: EntityTrait,
23{
24 pub(crate) query: SelectStatement,
25 pub(crate) entity: PhantomData<(E, F)>,
26}
27
28#[derive(Clone, Debug)]
30pub struct SelectTwoMany<E, F>
31where
32 E: EntityTrait,
33 F: EntityTrait,
34{
35 pub(crate) query: SelectStatement,
36 pub(crate) entity: PhantomData<(E, F)>,
37}
38
39pub trait Topology {}
41
42#[derive(Debug)]
44pub struct TopologyStar;
45
46#[derive(Debug)]
48pub struct TopologyChain;
49
50impl Topology for TopologyStar {}
51impl Topology for TopologyChain {}
52
53#[derive(Clone, Debug)]
55pub struct SelectThree<E, F, G, TOP>
56where
57 E: EntityTrait,
58 F: EntityTrait,
59 G: EntityTrait,
60 TOP: Topology,
61{
62 pub(crate) query: SelectStatement,
63 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
64}
65
66#[derive(Clone, Debug)]
68pub struct SelectThreeMany<E, F, G, TOP>
69where
70 E: EntityTrait,
71 F: EntityTrait,
72 G: EntityTrait,
73 TOP: Topology,
74{
75 pub(crate) query: SelectStatement,
76 pub(crate) entity: PhantomData<(E, F, G, TOP)>,
77}
78
79pub trait IntoSimpleExpr {
81 fn into_simple_expr(self) -> SimpleExpr;
83}
84
85pub trait ColumnAsExpr: IntoSimpleExpr {
87 fn into_column_as_expr(self) -> SimpleExpr;
90}
91
92macro_rules! impl_query_trait {
93 ( $trait: ident ) => {
94 impl<E> $trait for Select<E>
95 where
96 E: EntityTrait,
97 {
98 type QueryStatement = SelectStatement;
99
100 fn query(&mut self) -> &mut SelectStatement {
101 &mut self.query
102 }
103 }
104
105 impl<E, F> $trait for SelectTwo<E, F>
106 where
107 E: EntityTrait,
108 F: EntityTrait,
109 {
110 type QueryStatement = SelectStatement;
111
112 fn query(&mut self) -> &mut SelectStatement {
113 &mut self.query
114 }
115 }
116
117 impl<E, F> $trait for SelectTwoMany<E, F>
118 where
119 E: EntityTrait,
120 F: EntityTrait,
121 {
122 type QueryStatement = SelectStatement;
123
124 fn query(&mut self) -> &mut SelectStatement {
125 &mut self.query
126 }
127 }
128
129 impl<E, F, G, TOP> $trait for SelectThree<E, F, G, TOP>
130 where
131 E: EntityTrait,
132 F: EntityTrait,
133 G: EntityTrait,
134 TOP: Topology,
135 {
136 type QueryStatement = SelectStatement;
137
138 fn query(&mut self) -> &mut SelectStatement {
139 &mut self.query
140 }
141 }
142 };
143}
144
145impl_query_trait!(QuerySelect);
146impl_query_trait!(QueryFilter);
147impl_query_trait!(QueryOrder);
148
149impl<C> ColumnAsExpr for C
150where
151 C: ColumnTrait,
152{
153 fn into_column_as_expr(self) -> SimpleExpr {
154 self.select_as(self.as_column_ref().into_column_ref().into())
155 }
156}
157
158impl ColumnAsExpr for SimpleExpr {
159 fn into_column_as_expr(self) -> SimpleExpr {
160 self.into_simple_expr()
161 }
162}
163
164impl<C> IntoSimpleExpr for C
165where
166 C: ColumnTrait,
167{
168 fn into_simple_expr(self) -> SimpleExpr {
169 SimpleExpr::Column(self.as_column_ref().into_column_ref())
170 }
171}
172
173impl IntoSimpleExpr for SimpleExpr {
174 fn into_simple_expr(self) -> SimpleExpr {
175 self
176 }
177}
178
179impl<E> Select<E>
180where
181 E: EntityTrait,
182{
183 pub(crate) fn new() -> Self {
184 Self {
185 query: SelectStatement::new(),
186 entity: PhantomData,
187 linked_index: 0,
188 }
189 .prepare_select()
190 .prepare_from()
191 }
192
193 fn prepare_select(mut self) -> Self {
194 self.query.exprs(self.column_list());
195 self
196 }
197
198 fn column_list(&self) -> Vec<SimpleExpr> {
199 E::Column::iter()
200 .map(|col| col.select_as(col.into_expr()))
201 .collect()
202 }
203
204 fn prepare_from(mut self) -> Self {
205 self.query.from(E::default().table_ref());
206 self
207 }
208}
209
210impl<E> QueryTrait for Select<E>
211where
212 E: EntityTrait,
213{
214 type QueryStatement = SelectStatement;
215 fn query(&mut self) -> &mut SelectStatement {
216 &mut self.query
217 }
218 fn as_query(&self) -> &SelectStatement {
219 &self.query
220 }
221 fn into_query(self) -> SelectStatement {
222 self.query
223 }
224}
225
226macro_rules! select_two {
227 ( $selector: ident ) => {
228 impl<E, F> QueryTrait for $selector<E, F>
229 where
230 E: EntityTrait,
231 F: EntityTrait,
232 {
233 type QueryStatement = SelectStatement;
234 fn query(&mut self) -> &mut SelectStatement {
235 &mut self.query
236 }
237 fn as_query(&self) -> &SelectStatement {
238 &self.query
239 }
240 fn into_query(self) -> SelectStatement {
241 self.query
242 }
243 }
244 };
245}
246
247select_two!(SelectTwo);
248select_two!(SelectTwoMany);
249
250impl<E, F, G, TOP> QueryTrait for SelectThree<E, F, G, TOP>
251where
252 E: EntityTrait,
253 F: EntityTrait,
254 G: EntityTrait,
255 TOP: Topology,
256{
257 type QueryStatement = SelectStatement;
258 fn query(&mut self) -> &mut SelectStatement {
259 &mut self.query
260 }
261 fn as_query(&self) -> &SelectStatement {
262 &self.query
263 }
264 fn into_query(self) -> SelectStatement {
265 self.query
266 }
267}