Skip to content

Commit

Permalink
CREATEPREDINDEX command parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
deven96 committed Sep 25, 2024
1 parent 995fe2c commit d90c4ca
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
47 changes: 46 additions & 1 deletion ahnlich/dsl/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ahnlich_types::{db::DBQuery, keyval::StoreName};
use ahnlich_types::{db::DBQuery, keyval::StoreName, metadata::MetadataKey};
use pest::Parser;
use pest_derive::Parser;

Expand All @@ -8,6 +8,15 @@ use crate::error::DslError;
#[grammar = "syntax/db.pest"]
struct DBQueryParser;

// Parse raw strings separated by ; into a Vec<DBQuery>. Examples include but are not restricted
// to
//
// PING
// LISTCLIENTS
// LISTSTORES
// INFOSERVER
// DROPSTORE store_name IF EXISTS
// CREATEPREDINDEX (key_1, key_2) in store_name
pub fn parse_db_query(input: &str) -> Result<Vec<DBQuery>, DslError> {
let pairs = DBQueryParser::parse(Rule::query, input).map_err(Box::new)?;
let statements = pairs.into_iter().collect::<Vec<_>>();
Expand All @@ -20,6 +29,24 @@ pub fn parse_db_query(input: &str) -> Result<Vec<DBQuery>, DslError> {
Rule::list_clients => DBQuery::ListClients,
Rule::list_stores => DBQuery::ListStores,
Rule::info_server => DBQuery::InfoServer,
Rule::create_pred_index => {
let mut inner_pairs = statement.into_inner();
let index_name_pairs = inner_pairs
.next()
.ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?;
let predicates = index_name_pairs
.into_inner()
.map(|index_pair| MetadataKey::new(index_pair.as_str().to_string()))
.collect();
let store = inner_pairs
.next()
.ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?
.as_str();
DBQuery::CreatePredIndex {
store: StoreName(store.to_string()),
predicates,
}
}
Rule::drop_store => {
let mut inner_pairs = statement.into_inner();
let store = inner_pairs
Expand Down Expand Up @@ -51,6 +78,8 @@ pub fn parse_db_query(input: &str) -> Result<Vec<DBQuery>, DslError> {

#[cfg(test)]
mod tests {
use std::collections::HashSet;

use super::*;

#[test]
Expand Down Expand Up @@ -120,4 +149,20 @@ mod tests {
};
assert_eq!((start, end), (15, 29));
}

#[test]
fn test_create_predicate_index_parse() {
let input = r#"CREATEPREDINDEX (one, two, 3) in tapHstore1"#;
assert_eq!(
parse_db_query(input).expect("Could not parse query input"),
vec![DBQuery::CreatePredIndex {
store: StoreName("tapHstore1".to_string()),
predicates: HashSet::from_iter([
MetadataKey::new("one".to_string()),
MetadataKey::new("two".to_string()),
MetadataKey::new("3".to_string()),
])
}]
);
}
}
7 changes: 5 additions & 2 deletions ahnlich/dsl/src/syntax/db.pest
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ whitespace = _{ " " | "\t" }

query = _{ statement ~ (";" ~ statement) * } // Matches multiple statements separated by ;

statement = _{ ping | info_server | list_stores | list_clients | drop_store | invalid_statement }
statement = _{ ping | info_server | list_stores | list_clients | drop_store | create_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 }

if_exists = { whitespace* ~ ^"if" ~ whitespace* ~ "exists" ~ whitespace* }

// stores can be alphanumeric
// stores and predicates can be alphanumeric
store_name = { (ASCII_ALPHANUMERIC | "_" | "-")+ }
index_name = { (ASCII_ALPHANUMERIC | "_" | "-")+ }
index_names = { index_name ~ (whitespace* ~ "," ~ whitespace* ~ index_name)* }

// Catch-all rule for invalid statements
invalid_statement = { whitespace* ~ (!";" ~ ANY)+ } // Match anything that isn't a valid statement
Expand Down

0 comments on commit d90c4ca

Please sign in to comment.