pgsql_builder/
insert.rs

1use modifier::{Modifier, Set};
2use std::borrow::Cow;
3use super::{util, Assignment, Assignments, Query, Selection, Selections, Statement};
4
5pub struct Insert<'a> {
6    table: Cow<'static, str>,
7    assignments: Assignments<'a>,
8    selections: Selections,
9}
10
11impl<'a> Insert<'a> {
12    pub fn new(table: Cow<'static, str>) -> Insert<'a> {
13        Insert { table: table, assignments: vec![], selections: vec![] }
14    }
15}
16
17impl<'a> Statement<'a> for Insert<'a> {
18    fn into_query(self) -> Query<'a> {
19        let mut query = format!("INSERT INTO {} ", self.table);
20        if self.assignments.is_empty() {
21            query.push_str("DEFAULT VALUES");
22        } else {
23            query.push('(');
24            query.push_str(&util::keyword_list(self.assignments.iter().map(|a| &a.0)));
25            query.push_str(") VALUES (");
26            query.push_str(&util::placeholders(1, self.assignments.len()));
27            query.push(')');
28        }
29
30        if !self.selections.is_empty() {
31            query.push_str(" RETURNING ");
32            query.push_str(&util::keyword_list(self.selections.iter().map(|a| &a.0)));
33        }
34
35        query.push(';');
36
37        Query(query, self.assignments.iter().map(|a| a.1).collect::<Vec<_>>())
38    }
39}
40
41impl<'a> Set for Insert<'a> { }
42
43impl<'a> Modifier<Insert<'a>> for Assignment<'a> {
44    fn modify(self, insert: &mut Insert<'a>) {
45        insert.assignments.push(self);
46    }
47}
48
49impl<'a> Modifier<Insert<'a>> for Assignments<'a> {
50    fn modify(mut self, insert: &mut Insert<'a>) {
51        insert.assignments.append(&mut self);
52    }
53}
54
55impl<'a> Modifier<Insert<'a>> for Selection {
56    fn modify(self, insert: &mut Insert<'a>) {
57        insert.selections.push(self);
58    }
59}
60
61impl<'a> Modifier<Insert<'a>> for Selections {
62    fn modify(mut self, insert: &mut Insert<'a>) {
63        insert.selections.append(&mut self);
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use ::{Assignment, Selection, Set, Statement};
70    use super::*;
71
72    #[test]
73    fn insert() {
74        let expected = "INSERT INTO test_table (name, age) VALUES ($1, $2) RETURNING id;";
75        let skyler = "Skyler";
76        let age = 23;
77
78        {
79            let insert = Insert::new("test_table".into())
80                .set(Assignment("name".into(), &skyler))
81                .set(Assignment("age".into(), &age))
82                .set(Selection("id".into()));
83            assert_eq!(insert.into_query().0, expected);
84        }
85    }
86
87    #[test]
88    fn default_insert() {
89        let expected = "INSERT INTO test_table DEFAULT VALUES RETURNING id;";
90
91        {
92            let insert = Insert::new("test_table".into()).set(Selection("id".into()));
93            assert_eq!(insert.into_query().0, expected);
94        }
95    }
96}