From 125142492aaca2f1ddb3df86fb1256e7f679a323 Mon Sep 17 00:00:00 2001 From: Diretnan Domnan Date: Wed, 25 Sep 2024 21:32:42 +0200 Subject: [PATCH] DROPPREDINDEX command parsing --- ahnlich/dsl/src/db.rs | 51 ++++++++++++++++++++++++++++++++++ ahnlich/dsl/src/syntax/db.pest | 7 +++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/ahnlich/dsl/src/db.rs b/ahnlich/dsl/src/db.rs index 1f464f3a..f78439b1 100644 --- a/ahnlich/dsl/src/db.rs +++ b/ahnlich/dsl/src/db.rs @@ -47,6 +47,32 @@ pub fn parse_db_query(input: &str) -> Result, DslError> { predicates, } } + Rule::drop_pred_index => { + let mut inner_pairs = statement.into_inner().peekable(); + let mut if_exists = false; + if let Some(next_pair) = inner_pairs.peek() { + if next_pair.as_rule() == Rule::if_exists { + inner_pairs.next(); // Consume it if needed + if_exists = true; + } + }; + let index_names_pair = inner_pairs + .next() + .ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?; + let store = inner_pairs + .next() + .ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))? + .as_str(); + let predicates = index_names_pair + .into_inner() + .map(|index_pair| MetadataKey::new(index_pair.as_str().to_string())) + .collect(); + DBQuery::DropPredIndex { + store: StoreName(store.to_string()), + predicates, + error_if_not_exists: !if_exists, + } + } Rule::drop_store => { let mut inner_pairs = statement.into_inner(); let store = inner_pairs @@ -165,4 +191,29 @@ mod tests { }] ); } + + #[test] + fn test_drop_pred_index_parse() { + let input = r#"DROPPREDINDEX (here, th2) in store2"#; + assert_eq!( + parse_db_query(input).expect("Could not parse query input"), + vec![DBQuery::DropPredIndex { + store: StoreName("store2".to_string()), + predicates: HashSet::from_iter([ + MetadataKey::new("here".to_string()), + MetadataKey::new("th2".to_string()), + ]), + error_if_not_exists: true, + }] + ); + let input = r#"DROPPREDINDEX IF EXISTS (off) in storememe"#; + assert_eq!( + parse_db_query(input).expect("Could not parse query input"), + vec![DBQuery::DropPredIndex { + store: StoreName("storememe".to_string()), + predicates: HashSet::from_iter([MetadataKey::new("off".to_string()),]), + error_if_not_exists: false, + }] + ); + } } diff --git a/ahnlich/dsl/src/syntax/db.pest b/ahnlich/dsl/src/syntax/db.pest index 80a1de5c..84ae45ad 100644 --- a/ahnlich/dsl/src/syntax/db.pest +++ b/ahnlich/dsl/src/syntax/db.pest @@ -2,16 +2,17 @@ whitespace = _{ " " | "\t" } query = _{ statement ~ (";" ~ statement) * } // Matches multiple statements separated by ; -statement = _{ ping | info_server | list_stores | list_clients | drop_store | create_pred_index | invalid_statement } +statement = _{ ping | info_server | list_stores | list_clients | drop_store | create_pred_index | drop_pred_index | invalid_statement } ping = { whitespace* ~ ^"ping" ~ whitespace* } info_server = { whitespace* ~ ^"infoserver" ~ whitespace* } list_stores = { whitespace* ~ ^"liststores" ~ whitespace* } list_clients = { whitespace* ~ ^"listclients" ~ whitespace* } drop_store = { whitespace* ~ ^"dropstore" ~ whitespace* ~ store_name ~ (if_exists | invalid_statement)? } -create_pred_index = { whitespace* ~ ^"createpredindex" ~ whitespace* ~ "(" ~ index_names ~ ")" ~ whitespace* ~ ^"in" ~whitespace* ~ store_name } +create_pred_index = { whitespace* ~ ^"createpredindex" ~ whitespace* ~ "(" ~ index_names ~ ")" ~ whitespace* ~ ^"in" ~ whitespace* ~ store_name } +drop_pred_index = { whitespace* ~ ^"droppredindex" ~ whitespace* ~ (if_exists)? ~ "(" ~ index_names ~ ")" ~ whitespace* ~ ^"in" ~whitespace* ~ store_name } -if_exists = { whitespace* ~ ^"if" ~ whitespace* ~ "exists" ~ whitespace* } +if_exists = { whitespace* ~ ^"if" ~ whitespace* ~ ^"exists" ~ whitespace* } // stores and predicates can be alphanumeric store_name = { (ASCII_ALPHANUMERIC | "_" | "-")+ }