formatting

This commit is contained in:
Yuriy Dupyn 2024-02-05 23:11:38 +01:00
parent ad98cfafb2
commit c25c6edc6a
29 changed files with 886 additions and 571 deletions

View file

@ -1,10 +1,19 @@
use minisql::type_system::DbType;
use nom::{
branch::alt, bytes::complete::{tag, take_while}, character::{complete::{alphanumeric1, anychar, char, multispace0, multispace1}, is_alphanumeric}, combinator::peek, error::make_error, sequence::{delimited, terminated}, IResult, Parser
branch::alt,
bytes::complete::{tag, take_while},
character::{
complete::{alphanumeric1, anychar, char, multispace0, multispace1},
is_alphanumeric,
},
combinator::peek,
error::make_error,
sequence::{delimited, terminated},
IResult, Parser,
};
use crate::syntax::Condition;
use super::literal::parse_literal;
use crate::syntax::Condition;
pub fn parse_table_name(input: &str) -> IResult<&str, &str> {
alt((
@ -16,11 +25,9 @@ pub fn parse_table_name(input: &str) -> IResult<&str, &str> {
pub fn parse_identifier(input: &str) -> IResult<&str, &str> {
let (_, first) = peek(anychar)(input)?;
if first.is_alphabetic() || first == '_' {
take_while(|c: char| {
match c {
'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => true,
_ => false
}
take_while(|c: char| match c {
'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => true,
_ => false,
})(input)
} else {
Err(nom::Err::Error(make_error(
@ -35,22 +42,13 @@ pub fn parse_column_name(input: &str) -> IResult<&str, String> {
}
pub fn parse_db_type(input: &str) -> IResult<&str, DbType> {
let (input, db_type) = alt(
(
tag("STRING")
.map(|_| DbType::String),
tag("INT")
.map(|_| DbType::Int),
tag("NUMBER")
.map(|_| DbType::Number),
tag("UUID")
.map(|_| DbType::Uuid),
delimited(tag("Option("), parse_db_type, tag(")"))
.map(|ty| {
DbType::Option(Box::new(ty))
})
)
)(input)?;
let (input, db_type) = alt((
tag("STRING").map(|_| DbType::String),
tag("INT").map(|_| DbType::Int),
tag("NUMBER").map(|_| DbType::Number),
tag("UUID").map(|_| DbType::Uuid),
delimited(tag("Option("), parse_db_type, tag(")")).map(|ty| DbType::Option(Box::new(ty))),
))(input)?;
Ok((input, db_type))
}
@ -122,10 +120,7 @@ mod tests {
parse_identifier("_variable__Test").expect("should parse").1,
"_variable__Test"
);
assert!(matches!(
parse_identifier("123_variable__Test"),
Err(_)
));
assert!(matches!(parse_identifier("123_variable__Test"), Err(_)));
}
#[test]
@ -139,8 +134,12 @@ mod tests {
#[test]
fn test_parse_nested_option_int_type() {
assert_eq!(
parse_db_type("Option(Option(Option(INT)))").expect("should parse").1,
DbType::Option(Box::new(DbType::Option(Box::new(DbType::Option(Box::new(DbType::Int))))))
parse_db_type("Option(Option(Option(INT)))")
.expect("should parse")
.1,
DbType::Option(Box::new(DbType::Option(Box::new(DbType::Option(
Box::new(DbType::Int)
)))))
);
}
}

View file

@ -77,8 +77,7 @@ mod tests {
#[test]
fn test_parse_create_no_quotes_table_name() {
parse_create("CREATE TABLE Table1(id UUID PRIMARY KEY,column1 INT)")
.expect("should parse");
parse_create("CREATE TABLE Table1(id UUID PRIMARY KEY,column1 INT)").expect("should parse");
}
#[test]
@ -91,8 +90,8 @@ mod tests {
#[test]
fn test_parse_create() {
let (_, create) = parse_create("CREATE TABLE \"Table1\"( id UUID , column1 INT )")
.expect("should parse");
let (_, create) =
parse_create("CREATE TABLE \"Table1\"( id UUID , column1 INT )").expect("should parse");
assert!(matches!(create, RawQuerySyntax::CreateTable(_)));
match create {
RawQuerySyntax::CreateTable(schema) => {
@ -114,11 +113,13 @@ mod tests {
_ => {}
}
}
#[test]
fn test_parse_create_option() {
let (_, create) = parse_create("CREATE TABLE games (id UUID PRIMARY KEY, name STRING, year Option(INT), price NUMBER)")
.expect("should parse");
let (_, create) = parse_create(
"CREATE TABLE games (id UUID PRIMARY KEY, name STRING, year Option(INT), price NUMBER)",
)
.expect("should parse");
assert!(matches!(create, RawQuerySyntax::CreateTable(_)));
match create {
RawQuerySyntax::CreateTable(schema) => {
@ -139,16 +140,12 @@ mod tests {
assert_eq!(column1_column.type_, DbType::String);
let column = schema.get_column(&"year".to_string());
let Some(column) = column else {
panic!()
};
let Some(column) = column else { panic!() };
assert_eq!(column.column_name, "year".to_string());
assert_eq!(column.type_, DbType::Option(Box::new(DbType::Int)));
let column = schema.get_column(&"price".to_string());
let Some(column) = column else {
panic!()
};
let Some(column) = column else { panic!() };
assert_eq!(column.column_name, "price".to_string());
assert_eq!(column.type_, DbType::Number);
}

View file

@ -29,22 +29,19 @@ mod tests {
#[test]
fn test_parse_delete() {
let (_, sntx) =
parse_delete("DELETE FROM \"T1\" WHERE id = 1").expect("should parse");
let (_, sntx) = parse_delete("DELETE FROM \"T1\" WHERE id = 1").expect("should parse");
assert!(matches!(sntx, RawQuerySyntax::Delete(_, _)))
}
#[test]
fn test_parse_delete_with_spaces() {
let (_, sntx) =
parse_delete("DELETE FROM T1 WHERE id = 1").expect("should parse");
let (_, sntx) = parse_delete("DELETE FROM T1 WHERE id = 1").expect("should parse");
assert!(matches!(sntx, RawQuerySyntax::Delete(_, _)))
}
#[test]
fn test_parse_delete_none() {
let (_, sntx) =
parse_delete("DELETE FROM games WHERE year = None").expect("should parse");
let (_, sntx) = parse_delete("DELETE FROM games WHERE year = None").expect("should parse");
if let RawQuerySyntax::Delete(tname, Some(Condition::Eq(column_name, lit))) = sntx {
assert_eq!(tname, "games".to_string());
assert_eq!(column_name, "year".to_string());

View file

@ -68,10 +68,7 @@ mod tests {
insertion_values,
vec![
("id".to_string(), Literal::Int(1)),
(
"data".to_string(),
Literal::String("Text".to_string())
)
("data".to_string(), Literal::String("Text".to_string()))
]
);
}
@ -83,8 +80,7 @@ mod tests {
#[test]
fn test_parse_insert_with_spaces() {
let sql =
"INSERT INTO \"MyTable\" ( id, data ) VALUES ( 1, \"Text\" )";
let sql = "INSERT INTO \"MyTable\" ( id, data ) VALUES ( 1, \"Text\" )";
let operation = parse_insert(sql).expect("should parse");
match operation {
("", RawQuerySyntax::Insert(table_name, insertion_values)) => {
@ -93,10 +89,7 @@ mod tests {
insertion_values,
vec![
("id".to_string(), Literal::Int(1)),
(
"data".to_string(),
Literal::String("Text".to_string())
)
("data".to_string(), Literal::String("Text".to_string()))
]
);
}
@ -117,18 +110,12 @@ mod tests {
insertion_values,
vec![
("id".to_string(), Literal::Uuid(12345)),
(
"name".to_string(),
Literal::String("Doom".to_string())
),
("name".to_string(), Literal::String("Doom".to_string())),
(
"year".to_string(),
Literal::Some(Box::new(Literal::Int(1993)))
),
(
"price".to_string(),
Literal::Number(6.5)
)
("price".to_string(), Literal::Number(6.5))
]
);
}

View file

@ -1,5 +1,12 @@
use nom::{
branch::alt, bytes::complete::tag, character::complete::{char, digit1, none_of, u64}, combinator::opt, error::make_error, multi::many0, sequence::{delimited, pair, preceded}, IResult, Parser
branch::alt,
bytes::complete::tag,
character::complete::{char, digit1, none_of, u64},
combinator::opt,
error::make_error,
multi::many0,
sequence::{delimited, pair, preceded},
IResult, Parser,
};
#[derive(Debug, PartialEq)]
@ -13,7 +20,13 @@ pub enum Literal {
}
pub fn parse_literal(input: &str) -> IResult<&str, Literal> {
alt((parse_option, parse_string, parse_number, parse_int, parse_uuid))(input)
alt((
parse_option,
parse_string,
parse_number,
parse_int,
parse_uuid,
))(input)
}
pub fn parse_number(input: &str) -> IResult<&str, Literal> {
@ -92,16 +105,16 @@ pub fn parse_string(input: &str) -> IResult<&str, Literal> {
}
pub fn parse_uuid(input: &str) -> IResult<&str, Literal> {
let (input, value) = pair(char('u'), u64)(input)
.map(|(input, (_, v))| (input, Literal::Uuid(v)))?;
let (input, value) =
pair(char('u'), u64)(input).map(|(input, (_, v))| (input, Literal::Uuid(v)))?;
Ok((input, value))
}
pub fn parse_option(input: &str) -> IResult<&str, Literal> {
let (input, inner) = alt((tag("None")
.map(|_| Literal::None), delimited(tag("Some("), parse_literal, tag(")")).map(|v| {
Literal::Some(Box::new(v))
})))(input)?;
let (input, inner) = alt((
tag("None").map(|_| Literal::None),
delimited(tag("Some("), parse_literal, tag(")")).map(|v| Literal::Some(Box::new(v))),
))(input)?;
Ok((input, inner))
}
@ -114,24 +127,15 @@ mod tests {
fn test_string_parser() {
assert_eq!(
parse_string(r#""simple""#),
Ok((
"",
Literal::String(String::from("simple"))
))
Ok(("", Literal::String(String::from("simple"))))
);
assert_eq!(
parse_string(r#""\"\t\r\n\\""#),
Ok((
"",
Literal::String(String::from("\"\t\r\n\\"))
))
Ok(("", Literal::String(String::from("\"\t\r\n\\"))))
);
assert_eq!(
parse_string(r#""name is \"John\".""#),
Ok((
"",
Literal::String(String::from("name is \"John\"."))
))
Ok(("", Literal::String(String::from("name is \"John\"."))))
);
}
@ -147,13 +151,11 @@ mod tests {
let (_, _) = parse_literal("\"STRING\"").expect("should parse");
let (input, value) =
parse_literal("\"abcdefghkjklmnopqrstuvwxyz!@#$%^&*()_+ \"").expect("should parse");
parse_literal("\"abcdefghkjklmnopqrstuvwxyz!@#$%^&*()_+ \"").expect("should parse");
assert_eq!(input, "");
assert_eq!(
value,
Literal::String(
"abcdefghkjklmnopqrstuvwxyz!@#$%^&*()_+ ".to_string()
)
Literal::String("abcdefghkjklmnopqrstuvwxyz!@#$%^&*()_+ ".to_string())
);
}
@ -192,18 +194,12 @@ mod tests {
#[test]
fn test_parse_int() {
assert_eq!(
parse_literal("5134616"),
Ok(("", Literal::Int(5134616)))
);
assert_eq!(parse_literal("5134616"), Ok(("", Literal::Int(5134616))));
}
#[test]
fn test_parse_uuid() {
assert_eq!(
parse_uuid("u131515"),
Ok(("", Literal::Uuid(131515)))
)
assert_eq!(parse_uuid("u131515"), Ok(("", Literal::Uuid(131515))))
}
#[test]
@ -214,7 +210,10 @@ mod tests {
);
assert_eq!(
parse_option("Some(Some(3))"),
Ok(("", Literal::Some(Box::new(Literal::Some(Box::new(Literal::Int(3)))))))
Ok((
"",
Literal::Some(Box::new(Literal::Some(Box::new(Literal::Int(3)))))
))
);
assert_eq!(
parse_option("Some(None)"),

View file

@ -42,7 +42,9 @@ pub fn try_parse_column_selection(input: &str) -> IResult<&str, ColumnSelection>
#[cfg(test)]
mod tests {
use crate::parsing::{
common::{parse_column_name, parse_table_name}, literal::Literal, select::parse_select
common::{parse_column_name, parse_table_name},
literal::Literal,
select::parse_select,
};
use crate::syntax::{ColumnSelection, RawQuerySyntax};
@ -137,7 +139,7 @@ mod tests {
}
}
}
#[test]
fn test_parse_select_option_none() {
use crate::syntax::Condition;