Skip to main content

tank_core/query/builder/
select.rs

1use crate::{
2    Dataset, Driver, DynQuery, EitherIterator, Expression, ExpressionCollection, NA, SqlWriter,
3};
4use std::{iter, marker::PhantomData};
5
6pub struct SelectQueryBuilder<Select, From, Where, GroupBy, Having, OrderBy, Limit> {
7    pub(crate) select: Select,
8    pub(crate) from: Option<From>,
9    pub(crate) where_expr: Option<Where>,
10    pub(crate) group_by: Option<GroupBy>,
11    pub(crate) having: Option<Having>,
12    pub(crate) order_by: Option<OrderBy>,
13    pub(crate) limit: Option<u32>,
14    pub(crate) _l: PhantomData<Limit>,
15}
16
17impl<S> SelectQueryBuilder<S, NA, NA, NA, NA, NA, NA> {
18    pub fn from<From: Dataset>(
19        self,
20        from: From,
21    ) -> SelectQueryBuilder<S, From, NA, NA, NA, NA, NA> {
22        SelectQueryBuilder {
23            select: self.select,
24            from: Some(from),
25            where_expr: Default::default(),
26            group_by: Default::default(),
27            having: Default::default(),
28            order_by: Default::default(),
29            limit: Default::default(),
30            _l: Default::default(),
31        }
32    }
33}
34
35impl<S, F> SelectQueryBuilder<S, F, NA, NA, NA, NA, NA> {
36    pub fn where_expr<Where>(
37        self,
38        condition: Where,
39    ) -> SelectQueryBuilder<S, F, Where, NA, NA, NA, NA>
40    where
41        Where: Expression,
42    {
43        SelectQueryBuilder {
44            select: self.select,
45            from: self.from,
46            where_expr: Some(condition),
47            group_by: Default::default(),
48            having: Default::default(),
49            order_by: Default::default(),
50            limit: Default::default(),
51            _l: Default::default(),
52        }
53    }
54}
55
56impl<S, F, W> SelectQueryBuilder<S, F, W, NA, NA, NA, NA> {
57    pub fn group_by<GroupBy>(
58        self,
59        group_by: GroupBy,
60    ) -> SelectQueryBuilder<S, F, W, GroupBy, NA, NA, NA>
61    where
62        GroupBy: Clone,
63    {
64        SelectQueryBuilder {
65            select: self.select,
66            from: self.from,
67            where_expr: self.where_expr,
68            group_by: Some(group_by),
69            having: Default::default(),
70            order_by: Default::default(),
71            limit: Default::default(),
72            _l: Default::default(),
73        }
74    }
75}
76
77impl<S, F, W, G> SelectQueryBuilder<S, F, W, G, NA, NA, NA> {
78    pub fn having<Having: Expression>(
79        self,
80        having: Having,
81    ) -> SelectQueryBuilder<S, F, W, G, Having, NA, NA> {
82        SelectQueryBuilder {
83            select: self.select,
84            from: self.from,
85            where_expr: self.where_expr,
86            group_by: self.group_by,
87            having: Some(having),
88            order_by: Default::default(),
89            limit: Default::default(),
90            _l: Default::default(),
91        }
92    }
93}
94
95impl<S, F, W, G, H> SelectQueryBuilder<S, F, W, G, H, NA, NA> {
96    pub fn order_by<OrderBy>(
97        self,
98        order_by: OrderBy,
99    ) -> SelectQueryBuilder<S, F, W, G, H, OrderBy, NA> {
100        SelectQueryBuilder {
101            select: self.select,
102            from: self.from,
103            where_expr: self.where_expr,
104            group_by: self.group_by,
105            having: self.having,
106            order_by: Some(order_by),
107            limit: None,
108            _l: Default::default(),
109        }
110    }
111}
112
113impl<S, F, W, G, H, O> SelectQueryBuilder<S, F, W, G, H, O, NA> {
114    pub fn limit(self, limit: Option<u32>) -> SelectQueryBuilder<S, F, W, G, H, O, u32> {
115        SelectQueryBuilder {
116            select: self.select,
117            from: self.from,
118            where_expr: self.where_expr,
119            group_by: self.group_by,
120            having: self.having,
121            order_by: self.order_by,
122            limit,
123            _l: Default::default(),
124        }
125    }
126}
127
128impl<S, From, W, G, H, O, L> SelectQueryBuilder<S, From, W, G, H, O, L>
129where
130    S: ExpressionCollection,
131    From: Dataset,
132    W: Expression,
133    G: ExpressionCollection,
134    H: Expression,
135    O: ExpressionCollection,
136{
137    pub fn get_select(&self) -> impl Iterator<Item = impl Expression> + Clone {
138        self.select.expr_iter()
139    }
140
141    pub fn get_from(&self) -> &Option<From> {
142        &self.from
143    }
144
145    pub fn get_where(&self) -> &Option<impl Expression> {
146        &self.where_expr
147    }
148
149    pub fn get_group_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
150        match &self.group_by {
151            Some(v) => EitherIterator::Left(v.expr_iter()),
152            None => EitherIterator::Right(iter::empty()),
153        }
154    }
155
156    pub fn get_having(&self) -> &Option<impl Expression> {
157        &self.having
158    }
159
160    pub fn get_order_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
161        match &self.order_by {
162            Some(v) => EitherIterator::Left(v.expr_iter()),
163            None => EitherIterator::Right(iter::empty()),
164        }
165    }
166
167    pub fn get_limit(&self) -> Option<u32> {
168        self.limit
169    }
170
171    pub fn build<D: Driver>(&self, driver: &D) -> DynQuery {
172        let writer = driver.sql_writer();
173        let mut query = DynQuery::default();
174        writer.write_select(&mut query, self);
175        query.into()
176    }
177
178    pub fn build_into<D: Driver>(&self, driver: &D, out: &mut DynQuery) {
179        let writer = driver.sql_writer();
180        writer.write_select(out, self);
181    }
182}
183
184/// SELECT query builder.
185///
186/// Use `QueryBuilder::new().select(..)` to start.
187pub trait SelectQuery<From>
188where
189    From: Dataset,
190{
191    /// Get SELECT expressions.
192    fn get_select(&self) -> impl Iterator<Item = impl Expression> + Clone;
193    /// Get FROM clause dataset.
194    fn get_from<'s>(&'s self) -> &'s Option<From>;
195    /// Get WHERE clause expression.
196    fn get_where<'s>(&'s self) -> &'s Option<impl Expression>;
197    /// Get GROUP BY expressions.
198    fn get_group_by(&self) -> impl Iterator<Item = impl Expression> + Clone;
199    /// Get HAVING clause expression.
200    fn get_having(&self) -> &Option<impl Expression>;
201    /// Get ORDER BY expressions.
202    fn get_order_by(&self) -> impl Iterator<Item = impl Expression> + Clone;
203    /// Get LIMIT value.
204    fn get_limit(&self) -> Option<u32>;
205    /// Build query.
206    fn build<D: Driver>(&self, driver: &D) -> DynQuery;
207    /// Build query into existing buffer.
208    fn build_into<D: Driver>(&self, driver: &D, out: &mut DynQuery);
209}
210
211impl<S, From, W, G, H, O, L> SelectQuery<From> for SelectQueryBuilder<S, From, W, G, H, O, L>
212where
213    S: ExpressionCollection,
214    From: Dataset,
215    W: Expression,
216    G: ExpressionCollection,
217    H: Expression,
218    O: ExpressionCollection,
219{
220    fn get_select(&self) -> impl Iterator<Item = impl Expression> + Clone {
221        self.get_select()
222    }
223
224    fn get_from(&self) -> &Option<From> {
225        self.get_from()
226    }
227
228    fn get_where(&self) -> &Option<impl Expression> {
229        self.get_where()
230    }
231
232    fn get_group_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
233        self.get_group_by()
234    }
235
236    fn get_having(&self) -> &Option<impl Expression> {
237        self.get_having()
238    }
239
240    fn get_order_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
241        self.get_order_by()
242    }
243
244    fn get_limit(&self) -> Option<u32> {
245        self.get_limit()
246    }
247
248    fn build<D: Driver>(&self, driver: &D) -> DynQuery {
249        self.build(driver)
250    }
251
252    fn build_into<D: Driver>(&self, driver: &D, out: &mut DynQuery) {
253        self.build_into(driver, out);
254    }
255}