rust_ef/query/builder/filter.rs
1//! Predicates, ordering, distinct, and pagination methods.
2
3use crate::entity::IEntityType;
4
5use super::super::ast::{OrderBy, OrderDirection};
6use super::super::predicate::Predicate;
7use super::core::QueryBuilder;
8
9impl<T: IEntityType> QueryBuilder<T> {
10 #[doc(hidden)]
11 pub fn order_by_column(mut self, column: &str) -> Self {
12 self.state
13 .orderings
14 .push(OrderBy::new(column, OrderDirection::Ascending));
15 self
16 }
17
18 #[doc(hidden)]
19 pub fn order_by_desc_column(mut self, column: &str) -> Self {
20 self.state
21 .orderings
22 .push(OrderBy::new(column, OrderDirection::Descending));
23 self
24 }
25
26 /// Marks this query as `SELECT DISTINCT`.
27 pub fn distinct(mut self) -> Self {
28 self.state.distinct = true;
29 self
30 }
31
32 /// Appends a predicate with `AND`.
33 ///
34 /// Accepts a [`Predicate`] — `linq!(|b: T| ...)` combined with
35 /// [`Predicate::and`] / [`Predicate::or`] / [`Predicate::not`] — or a bare
36 /// [`BoolExpr`](super::super::ast::BoolExpr). The predicate's bound values
37 /// are registered in tree order, so they line up with the generated
38 /// placeholders.
39 ///
40 /// Conditions accumulate with `AND`, and `Predicate::always()` adds no SQL,
41 /// which makes it safe to seed a chain and apply it unconditionally:
42 ///
43 /// ```ignore
44 /// let mut predicate = Predicate::<Product>::always();
45 /// predicate = predicate.and_opt(
46 /// keyword.map(|keyword| linq!(|p: Product| p.name.contains(keyword))),
47 /// );
48 /// predicate = predicate.and_opt(
49 /// min_price.map(|min_price| linq!(|p: Product| p.price >= min_price)),
50 /// );
51 /// let query = ctx.set::<Product>().query().filter(predicate);
52 /// ```
53 pub fn filter(self, predicate: impl Into<Predicate<T>>) -> Self {
54 match predicate.into().into_where_expr() {
55 Some(expr) => self.apply_query_filter(expr),
56 None => self,
57 }
58 }
59
60 /// Skips the specified number of rows.
61 pub fn skip(mut self, count: usize) -> Self {
62 self.state.offset = Some(count);
63 self
64 }
65
66 /// Takes the specified number of rows.
67 pub fn take(mut self, count: usize) -> Self {
68 self.state.limit = Some(count);
69 self
70 }
71}