nodedb_sql/ddl_ast/parse/database/
dispatch.rs1use crate::ddl_ast::parse::clause::{ClauseCursor, tokenize};
8use crate::ddl_ast::statement::{DatabaseStmt, NodedbStatement};
9use crate::error::SqlError;
10
11use super::alter::parse_alter_database;
12use super::backup_restore::{parse_backup_database, parse_restore_database};
13use super::clone::parse_clone_database;
14use super::create::parse_create_database;
15use super::drop_db::parse_drop_database;
16use super::mirror::{parse_mirror_database, parse_show_database_mirror_status};
17use super::move_tenant::parse_move_tenant;
18use super::show_extras::{parse_show_database_lineage, parse_show_database_quota_or_usage};
19use super::use_db::parse_use_database;
20
21pub fn try_parse(
28 _upper: &str,
29 _parts: &[&str],
30 original: &str,
31) -> Option<Result<NodedbStatement, SqlError>> {
32 let toks = tokenize(original);
33 let mut c = ClauseCursor::new(original, &toks, "DATABASE");
34 let result = if c.eat_keywords(&["CREATE", "DATABASE"]) {
35 parse_create_database(&mut c)
36 } else if c.eat_keywords(&["DROP", "DATABASE"]) {
37 parse_drop_database(&mut c)
38 } else if c.eat_keywords(&["ALTER", "DATABASE"]) {
39 parse_alter_database(&mut c)
40 } else if c.eat_keywords(&["USE", "DATABASE"]) {
41 parse_use_database(&mut c)
42 } else if c.eat_keywords(&["CLONE", "DATABASE"]) {
43 parse_clone_database(&mut c)
44 } else if c.eat_keywords(&["MIRROR", "DATABASE"]) {
45 parse_mirror_database(&mut c)
46 } else if c.eat_keywords(&["MOVE", "TENANT"]) {
47 parse_move_tenant(&mut c)
48 } else if c.eat_keywords(&["BACKUP", "DATABASE"]) {
49 parse_backup_database(&mut c)
50 } else if c.eat_keywords(&["RESTORE", "DATABASE"]) {
51 parse_restore_database(&mut c)
52 } else if c.peek_keywords(&["SHOW", "DATABASES"]) {
53 c.eat_keywords(&["SHOW", "DATABASES"]);
54 if !c.at_end() {
55 return None;
56 }
57 Ok(NodedbStatement::Database(DatabaseStmt::ShowDatabases))
58 } else if c.eat_keywords(&["SHOW", "DATABASE", "QUOTA"]) {
59 parse_show_database_quota_or_usage(&mut c, false)
60 } else if c.eat_keywords(&["SHOW", "DATABASE", "USAGE"]) {
61 parse_show_database_quota_or_usage(&mut c, true)
62 } else if c.eat_keywords(&["SHOW", "DATABASE", "LINEAGE"]) {
63 parse_show_database_lineage(&mut c)
64 } else if c.eat_keywords(&["SHOW", "DATABASE", "MIRROR", "STATUS"]) {
65 parse_show_database_mirror_status(&mut c)
66 } else {
67 return None;
68 };
69 Some(result)
70}
71
72pub(super) fn db_name(c: &mut ClauseCursor<'_, '_>, what: &str) -> Result<String, SqlError> {
75 let raw = c.raw(what)?;
76 Ok(raw
77 .strip_prefix('"')
78 .and_then(|r| r.strip_suffix('"'))
79 .map_or_else(|| raw.to_string(), |inner| inner.replace("\"\"", "\"")))
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn parse_show_databases() {
88 let sql = "SHOW DATABASES";
89 let upper = sql.to_uppercase();
90 let parts: Vec<&str> = sql.split_whitespace().collect();
91 let stmt = try_parse(&upper, &parts, sql).unwrap().unwrap();
92 assert_eq!(stmt, NodedbStatement::Database(DatabaseStmt::ShowDatabases));
93 }
94}