1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use serde_json::Value as JsonValue;
use regex::Regex;
use crate::nodes::NodesType;
use crate::nodes::{NodeWhere};
use crate::traits::ModelAble;
use std::vec::Vec;
#[allow(dead_code)]
enum ClearableStatement {
With, Select, Columns, HintComments, Where, Union, Join, Group, Order, Having, Limit, Offset, Counter, Counters,
}
#[allow(dead_code)]
enum LockModes {
ForShare, ForUpdate
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct QueryBuilder {
table_name: String,
columns: Vec<String>,
wheres: Vec<NodesType>,
groups: Vec<NodesType>,
havings: Vec<NodesType>,
}
impl QueryBuilder {
pub fn new<T: ModelAble>() -> Self {
let table_name = T::table_name();
Self {
table_name: table_name.clone(),
columns: vec![format!("`{}`.*", table_name.clone())],
wheres: vec![],
groups: vec![],
havings: vec![],
}
}
pub fn except(&mut self, columns: Vec<&'static str>) -> &mut Self {
for &val in &columns {
match val {
"where" => self.wheres = vec![],
_ => {}
}
}
self
}
pub fn r#where(&mut self, condition: JsonValue) -> &mut Self {
self.wheres.push(NodesType::Where(NodeWhere::new(condition)));
self
}
pub fn select(&mut self, columns: Vec<&'static str>) -> &mut Self {
self.columns = columns.iter().map(|&value| {
if Regex::new(r"\.").unwrap().is_match(value) {
format!("{}", value)
} else {
format!("`{}`.`{}`", self.table_name, value)
}
}).collect();
self
}
pub fn to_sql(&self) -> String {
let mut sql = format!("SELECT {} FROM `{}`", self.columns.join(", "), self.table_name);
if self.wheres.len() > 0 {
let where_sql: Vec<String> = self.wheres.iter().filter_map(|val| {
let NodesType::Where(node_where) = val;
Some(node_where.to_sql(&self.table_name))
}).map(|value| value.unwrap()).collect();
sql = format!("{} WHERE {}", sql, where_sql.join(" AND "))
}
sql
}
}