nom_sql/
delete.rs

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}