sql/grammar/statement/
select.rs1use Result;
2use grammar::clause::{OrderBy, Where};
3use grammar::{Buffer, Clause, Condition, Expression, Statement};
4
5#[derive(Debug, Default)]
7pub struct Select {
8 table: Option<String>,
9 columns: Option<Vec<String>>,
10 so_that: Option<Where>,
11 order_by: Option<OrderBy>,
12 limit: Option<usize>,
13}
14
15impl Select {
16 #[inline]
18 pub fn new<T: ToString>(table: T) -> Self {
19 Select::default().table(table)
20 }
21
22 pub fn table<T: ToString>(mut self, name: T) -> Self {
24 self.table = Some(name.to_string());
25 self
26 }
27
28 pub fn column<T: ToString>(mut self, name: T) -> Self {
30 push!(self.columns, name.to_string());
31 self
32 }
33
34 pub fn columns<T: ToString>(mut self, names: &[T]) -> Self {
36 for name in names {
37 push!(self.columns, name.to_string());
38 }
39 self
40 }
41
42 pub fn so_that<T>(mut self, condition: T) -> Self where T: Condition + 'static {
44 self.so_that = Some(match self.so_that.take() {
45 Some(so_that) => so_that.and(condition),
46 _ => Where::default().and(condition),
47 });
48 self
49 }
50
51 pub fn order_by<T>(mut self, expression: T) -> Self where T: Expression + 'static {
53 self.order_by = Some(match self.order_by.take() {
54 Some(order_by) => order_by.append(expression),
55 _ => OrderBy::default().append(expression),
56 });
57 self
58 }
59
60 pub fn limit(mut self, count: usize) -> Self {
62 self.limit = Some(count);
63 self
64 }
65}
66
67impl Statement for Select {
68 fn compile(&self) -> Result<String> {
69 let mut buffer = Buffer::new();
70 buffer.push("SELECT");
71 if let &Some(ref columns) = &self.columns {
72 buffer.push({
73 let mut buffer = Buffer::new();
74 for column in columns {
75 buffer.push(format!("`{}`", column));
76 }
77 buffer.join(", ")
78 });
79 } else {
80 buffer.push("*");
81 }
82 buffer.push("FROM");
83 buffer.push(format!("`{}`", some!(self.table)));
84 if let &Some(ref clause) = &self.so_that {
85 buffer.push(try!(clause.compile()));
86 }
87 if let Some(ref clause) = self.order_by {
88 buffer.push(try!(clause.compile()));
89 }
90 if let Some(count) = self.limit {
91 buffer.push(format!("LIMIT {}", count));
92 }
93 Ok(buffer.join(" "))
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use prelude::*;
100
101 #[test]
102 fn all() {
103 let statement = select_from("foo");
104 assert_eq!(statement.compile().unwrap(), "SELECT * FROM `foo`");
105 }
106
107 #[test]
108 fn columns() {
109 let statement = select_from("foo").columns(&["bar", "baz"]);
110 assert_eq!(statement.compile().unwrap(), "SELECT `bar`, `baz` FROM `foo`");
111 }
112
113 #[test]
114 fn like() {
115 let statement = select_from("foo").so_that(column("bar").like("%baz%"));
116 assert_eq!(statement.compile().unwrap(), "SELECT * FROM `foo` WHERE `bar` LIKE '%baz%'");
117 }
118
119 #[test]
120 fn order() {
121 let statement = select_from("foo").order_by("bar").order_by(column("baz").descend());
122 assert_eq!(statement.compile().unwrap(), "SELECT * FROM `foo` ORDER BY bar, `baz` DESC");
123 }
124
125 #[test]
126 fn limit() {
127 let statement = select_from("foo").limit(10);
128 assert_eq!(statement.compile().unwrap(), "SELECT * FROM `foo` LIMIT 10");
129 }
130}