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}