use super::*;
pub struct Parser {
query: String,
tokens: Vec<String>,
keyword_indexs: Vec<usize>,
expressions: Vec<expression::Expression>,
}
impl Parser {
pub fn new(query: String) -> Parser {
Parser {
query,
tokens: Vec::new(),
keyword_indexs: Vec::new(),
expressions: Vec::new(),
}
}
pub fn set_new_query(&mut self, new_query: String) {
self.tokens = Vec::new();
self.keyword_indexs = Vec::new();
self.expressions = Vec::new();
self.query = new_query;
}
pub fn split_query(&mut self) {
self.tokens = self
.query
.split_whitespace()
.map(|s| s.to_string())
.collect();
}
pub fn find_keywords(&mut self) {
for i in 0..self.tokens.len() {
if grammar::unwrap_string(self.tokens[i].to_string()) != grammar::Keyword::UNKNOWN {
self.keyword_indexs.push(i);
}
}
self.build_expressions_from_keywords();
}
fn build_expressions_from_keywords(&mut self) {
if self.keyword_indexs.is_empty() {
panic!("No keywords have been found inside the query");
}
for i in 0..self.keyword_indexs.len() {
if i == self.keyword_indexs.len() - 1 {
self.expressions.push(expression::Expression::new(
self.tokens[self.keyword_indexs[i]].to_string(),
self.tokens[self.keyword_indexs[i] + 1..self.tokens.len()].to_vec(),
));
} else {
self.expressions.push(expression::Expression::new(
self.tokens[self.keyword_indexs[i]].to_string(),
self.tokens[self.keyword_indexs[i] + 1..self.keyword_indexs[i + 1]].to_vec(),
));
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn splitting_sql_query() {
let query = "SELECT * FROM a";
let mut parser = Parser::new(query.to_owned());
parser.split_query();
assert_eq!(parser.tokens, vec!["SELECT", "*", "FROM", "a"]);
}
#[test]
fn indexing_of_keywords() {
let query = "SELECT * FROM a";
let mut parser = Parser::new(query.to_owned());
parser.split_query();
parser.find_keywords();
assert_eq!(parser.keyword_indexs, vec![0, 2]);
}
#[test]
fn correct_expression_building() {
let query = "SELECT * FROM a";
let mut parser = Parser::new(query.to_owned());
parser.split_query();
parser.find_keywords();
let token_list = vec![
expression::Expression::new(String::from("SELECT"), vec![String::from("*")]),
expression::Expression::new(String::from("FROM"), vec![String::from("a")]),
];
assert_eq!(token_list, parser.expressions);
}
#[test]
fn special_query_input() {
let query = "SELECT * FROM a WHERE a = 1";
let mut parser = Parser::new(query.to_owned());
parser.split_query();
parser.find_keywords();
let expression_listing = vec![
expression::Expression::new(String::from("SELECT"), vec![String::from("*")]),
expression::Expression::new(String::from("FROM"), vec![String::from("a")]),
expression::Expression::new(
String::from("WHERE"),
vec![String::from("a"), String::from("="), String::from("1")],
),
];
assert_eq!(expression_listing, parser.expressions);
}
#[test]
fn order_commands_in_value_order() {}
#[test]
fn special_query_input_2() {
let query = "SELECT a,b FROM a WHERE a = 1 ORDER test";
let mut parser = Parser::new(query.to_owned());
parser.split_query();
parser.find_keywords();
let expression_listing = vec![
expression::Expression::new(String::from("SELECT"), vec![String::from("a,b")]),
expression::Expression::new(String::from("FROM"), vec![String::from("a")]),
expression::Expression::new(
String::from("WHERE"),
vec![String::from("a"), String::from("="), String::from("1")],
),
expression::Expression::new(String::from("ORDER"), vec![String::from("test")]),
];
assert_eq!(expression_listing, parser.expressions);
}
}