sea_query/query/
ordered.rs

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