sea_orm/query/
select.rs

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::{IntoColumnRef, SelectStatement, SimpleExpr};
8
9/// Defines a structure to perform select operations
10#[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/// Defines a structure to perform a SELECT operation on two Models
21#[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/// Defines a structure to perform a SELECT operation on many Models
32#[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/// Topology of multi-joins
43pub trait Topology {}
44
45/// A star topology
46#[derive(Debug)]
47pub struct TopologyStar;
48
49/// A chain topology
50#[derive(Debug)]
51pub struct TopologyChain;
52
53impl Topology for TopologyStar {}
54impl Topology for TopologyChain {}
55
56/// Perform a SELECT operation on three Models
57#[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/// Perform a SELECT operation on three Models with results consolidated
70#[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/// Perform a SELECT operation on 4 Models
83#[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/// Perform a SELECT operation on 5 Models
97#[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/// Perform a SELECT operation on 6 Models
112#[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
127/// Performs a conversion to [SimpleExpr]
128pub trait IntoSimpleExpr {
129    /// Method to perform the conversion
130    fn into_simple_expr(self) -> SimpleExpr;
131}
132
133/// Extending [IntoSimpleExpr] to support casting ActiveEnum as TEXT in select expression
134pub trait ColumnAsExpr: IntoSimpleExpr {
135    /// Casting ActiveEnum as TEXT in select expression,
136    /// otherwise same as [IntoSimpleExpr::into_simple_expr]
137    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<E> Select<E>
214where
215    E: EntityTrait,
216{
217    pub(crate) fn new() -> Self {
218        Self {
219            query: SelectStatement::new(),
220            entity: PhantomData,
221            linked_index: 0,
222        }
223        .prepare_select()
224        .prepare_from()
225    }
226
227    fn prepare_select(mut self) -> Self {
228        self.query.exprs(self.column_list());
229        self
230    }
231
232    fn column_list(&self) -> Vec<SimpleExpr> {
233        E::Column::iter()
234            .map(|col| col.select_as(col.into_expr()))
235            .collect()
236    }
237
238    fn prepare_from(mut self) -> Self {
239        self.query.from(E::default().table_ref());
240        self
241    }
242
243    /// Apply order by primary key to the query statement
244    pub fn order_by_id_asc(self) -> Self {
245        self.order_by_id(Order::Asc)
246    }
247
248    /// Apply order by primary key to the query statement
249    pub fn order_by_id_desc(self) -> Self {
250        self.order_by_id(Order::Desc)
251    }
252
253    /// Apply order by primary key to the query statement
254    pub fn order_by_id(mut self, order: Order) -> Self {
255        for key in E::PrimaryKey::iter() {
256            let col = key.into_column();
257            self.query
258                .order_by_expr(col.into_simple_expr(), order.clone());
259        }
260        self
261    }
262}
263
264impl<E> QueryTrait for Select<E>
265where
266    E: EntityTrait,
267{
268    type QueryStatement = SelectStatement;
269    fn query(&mut self) -> &mut SelectStatement {
270        &mut self.query
271    }
272    fn as_query(&self) -> &SelectStatement {
273        &self.query
274    }
275    fn into_query(self) -> SelectStatement {
276        self.query
277    }
278}
279
280macro_rules! select_two {
281    ( $selector: ident ) => {
282        impl<E, F> QueryTrait for $selector<E, F>
283        where
284            E: EntityTrait,
285            F: EntityTrait,
286        {
287            type QueryStatement = SelectStatement;
288            fn query(&mut self) -> &mut SelectStatement {
289                &mut self.query
290            }
291            fn as_query(&self) -> &SelectStatement {
292                &self.query
293            }
294            fn into_query(self) -> SelectStatement {
295                self.query
296            }
297        }
298    };
299}
300
301select_two!(SelectTwo);
302select_two!(SelectTwoMany);