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;
// use std::collections::HashMap;

#[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
    }
}