Improve Create Table
This commit is contained in:
parent
4a099468b2
commit
7b5b2bf9f3
6 changed files with 197 additions and 107 deletions
|
|
@ -1,4 +1,3 @@
|
|||
use minisql::{schema::{ColumnName, TableSchema}, type_system::DbType};
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete::{char, multispace0, multispace1},
|
||||
|
|
@ -8,7 +7,7 @@ use nom::{
|
|||
};
|
||||
|
||||
use super::common::{parse_table_name, parse_identifier, parse_db_type};
|
||||
use crate::syntax::RawQuerySyntax;
|
||||
use crate::syntax::{RawTableSchema, ColumnSchema, RawQuerySyntax};
|
||||
|
||||
pub fn parse_create(input: &str) -> IResult<&str, RawQuerySyntax> {
|
||||
let (input, _) = tag("CREATE")(input)?;
|
||||
|
|
@ -20,33 +19,21 @@ pub fn parse_create(input: &str) -> IResult<&str, RawQuerySyntax> {
|
|||
let (input, _) = char('(')(input)?;
|
||||
let (input, _) = multispace0(input)?;
|
||||
let (input, column_definitions) = parse_column_definitions(input)?;
|
||||
let mut column_name_position_mapping = Vec::new();
|
||||
let mut types: Vec<DbType> = Vec::new();
|
||||
let mut primary_key = None;
|
||||
for (position, (column_name, db_type, pk)) in column_definitions.iter().enumerate() {
|
||||
types.push(db_type.clone());
|
||||
if *pk {
|
||||
primary_key = Some(position);
|
||||
}
|
||||
column_name_position_mapping.push((column_name.clone(), position));
|
||||
}
|
||||
|
||||
let (input, _) = char(')')(input)?;
|
||||
let (input, _) = multispace0(input)?;
|
||||
let (input, _) = char(';')(input)?;
|
||||
let schema = TableSchema::new(
|
||||
table_name.to_string(),
|
||||
primary_key.unwrap_or_default(),
|
||||
column_name_position_mapping,
|
||||
types
|
||||
);
|
||||
let schema = RawTableSchema {
|
||||
table_name: table_name.to_string(),
|
||||
columns: column_definitions,
|
||||
};
|
||||
Ok((
|
||||
input,
|
||||
RawQuerySyntax::CreateTable(table_name.to_string(), schema),
|
||||
RawQuerySyntax::CreateTable(schema),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn parse_column_definitions(input: &str) -> IResult<&str, Vec<(ColumnName, DbType, bool)>> {
|
||||
fn parse_column_definitions(input: &str) -> IResult<&str, Vec<ColumnSchema>> {
|
||||
separated_list0(terminated(char(','), multispace0), parse_column_definition)(input)
|
||||
}
|
||||
|
||||
|
|
@ -58,13 +45,13 @@ fn parse_primary_key(input: &str) -> IResult<&str, &str> {
|
|||
Ok((input, "PRIMARY KEY"))
|
||||
}
|
||||
|
||||
pub fn parse_column_definition(input: &str) -> IResult<&str, (ColumnName, DbType, bool)> {
|
||||
fn parse_column_definition(input: &str) -> IResult<&str, ColumnSchema> {
|
||||
let (input, identifier) = parse_identifier(input)?;
|
||||
let (input, _) = multispace1(input)?;
|
||||
let (input, db_type) = parse_db_type(input)?;
|
||||
let (input, pk) = opt(parse_primary_key)(input).map(|(input, pk)| (input, pk.is_some()))?;
|
||||
let (input, _) = multispace0(input)?;
|
||||
Ok((input, (identifier.to_string(), db_type, pk)))
|
||||
Ok((input, ColumnSchema { column_name: identifier.to_string(), type_: db_type, is_primary: pk }))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -95,16 +82,23 @@ mod tests {
|
|||
#[test]
|
||||
fn test_parse_create() {
|
||||
let (_, create) = parse_create("CREATE TABLE \"Table1\"( id UUID , column1 INT );").expect("should parse");
|
||||
assert!(matches!(create, RawQuerySyntax::CreateTable(_ ,_)));
|
||||
assert!(matches!(create, RawQuerySyntax::CreateTable(_)));
|
||||
match create {
|
||||
RawQuerySyntax::CreateTable(name, schema) => {
|
||||
assert_eq!(name, "Table1");
|
||||
RawQuerySyntax::CreateTable(schema) => {
|
||||
assert_eq!(schema.table_name, "Table1");
|
||||
assert_eq!(schema.number_of_columns(), 2);
|
||||
assert_eq!(schema.get_column_position(&"id".to_string()).unwrap(), 0);
|
||||
assert_eq!(schema.get_column_position(&"column1".to_string()).unwrap(), 1);
|
||||
|
||||
let result_id = schema.get_column(&"id".to_string());
|
||||
assert!(matches!(result_id, Some(_)));
|
||||
let Some(id_column) = result_id else { panic!() };
|
||||
assert_eq!(id_column.column_name, "id".to_string());
|
||||
|
||||
let result_column1 = schema.get_column(&"column1".to_string());
|
||||
assert!(matches!(result_column1, Some(_)));
|
||||
let Some(column1_column) = result_column1 else { panic!() };
|
||||
assert_eq!(column1_column.column_name, "column1".to_string());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue