rdb_pagination_core/sql/
order_by.rs1use crate::{ColumnName, OrderType, TableName};
2
3#[derive(Debug, Clone)]
4pub enum NullStrategy {
5 Default,
6 First,
7 Last,
8}
9
10#[derive(Debug, Clone)]
12pub struct SqlOrderByComponent {
13 pub table_name: TableName,
14 pub column_name: ColumnName,
15 pub order_type: OrderType,
16 pub null_strategy: NullStrategy,
17}
18
19#[cfg(any(feature = "mysql", feature = "sqlite"))]
20impl SqlOrderByComponent {
21 fn to_sql_order_by_clause_component<'a>(&self, s: &'a mut String) -> &'a str {
22 use std::{fmt::Write, str::from_utf8_unchecked};
23
24 let len = s.len();
25
26 match self.null_strategy {
27 NullStrategy::Default => (),
28 NullStrategy::First => {
29 s.write_fmt(format_args!(
30 "`{table_name}`.`{column_name}` IS NOT NULL, ",
31 table_name = self.table_name,
32 column_name = self.column_name,
33 ))
34 .unwrap();
35 },
36 NullStrategy::Last => {
37 s.write_fmt(format_args!(
38 "`{table_name}`.`{column_name}` IS NULL, ",
39 table_name = self.table_name,
40 column_name = self.column_name,
41 ))
42 .unwrap();
43 },
44 }
45
46 s.write_fmt(format_args!(
47 "`{table_name}`.`{column_name}` {order_type}",
48 table_name = self.table_name,
49 column_name = self.column_name,
50 order_type = self.order_type.as_str(),
51 ))
52 .unwrap();
53
54 unsafe { from_utf8_unchecked(&s.as_bytes()[len..]) }
55 }
56
57 fn format_sql_order_by_components<'a>(
58 order_by_components: &[SqlOrderByComponent],
59 s: &'a mut String,
60 ) -> &'a str {
61 use std::str::from_utf8_unchecked;
62
63 if order_by_components.is_empty() {
64 return "";
65 }
66
67 let len = s.len();
68
69 s.push_str("ORDER BY ");
70
71 for order_by_unit in order_by_components {
72 order_by_unit.to_sql_order_by_clause_component(s);
73 s.push_str(", ");
74 }
75
76 unsafe {
77 let len = s.len();
78
79 s.as_mut_vec().truncate(len - 2);
80 }
81
82 unsafe { from_utf8_unchecked(&s.as_bytes()[len..]) }
83 }
84}
85
86#[cfg(feature = "mysql")]
87impl SqlOrderByComponent {
88 #[inline]
94 pub fn to_mysql_order_by_clause_component<'a>(&self, s: &'a mut String) -> &'a str {
95 self.to_sql_order_by_clause_component(s)
96 }
97
98 #[inline]
106 pub fn format_mysql_order_by_components<'a>(
107 order_by_components: &[SqlOrderByComponent],
108 s: &'a mut String,
109 ) -> &'a str {
110 Self::format_sql_order_by_components(order_by_components, s)
111 }
112}
113
114#[cfg(feature = "sqlite")]
115impl SqlOrderByComponent {
116 #[inline]
122 pub fn to_sqlite_order_by_clause_component<'a>(&self, s: &'a mut String) -> &'a str {
123 self.to_sql_order_by_clause_component(s)
124 }
125
126 #[inline]
134 pub fn format_sqlite_order_by_components<'a>(
135 order_by_components: &[SqlOrderByComponent],
136 s: &'a mut String,
137 ) -> &'a str {
138 Self::format_sql_order_by_components(order_by_components, s)
139 }
140}
141
142#[cfg(any(feature = "mssql", feature = "mssql2008"))]
143impl SqlOrderByComponent {
144 fn to_sql_order_by_clause_component_ms<'a>(&self, s: &'a mut String) -> &'a str {
145 use std::{fmt::Write, str::from_utf8_unchecked};
146
147 let len = s.len();
148
149 match self.null_strategy {
150 NullStrategy::Default => (),
151 NullStrategy::First => {
152 s.write_fmt(format_args!(
153 "CASE WHEN [{table_name}].[{column_name}] IS NULL THEN 0 ELSE 1 END, ",
154 table_name = self.table_name,
155 column_name = self.column_name,
156 ))
157 .unwrap();
158 },
159 NullStrategy::Last => {
160 s.write_fmt(format_args!(
161 "CASE WHEN [{table_name}].[{column_name}] IS NULL THEN 1 ELSE 0 END, ",
162 table_name = self.table_name,
163 column_name = self.column_name,
164 ))
165 .unwrap();
166 },
167 }
168
169 s.write_fmt(format_args!(
170 "[{table_name}].[{column_name}] {order_type}",
171 table_name = self.table_name,
172 column_name = self.column_name,
173 order_type = self.order_type.as_str(),
174 ))
175 .unwrap();
176
177 unsafe { from_utf8_unchecked(&s.as_bytes()[len..]) }
178 }
179
180 fn format_sql_order_by_components_ms<'a>(
181 order_by_components: &[SqlOrderByComponent],
182 s: &'a mut String,
183 ) -> &'a str {
184 use std::str::from_utf8_unchecked;
185
186 if order_by_components.is_empty() {
187 return "";
188 }
189
190 let len = s.len();
191
192 s.push_str("ORDER BY ");
193
194 for order_by_unit in order_by_components {
195 order_by_unit.to_sql_order_by_clause_component_ms(s);
196 s.push_str(", ");
197 }
198
199 unsafe {
200 let len = s.len();
201
202 s.as_mut_vec().truncate(len - 2);
203 }
204
205 unsafe { from_utf8_unchecked(&s.as_bytes()[len..]) }
206 }
207}
208
209#[cfg(any(feature = "mssql", feature = "mssql2008"))]
210impl SqlOrderByComponent {
211 #[inline]
217 pub fn to_mssql_order_by_clause_component<'a>(&self, s: &'a mut String) -> &'a str {
218 self.to_sql_order_by_clause_component_ms(s)
219 }
220
221 #[inline]
229 pub fn format_mssql_order_by_components<'a>(
230 order_by_components: &[SqlOrderByComponent],
231 s: &'a mut String,
232 ) -> &'a str {
233 Self::format_sql_order_by_components_ms(order_by_components, s)
234 }
235}