84 lines
2.3 KiB
Rust
84 lines
2.3 KiB
Rust
use crate::syntax::RawQuerySyntax;
|
|
use minisql::{interpreter2::DbSchema, operation::Operation};
|
|
use nom::{
|
|
branch::alt,
|
|
character::complete::{char, multispace0},
|
|
multi::many1,
|
|
sequence::{delimited, terminated},
|
|
IResult,
|
|
};
|
|
use thiserror::Error;
|
|
|
|
use crate::{
|
|
parsing::{
|
|
create::parse_create, delete::parse_delete, index::parse_create_index,
|
|
insert::parse_insert, select::parse_select,
|
|
},
|
|
validation::{validate_operation, ValidationError},
|
|
};
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum Error {
|
|
#[error("parsing error: {0}")]
|
|
ParsingError(String),
|
|
#[error("validation error: {0}")]
|
|
ValidationError(#[from] ValidationError),
|
|
}
|
|
|
|
/// Parse single statement
|
|
fn parse_statement(input: &str) -> IResult<&str, RawQuerySyntax> {
|
|
alt((
|
|
parse_insert,
|
|
parse_create,
|
|
parse_delete,
|
|
//parse_drop,
|
|
parse_select,
|
|
// parse_update,
|
|
parse_create_index,
|
|
))(input)
|
|
}
|
|
|
|
/// Parse one or more statements
|
|
#[allow(dead_code)]
|
|
fn parse_statement1(input: &str) -> IResult<&str, Vec<RawQuerySyntax>> {
|
|
many1(terminated(
|
|
parse_statement,
|
|
delimited(multispace0, char(';'), multispace0),
|
|
))(input)
|
|
}
|
|
|
|
pub fn parse_and_validate(str_query: String, db_schema: &DbSchema) -> Result<Operation, Error> {
|
|
let (_, op) =
|
|
parse_statement(str_query.as_str()).map_err(|err| Error::ParsingError(err.to_string()))?;
|
|
|
|
Ok(validate_operation(op, db_schema)?)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use crate::core::parse_statement1;
|
|
use crate::parse_and_validate;
|
|
use crate::Error;
|
|
|
|
#[test]
|
|
fn test_parse_two_select() {
|
|
let (rest, sntx) = parse_statement1("SELECT * FROM users ; SELECT * FROM cities ; ")
|
|
.expect("should parse");
|
|
assert_eq!(sntx.len(), 2);
|
|
assert_eq!(rest, "");
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse_three_insert_one_select() {
|
|
let (rest, sntx) = parse_statement1(
|
|
r#"INSERT INTO table1 (id, data) VALUES (u1, 2);
|
|
SELECT * FROM users ;
|
|
INSERT INTO table1 (id, data) VALUES (u4, 30) ;
|
|
INSERT INTO table1 (id, data) VALUES (u5, 40) ;
|
|
"#,
|
|
)
|
|
.expect("should parse");
|
|
assert_eq!(sntx.len(), 4);
|
|
assert_eq!(rest, "");
|
|
}
|
|
}
|