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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#[allow(dead_code)]
pub struct Where {
    statement: String,
    combined_by: Combiner,
}

#[allow(dead_code)]
impl Where {
    pub fn new(combined_by: Combiner) -> Where {
        Where {
            statement: String::new(),
            combined_by,
        }
    }

    pub fn equal_to(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate("=", field, value)
    }

    pub fn not_equal_to(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate("!=", field, value)
    }

    pub fn greater_than(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate(">", field, value)
    }

    pub fn greater_than_equal(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate(">=", field, value)
    }

    pub fn less_than(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate("<", field, value)
    }

    pub fn less_than_equal(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate("<=", field, value)
    }

    pub fn is_null(&mut self, field: &str) -> &mut Where {
        self.add_self_comparative_predicate("ISNULL", field);
        self
    }

    pub fn is_not_null(&mut self, field: &str) -> &mut Where {
        self.add_self_comparative_predicate("IS NOT NULL", field);
        self
    }

    pub fn in_(&mut self, field: &str, fields: Vec<&str>) -> &mut Where {
        self.add_multiple_values_comparative_predicate("IN", field, fields);
        self
    }

    pub fn not_in(&mut self, field: &str, fields: Vec<&str>) -> &mut Where {
        self.add_multiple_values_comparative_predicate("NOT IN", field, fields);
        self
    }

    pub fn like(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate("LIKE", field, value)
    }

    pub fn not_like(&mut self, field: &str, value: &str) -> &mut Where {
        self.add_comparative_predicate("NOT LIKE", field, value)
    }

    pub fn build(&self) -> String {
        if self.statement.len() > 0 {
            return "WHERE".to_string() + &self.statement;
        }
        "".to_string()
    }

    fn add_combiner(&mut self) {
        let combined = match self.combined_by {
            Combiner::And => "AND",
            Combiner::Or => "OR",
        };

        if self.statement.len() > 0 {
            self.statement.push_str(&format!(" {}", combined))
        }
    }

    fn add_comparative_predicate(
        &mut self,
        operator: &str,
        field: &str,
        value: &str,
    ) -> &mut Where {
        self.add_combiner();
        if value.parse::<f64>().is_ok() {
            self.statement
                .push_str(&format!(" {} {} {}", field, operator, value));
        } else {
            self.statement
                .push_str(&format!(" {} {} '{}'", field, operator, value));
        }
        self
    }

    fn add_self_comparative_predicate(&mut self, operator: &str, field: &str) -> &mut Where {
        self.add_combiner();
        self.statement.push_str(&format!(" {} {}", field, operator));
        self
    }

    fn add_multiple_values_comparative_predicate(
        &mut self,
        operator: &str,
        field: &str,
        fields: Vec<&str>,
    ) -> &mut Where {
        self.add_combiner();

        let values = "'".to_owned() + &fields.join("', '") + "'";

        self.statement
            .push_str(&format!(" {} {} ({})", field, operator, values));
        self
    }
}

#[allow(dead_code)]
pub enum Combiner {
    And,
    Or,
}