sea_orm/query/
select.rs

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/// Defines a structure to perform select operations
7#[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/// Defines a structure to perform a SELECT operation on two Models
17#[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/// Defines a structure to perform a SELECT operation on many Models
28#[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/// Defines a structure to perform a SELECT operation on two Models
39#[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
50/// Performs a conversion to [SimpleExpr]
51pub trait IntoSimpleExpr {
52    /// Method to perform the conversion
53    fn into_simple_expr(self) -> SimpleExpr;
54}
55
56/// Extending [IntoSimpleExpr] to support casting ActiveEnum as TEXT in select expression
57pub trait ColumnAsExpr: IntoSimpleExpr {
58    /// Casting ActiveEnum as TEXT in select expression,
59    /// otherwise same as [IntoSimpleExpr::into_simple_expr]
60    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(Expr::expr(self.as_column_ref().into_column_ref()))
125    }
126}
127
128impl ColumnAsExpr for Expr {
129    fn into_column_as_expr(self) -> SimpleExpr {
130        self.into_simple_expr()
131    }
132}
133
134impl ColumnAsExpr for SimpleExpr {
135    fn into_column_as_expr(self) -> SimpleExpr {
136        self.into_simple_expr()
137    }
138}
139
140impl<C> IntoSimpleExpr for C
141where
142    C: ColumnTrait,
143{
144    fn into_simple_expr(self) -> SimpleExpr {
145        SimpleExpr::Column(self.as_column_ref().into_column_ref())
146    }
147}
148
149impl IntoSimpleExpr for Expr {
150    fn into_simple_expr(self) -> SimpleExpr {
151        self.into()
152    }
153}
154
155impl IntoSimpleExpr for SimpleExpr {
156    fn into_simple_expr(self) -> SimpleExpr {
157        self
158    }
159}
160
161impl<E> Select<E>
162where
163    E: EntityTrait,
164{
165    pub(crate) fn new() -> Self {
166        Self {
167            query: SelectStatement::new(),
168            entity: PhantomData,
169        }
170        .prepare_select()
171        .prepare_from()
172    }
173
174    fn prepare_select(mut self) -> Self {
175        self.query.exprs(self.column_list());
176        self
177    }
178
179    fn column_list(&self) -> Vec<SimpleExpr> {
180        E::Column::iter()
181            .map(|col| col.select_as(col.into_expr()))
182            .collect()
183    }
184
185    fn prepare_from(mut self) -> Self {
186        self.query.from(E::default().table_ref());
187        self
188    }
189}
190
191impl<E> QueryTrait for Select<E>
192where
193    E: EntityTrait,
194{
195    type QueryStatement = SelectStatement;
196    fn query(&mut self) -> &mut SelectStatement {
197        &mut self.query
198    }
199    fn as_query(&self) -> &SelectStatement {
200        &self.query
201    }
202    fn into_query(self) -> SelectStatement {
203        self.query
204    }
205}
206
207macro_rules! select_two {
208    ( $selector: ident ) => {
209        impl<E, F> QueryTrait for $selector<E, F>
210        where
211            E: EntityTrait,
212            F: 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    };
226}
227
228select_two!(SelectTwo);
229select_two!(SelectTwoMany);
230
231impl<E, F, G> QueryTrait for SelectThree<E, F, G>
232where
233    E: EntityTrait,
234    F: EntityTrait,
235    G: EntityTrait,
236{
237    type QueryStatement = SelectStatement;
238    fn query(&mut self) -> &mut SelectStatement {
239        &mut self.query
240    }
241    fn as_query(&self) -> &SelectStatement {
242        &self.query
243    }
244    fn into_query(self) -> SelectStatement {
245        self.query
246    }
247}