sql/grammar/statement/
select.rs

1use Result;
2use grammar::clause::{OrderBy, Where};
3use grammar::{Buffer, Clause, Condition, Expression, Statement};
4
5/// A `SELECT` statement.
6#[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    /// Create a `SELECT` statement.
17    #[inline]
18    pub fn new<T: ToString>(table: T) -> Self {
19        Select::default().table(table)
20    }
21
22    /// Set the table.
23    pub fn table<T: ToString>(mut self, name: T) -> Self {
24        self.table = Some(name.to_string());
25        self
26    }
27
28    /// Add a column.
29    pub fn column<T: ToString>(mut self, name: T) -> Self {
30        push!(self.columns, name.to_string());
31        self
32    }
33
34    /// Add multiple columns.
35    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    /// Add a condition.
43    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    /// Add an order.
52    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    /// Set the limit.
61    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}