Skip to main content

joker_query/query/
select.rs

1use std::fmt::Display;
2use super::{
3    having::{Having, HavingInfo},
4    join::{Join, JoinInfo, JoinType},
5    operator::Op,
6    order_by::{Order, OrderType},
7    where_by::{Where, WhereInfo, CondSep}, where_cond::WhereOwner, value::Value,
8};
9
10
11enum TableSource<'a> {
12    Name(&'a str),
13    SubQuery(Value<'a>)
14}
15
16pub struct Select<'a> {
17    table: TableSource<'a>,
18    pub distinct: Option<()>,
19    pub cols: Vec<&'a str>,
20    pub joins: Vec<JoinInfo<'a>>,
21    pub whereas: Vec<WhereInfo<'a>>,
22    pub groups: Vec<&'a str>,
23    pub havings: Vec<HavingInfo<'a>>,
24    pub orders: Vec<Order<'a>>,
25    pub limit: Option<u32>,
26    pub offset: Option<u32>,
27}
28
29impl<'a> WhereOwner<'a> for Select<'a> {
30    fn set_seperator(&mut self, index: usize, sep: CondSep) {
31        self.whereas[index].seperator = Some(sep);
32    }
33
34    fn push(&mut self, where_info: WhereInfo<'a>) {
35        self.whereas.push(where_info);
36    }
37
38    fn len(&self) -> usize {
39        self.whereas.len()
40    }
41}
42
43
44impl<'a> Display for Select<'a> {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        let _ = write!(f, "SELECT ");
47        if self.cols.len() == 0 {
48            let _ = write!(f, "*");
49        } else {
50            if let Some(_) = self.distinct {
51                let _ = write!(f, "DISTINCT ");
52            }
53        }
54        self.cols.iter().enumerate().for_each(|(index, c)| {
55            let _ = write!(f, "{}", c);
56            if index < (self.cols.len() - 1) {
57                let _ = write!(f, ", ");
58            }
59        });
60        match &self.table {
61            TableSource::Name(tab) => {
62                let _ = write!(f, " FROM {}", tab);
63            }
64            TableSource::SubQuery(q) => {
65                let _ = write!(f, " FROM {}", q);
66            }
67        }
68
69        self.joins.iter().for_each(|c| {
70            let _ = write!(f, "{}", c);
71        });
72
73        if self.whereas.len() > 0 {
74            let _ = write!(f, "\nWHERE");
75            self.whereas.iter().for_each(|c| {
76                let _ = write!(f, "{}", c);
77            });
78        }
79
80        if self.groups.len() > 0 {
81            let _ = write!(f, "\nGROUP BY");
82            self.groups.iter().enumerate().for_each(|(index, c)| {
83                let _ = write!(f, " {}", c);
84                if index < (self.groups.len() - 1) {
85                    let _ = write!(f, ", ");
86                }
87            });
88        }
89
90        if self.havings.len() > 0 {
91            let _ = write!(f, "\nHAVING");
92            self.havings.iter().for_each(|c| {
93                let _ = write!(f, "{}", c);
94            });
95        }
96
97        if self.orders.len() > 0 {
98            let _ = write!(f, "\nORDER BY ");
99            self.orders.iter().enumerate().for_each(|(i, c)| {
100                let _ = write!(f, "{}", c);
101                if i < self.orders.len() - 1 {
102                    let _ = write!(f, ", ");
103                }
104            });
105        }
106
107        if let Some(v) = self.limit {
108            let _ = write!(f, "\nLIMIT {}", v);
109        }
110
111        if let Some(v) = self.offset {
112            let _ = write!(f, "\nOFFSET {}", v);
113        }
114
115        Ok(())
116    }
117}
118
119impl<'a> Select<'a> {
120    fn new() -> Self {
121        Select {
122            distinct: None,
123            cols: vec![],
124            table: TableSource::Name(""),
125            joins: vec![],
126            whereas: vec![],
127            groups: vec![],
128            havings: vec![],
129            orders: vec![],
130            limit: None,
131            offset: None,
132        }
133    }
134
135    pub fn any() -> Self {
136        Select::new()
137    }
138
139    pub fn cols(cols: Vec<&'a str>) -> Self {
140        let mut selector = Select::new();
141        selector.cols = cols;
142        selector
143    }
144
145    pub fn col(mut self, col: &'a str) -> Self {
146        self.cols.push(col);
147        return self;
148    }
149
150    pub fn distinct(mut self) -> Self {
151        self.distinct = Some(());
152        self
153    }
154
155    pub fn from(mut self, table: &'a str) -> Self {
156        self.table = TableSource::Name(table);
157        return self;
158    }
159
160    pub fn from_subquery(mut self, table: impl Into<Select<'a>>) -> Self {
161        let select: Select<'a> = table.into();
162        self.table = TableSource::SubQuery(select.into());
163        return self;
164    }
165
166    pub fn inner_join(self, table: &'a str) -> Join<'a> {
167        Join::from(self, table, JoinType::Inner)
168    }
169    pub fn left_join(self, table: &'a str) -> Join<'a> {
170        Join::from(self, table, JoinType::Left)
171    }
172    pub fn right_join(self, table: &'a str) -> Join<'a> {
173        Join::from(self, table, JoinType::Right)
174    }
175    pub fn outer_join(self, table: &'a str) -> Join<'a> {
176        Join::from(self, table, JoinType::Outer)
177    }
178
179    pub fn where_by(self, left: &'a str, op: Op<'a>) -> Where<'a> {
180        Where::new(self, left, op)
181    }
182
183    pub fn group_by(mut self, cols: Vec<&'a str>) -> Self {
184        self.groups = cols;
185        return self;
186    }
187
188    pub fn order_by(mut self, col: &'a str) -> Self {
189        self.orders.push(Order::new(col, OrderType::ASC));
190        return self;
191    }
192    pub fn order_by_desc(mut self, col: &'a str) -> Self {
193        self.orders.push(Order::new(col, OrderType::DESC));
194        return self;
195    }
196
197    pub fn having(self, left: &'a str, op: Op<'a>) -> Having<'a> {
198        Having::new(self, left, op)
199    }
200
201    
202
203    pub fn limit(mut self, num: u32) -> Self {
204        self.limit = Some(num);
205        return self;
206    }
207
208    pub fn offset(mut self, num: u32) -> Self {
209        self.offset = Some(num);
210        return self;
211    }
212
213    pub fn build(&self) -> String {
214        format!("{}", self)
215    }
216
217
218}