sqlparser_mysql/dds/
drop_database.rs

1use core::fmt;
2use std::fmt::Formatter;
3use std::str;
4
5use nom::branch::alt;
6use nom::bytes::complete::tag_no_case;
7use nom::character::complete::multispace0;
8use nom::sequence::tuple;
9use nom::IResult;
10
11use base::error::ParseSQLError;
12use base::CommonParser;
13
14/// DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
15#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
16pub struct DropDatabaseStatement {
17    pub if_exists: bool,
18    pub name: String,
19}
20
21impl DropDatabaseStatement {
22    pub fn parse(i: &str) -> IResult<&str, DropDatabaseStatement, ParseSQLError<&str>> {
23        let mut parser = tuple((
24            tag_no_case("DROP "),
25            multispace0,
26            alt((tag_no_case("DATABASE "), tag_no_case("SCHEMA "))),
27            CommonParser::parse_if_exists,
28            multispace0,
29            CommonParser::sql_identifier,
30            CommonParser::statement_terminator,
31        ));
32        let (remaining_input, (_, _, _, opt_if_exists, _, database, _)) = parser(i)?;
33
34        let name = String::from(database);
35
36        Ok((
37            remaining_input,
38            DropDatabaseStatement {
39                name,
40                if_exists: opt_if_exists.is_some(),
41            },
42        ))
43    }
44}
45
46impl fmt::Display for DropDatabaseStatement {
47    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
48        write!(f, "DROP DATABASE")?;
49        if self.if_exists {
50            write!(f, " IF EXISTS")?;
51        }
52        let database = self.name.clone();
53        write!(f, " {}", database)?;
54        Ok(())
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use dds::drop_database::DropDatabaseStatement;
61
62    #[test]
63    fn parse_drop_database() {
64        let sqls = [
65            "DROP DATABASE db_name",
66            "DROP SCHEMA db_name;",
67            "DROP DATABASE IF EXISTS db_name;",
68            "DROP DATABASE IF  EXISTS db_name;",
69            "DROP SCHEMA IF EXISTS db_name",
70            "DROP SCHEMA IF      EXISTS db_name",
71        ];
72
73        let database_name = String::from("db_name");
74
75        let exp_statements = [
76            DropDatabaseStatement {
77                if_exists: false,
78                name: database_name.clone(),
79            },
80            DropDatabaseStatement {
81                if_exists: false,
82                name: database_name.clone(),
83            },
84            DropDatabaseStatement {
85                if_exists: true,
86                name: database_name.clone(),
87            },
88            DropDatabaseStatement {
89                if_exists: true,
90                name: database_name.clone(),
91            },
92            DropDatabaseStatement {
93                if_exists: true,
94                name: database_name.clone(),
95            },
96            DropDatabaseStatement {
97                if_exists: true,
98                name: database_name.clone(),
99            },
100        ];
101
102        for i in 0..sqls.len() {
103            let res = DropDatabaseStatement::parse(sqls[i]);
104            assert!(res.is_ok());
105            assert_eq!(res.unwrap().1, exp_statements[i]);
106        }
107    }
108}