1use nom::character::complete::multispace1;
2use std::{fmt, str};
3
4use common::{statement_terminator, table_reference};
5use condition::ConditionExpression;
6use keywords::escape_if_keyword;
7use nom::bytes::complete::tag_no_case;
8use nom::combinator::opt;
9use nom::sequence::{delimited, tuple};
10use nom::IResult;
11use select::where_clause;
12use table::Table;
13
14#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)]
15pub struct DeleteStatement {
16 pub table: Table,
17 pub where_clause: Option<ConditionExpression>,
18}
19
20impl fmt::Display for DeleteStatement {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "DELETE FROM ")?;
23 write!(f, "{}", escape_if_keyword(&self.table.name))?;
24 if let Some(ref where_clause) = self.where_clause {
25 write!(f, " WHERE ")?;
26 write!(f, "{}", where_clause)?;
27 }
28 Ok(())
29 }
30}
31
32pub fn deletion(i: &[u8]) -> IResult<&[u8], DeleteStatement> {
33 let (remaining_input, (_, _, table, where_clause, _)) = tuple((
34 tag_no_case("delete"),
35 delimited(multispace1, tag_no_case("from"), multispace1),
36 table_reference,
37 opt(where_clause),
38 statement_terminator,
39 ))(i)?;
40
41 Ok((
42 remaining_input,
43 DeleteStatement {
44 table,
45 where_clause,
46 },
47 ))
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use column::Column;
54 use common::{Literal, Operator};
55 use condition::ConditionBase::*;
56 use condition::ConditionExpression::*;
57 use condition::ConditionTree;
58 use table::Table;
59
60 #[test]
61 fn simple_delete() {
62 let qstring = "DELETE FROM users;";
63 let res = deletion(qstring.as_bytes());
64 assert_eq!(
65 res.unwrap().1,
66 DeleteStatement {
67 table: Table::from("users"),
68 ..Default::default()
69 }
70 );
71 }
72
73 #[test]
74 fn delete_with_where_clause() {
75 let qstring = "DELETE FROM users WHERE id = 1;";
76 let res = deletion(qstring.as_bytes());
77 let expected_left = Base(Field(Column::from("id")));
78 let expected_where_cond = Some(ComparisonOp(ConditionTree {
79 left: Box::new(expected_left),
80 right: Box::new(Base(Literal(Literal::Integer(1)))),
81 operator: Operator::Equal,
82 }));
83 assert_eq!(
84 res.unwrap().1,
85 DeleteStatement {
86 table: Table::from("users"),
87 where_clause: expected_where_cond,
88 ..Default::default()
89 }
90 );
91 }
92
93 #[test]
94 fn format_delete() {
95 let qstring = "DELETE FROM users WHERE id = 1";
96 let expected = "DELETE FROM users WHERE id = 1";
97 let res = deletion(qstring.as_bytes());
98 assert_eq!(format!("{}", res.unwrap().1), expected);
99 }
100}