sqlx_plus_builder/
where-builder.rs1use crate::error::SqlBuilderError;
2use std::fmt;
3
4#[macro_export]
5macro_rules! and {
6 ( $f:expr, $( $l:expr ),* ) => {
7 {
8 let mut x = String::from("(");
9 x.push_str( & $f .to_string() );
10 $(
11 x.push_str(") AND (");
12 x.push_str( & $l .to_string() );
13 )*
14 x.push(')');
15 x
16 }
17 };
18}
19
20#[macro_export]
21macro_rules! or {
22 ( $f:expr, $( $l:expr ),* ) => {
23 {
24 let mut x = String::from( $f );
25 $(
26 x.push_str(" OR ");
27 x.push_str( & $l .to_string() );
28 )*
29 x
30 }
31 };
32}
33
34#[macro_export]
35macro_rules! not {
36 ( $f:expr ) => {{
37 let mut x = String::from("NOT ");
38 x.push_str(&$f.to_string());
39 x
40 }};
41}
42
43#[macro_export]
44macro_rules! brackets {
45 ( $el:expr ) => {
46 {
47 let mut x = String::from("(");
48 x.push_str( & $el .to_string() );
49 x.push(')');
50 x
51 }
52 };
53 ( $first:expr, $( $el:expr ),* ) => {
54 {
55 let mut x = String::from("(");
56 x.push_str( & $first .to_string() );
57 $(
58 x.push_str(", ");
59 x.push_str( & $el .to_string() );
60 )*
61 x.push(')');
62 x
63 }
64 };
65}
66
67#[derive(Clone, Default)]
69pub struct Where {
70 text: String,
71 prefix: Option<String>,
72 error: Option<SqlBuilderError>,
73 was_and: bool,
74}
75
76impl fmt::Display for Where {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 write!(f, "{}", self.text)
79 }
80}
81
82impl Where {
83 pub fn new<S>(smth: S) -> Self
84 where
85 S: ToString,
86 {
87 let text = smth.to_string();
89 if text.is_empty() {
90 return Self {
91 error: Some(SqlBuilderError::NoWhereField),
92 ..Self::default()
93 };
94 }
95
96 Self {
98 text,
99 ..Self::default()
100 }
101 }
102
103 pub fn empty() -> Self {
104 Self::default()
105 }
106
107 pub fn in_brackets(&mut self) -> &mut Self {
108 if self.text.is_empty() {
110 self.error = Some(SqlBuilderError::NoWhereField);
111 return self;
112 }
113
114 self.text.insert(0, '(');
116 self.text.push(')');
117 self
118 }
119
120 pub fn not(&mut self) -> &mut Self {
121 if self.text.is_empty() {
123 self.error = Some(SqlBuilderError::NoWhereField);
124 return self;
125 }
126
127 self.text.insert_str(0, "NOT ");
129 self
130 }
131
132 pub fn and<S>(&mut self, smth: S) -> &mut Self
133 where
134 S: ToString,
135 {
136 if self.text.is_empty() {
138 self.error = Some(SqlBuilderError::NoWhereField);
139 return self;
140 }
141 let smth = smth.to_string();
142 if smth.is_empty() {
143 self.error = Some(SqlBuilderError::NoWhereValue(self.text.clone()));
144 return self;
145 }
146
147 if !self.was_and {
149 self.text.insert(0, '(');
150 self.text.push(')');
151 self.was_and = true;
152 }
153 self.text.push_str(" AND (");
154 self.text.push_str(&smth);
155 self.text.push(')');
156 self
157 }
158
159 pub fn or<S>(&mut self, smth: S) -> &mut Self
160 where
161 S: ToString,
162 {
163 if self.text.is_empty() {
165 self.error = Some(SqlBuilderError::NoWhereField);
166 return self;
167 }
168 let smth = smth.to_string();
169 if smth.is_empty() {
170 self.error = Some(SqlBuilderError::NoWhereValue(self.text.clone()));
171 return self;
172 }
173
174 self.text.push_str(" OR ");
176 self.text.push_str(&smth);
177 self
178 }
179
180 pub fn eq<S>(&mut self, smth: S) -> &mut Self
181 where
182 S: ToString,
183 {
184 let smth = smth.to_string();
186 if smth.is_empty() {
187 self.error = Some(SqlBuilderError::NoWhereValue(self.text.clone()));
188 return self;
189 }
190
191 if let Some(prefix) = &self.prefix {
193 self.text.push(' ');
194 self.text.push_str(&prefix);
195 self.prefix = None;
196 }
197 self.text.push_str(" = ");
198 self.text.push_str(&smth);
199 self
200 }
201
202 pub fn ne<S>(&mut self, smth: S) -> &mut Self
203 where
204 S: ToString,
205 {
206 let smth = smth.to_string();
208 if smth.is_empty() {
209 self.error = Some(SqlBuilderError::NoWhereValue(self.text.clone()));
210 return self;
211 }
212
213 if let Some(prefix) = &self.prefix {
215 self.text.push(' ');
216 self.text.push_str(&prefix);
217 self.prefix = None;
218 }
219 self.text.push_str(" <> ");
220 self.text.push_str(&smth);
221 self
222 }
223
224 pub fn build(&self) -> Result<String, SqlBuilderError> {
225 match &self.error {
226 Some(err) => Err(err.clone()),
227 None => Ok(self.text.to_string()),
228 }
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use super::*;
235
236 #[test]
237 fn test_macro_and() {
238 let sql = and!("10", "20", "30");
239 assert_eq!("(10) AND (20) AND (30)", sql);
240 }
241
242 #[test]
243 fn test_macro_or() {
244 let sql = or!("10", "20", "30");
245 assert_eq!("10 OR 20 OR 30", sql);
246 }
247
248 #[test]
249 fn test_macro_not() {
250 let sql = not!("10");
251 assert_eq!("NOT 10", sql);
252 }
253
254 #[test]
255 fn test_macro_brackets() {
256 let sql = brackets!("10", "20", "30");
257 assert_eq!("(10, 20, 30)", sql);
258
259 let sql = brackets!("10");
260 assert_eq!("(10)", sql);
261 }
262
263 #[test]
264 fn test_macro_and_or_not() {
265 let sql = and!("10", or!("20", not!("30"), "40"));
266 assert_eq!("(10) AND (20 OR NOT 30 OR 40)", &sql);
267 }
268
269 #[test]
270 fn test_new_where() {
271 let text = Where::new("abc").to_string();
272 assert_eq!("abc", &text);
273 }
274
275 #[test]
276 fn test_where_brackets() {
277 let text = Where::new("abc").eq(10).in_brackets().to_string();
278 assert_eq!("(abc = 10)", &text);
279 }
280
281 #[test]
282 fn test_where_build() {
283 let res = Where::new("abc").eq(10).build();
284 assert_eq!(Ok("abc = 10".to_string()), res);
285 }
286
287 #[test]
288 fn test_where_not() {
289 let text = Where::new("abc").eq(10).in_brackets().not().to_string();
290 assert_eq!("NOT (abc = 10)", &text);
291 }
292
293 #[test]
294 fn test_where_and() {
295 let text = Where::new("abc").eq(10).and(20).to_string();
296 assert_eq!("(abc = 10) AND (20)", &text);
297 }
298
299 #[test]
300 fn test_where_or() {
301 let text = Where::new("abc").eq(10).or(20).to_string();
302 assert_eq!("abc = 10 OR 20", &text);
303 }
304
305 #[test]
306 fn test_where_eq() {
307 let text = Where::new("abc").eq(10).to_string();
308 assert_eq!("abc = 10", &text);
309 }
310
311 #[test]
312 fn test_where_ne() {
313 let text = Where::new("abc").ne(10).to_string();
314 assert_eq!("abc <> 10", &text);
315 }
316}