sea_query/query/
ordered.rs

1use std::borrow::Cow;
2
3use crate::{expr::*, types::*};
4
5pub trait OrderedStatement {
6    #[doc(hidden)]
7    // Implementation for the trait.
8    fn add_order_by(&mut self, order: OrderExpr) -> &mut Self;
9
10    /// Clear order expressions
11    fn clear_order_by(&mut self) -> &mut Self;
12
13    /// Order by column.
14    ///
15    /// # Examples
16    ///
17    /// Order by ASC and DESC
18    /// ```
19    /// use sea_query::{*, tests_cfg::*};
20    ///
21    /// let query = Query::select()
22    ///     .column(Glyph::Aspect)
23    ///     .from(Glyph::Table)
24    ///     .and_where(Expr::col(Glyph::Aspect).if_null(0).gt(2))
25    ///     .order_by(Glyph::Image, Order::Desc)
26    ///     .order_by((Glyph::Table, Glyph::Aspect), Order::Asc)
27    ///     .to_owned();
28    ///
29    /// assert_eq!(
30    ///     query.to_string(MysqlQueryBuilder),
31    ///     r#"SELECT `aspect` FROM `glyph` WHERE IFNULL(`aspect`, 0) > 2 ORDER BY `image` DESC, `glyph`.`aspect` ASC"#
32    /// );
33    /// ```
34    ///
35    /// Order by custom field ordering
36    /// ```
37    /// use sea_query::{tests_cfg::*, *};
38    ///
39    /// let query = Query::select()
40    ///     .columns([Glyph::Aspect])
41    ///     .from(Glyph::Table)
42    ///     .order_by(
43    ///         Glyph::Id,
44    ///         Order::Field(Values(vec![4.into(), 5.into(), 1.into(), 3.into()])),
45    ///     )
46    ///     .to_owned();
47    ///
48    /// assert_eq!(
49    ///     query.to_string(MysqlQueryBuilder),
50    ///     [
51    ///         r#"SELECT `aspect`"#,
52    ///         r#"FROM `glyph`"#,
53    ///         r#"ORDER BY CASE"#,
54    ///         r#"WHEN `id`=4 THEN 0"#,
55    ///         r#"WHEN `id`=5 THEN 1"#,
56    ///         r#"WHEN `id`=1 THEN 2"#,
57    ///         r#"WHEN `id`=3 THEN 3"#,
58    ///         r#"ELSE 4 END"#,
59    ///     ]
60    ///     .join(" ")
61    /// );
62    ///
63    /// assert_eq!(
64    ///     query.to_string(PostgresQueryBuilder),
65    ///     [
66    ///         r#"SELECT "aspect""#,
67    ///         r#"FROM "glyph""#,
68    ///         r#"ORDER BY CASE"#,
69    ///         r#"WHEN "id"=4 THEN 0"#,
70    ///         r#"WHEN "id"=5 THEN 1"#,
71    ///         r#"WHEN "id"=1 THEN 2"#,
72    ///         r#"WHEN "id"=3 THEN 3"#,
73    ///         r#"ELSE 4 END"#,
74    ///     ]
75    ///     .join(" ")
76    /// );
77    ///
78    /// assert_eq!(
79    ///     query.to_string(SqliteQueryBuilder),
80    ///     [
81    ///         r#"SELECT "aspect""#,
82    ///         r#"FROM "glyph""#,
83    ///         r#"ORDER BY CASE"#,
84    ///         r#"WHEN "id"=4 THEN 0"#,
85    ///         r#"WHEN "id"=5 THEN 1"#,
86    ///         r#"WHEN "id"=1 THEN 2"#,
87    ///         r#"WHEN "id"=3 THEN 3"#,
88    ///         r#"ELSE 4 END"#,
89    ///     ]
90    ///     .join(" ")
91    /// );
92    /// ```
93    fn order_by<T>(&mut self, col: T, order: Order) -> &mut Self
94    where
95        T: IntoColumnRef,
96    {
97        self.add_order_by(OrderExpr {
98            expr: Expr::Column(col.into_column_ref()),
99            order,
100            nulls: None,
101        })
102    }
103
104    /// Order by [`Expr`].
105    fn order_by_expr(&mut self, expr: Expr, order: Order) -> &mut Self {
106        self.add_order_by(OrderExpr {
107            expr,
108            order,
109            nulls: None,
110        })
111    }
112
113    /// Order by custom string.
114    fn order_by_customs<I, T>(&mut self, cols: I) -> &mut Self
115    where
116        T: Into<Cow<'static, str>>,
117        I: IntoIterator<Item = (T, Order)>,
118    {
119        cols.into_iter().for_each(|(c, order)| {
120            self.add_order_by(OrderExpr {
121                expr: Expr::Custom(c.into()),
122                order,
123                nulls: None,
124            });
125        });
126        self
127    }
128
129    /// Order by vector of columns.
130    fn order_by_columns<I, T>(&mut self, cols: I) -> &mut Self
131    where
132        T: IntoColumnRef,
133        I: IntoIterator<Item = (T, Order)>,
134    {
135        cols.into_iter().for_each(|(c, order)| {
136            self.add_order_by(OrderExpr {
137                expr: Expr::Column(c.into_column_ref()),
138                order,
139                nulls: None,
140            });
141        });
142        self
143    }
144
145    /// Order by column with nulls order option.
146    ///
147    /// # Examples
148    ///
149    /// ```
150    /// use sea_query::{*, tests_cfg::*};
151    ///
152    /// let query = Query::select()
153    ///     .column(Glyph::Aspect)
154    ///     .from(Glyph::Table)
155    ///     .order_by_with_nulls(Glyph::Image, Order::Desc, NullOrdering::Last)
156    ///     .order_by_with_nulls((Glyph::Table, Glyph::Aspect), Order::Asc, NullOrdering::First)
157    ///     .to_owned();
158    ///
159    /// assert_eq!(
160    ///     query.to_string(PostgresQueryBuilder),
161    ///     r#"SELECT "aspect" FROM "glyph" ORDER BY "image" DESC NULLS LAST, "glyph"."aspect" ASC NULLS FIRST"#
162    /// );
163    /// assert_eq!(
164    ///     query.to_string(MysqlQueryBuilder),
165    ///     r#"SELECT `aspect` FROM `glyph` ORDER BY `image` IS NULL ASC, `image` DESC, `glyph`.`aspect` IS NULL DESC, `glyph`.`aspect` ASC"#
166    /// );
167    /// ```
168    fn order_by_with_nulls<T>(&mut self, col: T, order: Order, nulls: NullOrdering) -> &mut Self
169    where
170        T: IntoColumnRef,
171    {
172        self.add_order_by(OrderExpr {
173            expr: Expr::Column(col.into_column_ref()),
174            order,
175            nulls: Some(nulls),
176        })
177    }
178
179    /// Order by [`Expr`] with nulls order option.
180    fn order_by_expr_with_nulls(
181        &mut self,
182        expr: Expr,
183        order: Order,
184        nulls: NullOrdering,
185    ) -> &mut Self {
186        self.add_order_by(OrderExpr {
187            expr,
188            order,
189            nulls: Some(nulls),
190        })
191    }
192
193    /// Order by custom string with nulls order option.
194    fn order_by_customs_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
195    where
196        T: Into<Cow<'static, str>>,
197        I: IntoIterator<Item = (T, Order, NullOrdering)>,
198    {
199        cols.into_iter().for_each(|(c, order, nulls)| {
200            self.add_order_by(OrderExpr {
201                expr: Expr::Custom(c.into()),
202                order,
203                nulls: Some(nulls),
204            });
205        });
206        self
207    }
208
209    /// Order by vector of columns with nulls order option.
210    fn order_by_columns_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
211    where
212        T: IntoColumnRef,
213        I: IntoIterator<Item = (T, Order, NullOrdering)>,
214    {
215        cols.into_iter().for_each(|(c, order, nulls)| {
216            self.add_order_by(OrderExpr {
217                expr: Expr::Column(c.into_column_ref()),
218                order,
219                nulls: Some(nulls),
220            });
221        });
222        self
223    }
224}