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}