fix all linter issues
This commit is contained in:
parent
91193cf03e
commit
7f85e2debf
|
@ -10,7 +10,7 @@ pub use parser::command::Command;
|
||||||
mod table;
|
mod table;
|
||||||
use parser::command::{CreateCommand, InsertCommand, SelectCommand};
|
use parser::command::{CreateCommand, InsertCommand, SelectCommand};
|
||||||
pub use table::datatypes::Datatype;
|
pub use table::datatypes::Datatype;
|
||||||
pub use table::table::{ColumnDefinition, TableDefinition};
|
pub use table::table_definition::{ColumnDefinition, TableDefinition};
|
||||||
|
|
||||||
const BUFFER_SIZE: usize = 500;
|
const BUFFER_SIZE: usize = 500;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ fn handle_create(command: CreateCommand) -> ::anyhow::Result<TableDefinition> {
|
||||||
column.data_type.as_str(),
|
column.data_type.as_str(),
|
||||||
column.length
|
column.length
|
||||||
);
|
);
|
||||||
file.write_all(line.as_bytes()).unwrap();
|
file.write_all(line.as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(command.table_definition)
|
Ok(command.table_definition)
|
||||||
|
@ -43,7 +43,7 @@ fn read_tabledef(table_name: String) -> ::anyhow::Result<TableDefinition> {
|
||||||
let parts: Vec<&str> = line_str.split(' ').collect();
|
let parts: Vec<&str> = line_str.split(' ').collect();
|
||||||
let col_def = ColumnDefinition {
|
let col_def = ColumnDefinition {
|
||||||
name: parts[0].to_string(),
|
name: parts[0].to_string(),
|
||||||
data_type: Datatype::from_str(parts[1]).unwrap(),
|
data_type: Datatype::parse_from_str(parts[1])?,
|
||||||
length: parts[2].parse::<u16>()?.into(),
|
length: parts[2].parse::<u16>()?.into(),
|
||||||
};
|
};
|
||||||
column_defs.push(col_def);
|
column_defs.push(col_def);
|
||||||
|
@ -60,10 +60,9 @@ fn handle_insert(command: InsertCommand) -> ::anyhow::Result<()> {
|
||||||
.create(true)
|
.create(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(format!("./data/blobs/{}", command.table_name))
|
.open(format!("./data/blobs/{}", command.table_name))?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let tabledef = read_tabledef(command.table_name).unwrap();
|
let tabledef = read_tabledef(command.table_name)?;
|
||||||
|
|
||||||
for col_def in &tabledef.column_defs {
|
for col_def in &tabledef.column_defs {
|
||||||
if let Some(insert_item) = command.items.get(&col_def.name) {
|
if let Some(insert_item) = command.items.get(&col_def.name) {
|
||||||
|
@ -89,7 +88,7 @@ fn handle_insert(command: InsertCommand) -> ::anyhow::Result<()> {
|
||||||
|
|
||||||
fn handle_select(command: SelectCommand) -> ::anyhow::Result<String> {
|
fn handle_select(command: SelectCommand) -> ::anyhow::Result<String> {
|
||||||
let mut file = fs::File::open(format!("./data/blobs/{}", command.table_name))?;
|
let mut file = fs::File::open(format!("./data/blobs/{}", command.table_name))?;
|
||||||
let tabledef = read_tabledef(command.table_name).unwrap();
|
let tabledef = read_tabledef(command.table_name)?;
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
|
|
||||||
response += "| ";
|
response += "| ";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use crate::table::table::ColumnDefinition;
|
use crate::table::table_definition::ColumnDefinition;
|
||||||
use crate::{Datatype, TableDefinition};
|
use crate::{Datatype, TableDefinition};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
@ -36,34 +36,34 @@ pub struct InsertItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CreateParserState {
|
enum CreateParserState {
|
||||||
FindObject,
|
Object,
|
||||||
FindTableName,
|
TableName,
|
||||||
FindColumnName,
|
ColumnName,
|
||||||
FindColumnDefinitions,
|
ColumnDefinitions,
|
||||||
FindColumnDatatype,
|
ColumnDatatype,
|
||||||
FindColumnDefinitionEnd,
|
ColumnDefinitionEnd,
|
||||||
FindColumnLength,
|
ColumnLength,
|
||||||
FindSemicolon,
|
Semicolon,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SelectParserState {
|
enum SelectParserState {
|
||||||
FindWildcard, // Temporary, col selection coming soon
|
Wildcard, // Temporary, col selection coming soon
|
||||||
FindFrom,
|
FromKeyword,
|
||||||
FindTableName,
|
TableName,
|
||||||
FindSemicolon,
|
Semicolon,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InsertParserState {
|
enum InsertParserState {
|
||||||
FindIntoKeyword,
|
IntoKeyword,
|
||||||
FindTableName,
|
TableName,
|
||||||
FindColumnListBegin,
|
ColumnListBegin,
|
||||||
FindColumnName,
|
ColumnName,
|
||||||
FindColumnNameEnd,
|
ColumnNameEnd,
|
||||||
FindValuesKeyword,
|
ValuesKeyword,
|
||||||
FindValuesListBegin,
|
ValuesListBegin,
|
||||||
FindValue,
|
Value,
|
||||||
FindValueEnd,
|
ValueEnd,
|
||||||
FindSemicolon,
|
Semicolon,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tokenizer(text: String) -> Vec<String> {
|
pub fn tokenizer(text: String) -> Vec<String> {
|
||||||
|
@ -95,7 +95,7 @@ pub fn tokenizer(text: String) -> Vec<String> {
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
fn parse_insert_command(tokens: &mut Vec<String>) -> ::anyhow::Result<Command> {
|
fn parse_insert_command(tokens: &mut Vec<String>) -> ::anyhow::Result<Command> {
|
||||||
let mut state: InsertParserState = InsertParserState::FindIntoKeyword;
|
let mut state: InsertParserState = InsertParserState::IntoKeyword;
|
||||||
|
|
||||||
let mut table_name = String::new();
|
let mut table_name = String::new();
|
||||||
let mut column_name = String::new();
|
let mut column_name = String::new();
|
||||||
|
@ -106,35 +106,35 @@ impl Command {
|
||||||
|
|
||||||
while let Some(token) = &tokens.pop() {
|
while let Some(token) = &tokens.pop() {
|
||||||
match state {
|
match state {
|
||||||
InsertParserState::FindIntoKeyword => {
|
InsertParserState::IntoKeyword => {
|
||||||
if !token.eq_ignore_ascii_case("INTO") {
|
if !token.eq_ignore_ascii_case("INTO") {
|
||||||
return Err(anyhow!("Expected to find INTO at or near '{}'", token));
|
return Err(anyhow!("Expected to find INTO at or near '{}'", token));
|
||||||
} else {
|
} else {
|
||||||
state = InsertParserState::FindTableName;
|
state = InsertParserState::TableName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InsertParserState::FindTableName => {
|
InsertParserState::TableName => {
|
||||||
table_name = token.to_string();
|
table_name = token.to_string();
|
||||||
state = InsertParserState::FindColumnListBegin;
|
state = InsertParserState::ColumnListBegin;
|
||||||
}
|
}
|
||||||
InsertParserState::FindColumnListBegin => {
|
InsertParserState::ColumnListBegin => {
|
||||||
if token != "(" {
|
if token != "(" {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Unexpected token at or near '{}'. Expected start of column list",
|
"Unexpected token at or near '{}'. Expected start of column list",
|
||||||
token
|
token
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
state = InsertParserState::FindColumnName;
|
state = InsertParserState::ColumnName;
|
||||||
}
|
}
|
||||||
InsertParserState::FindColumnName => {
|
InsertParserState::ColumnName => {
|
||||||
column_name = token.to_string();
|
column_name = token.to_string();
|
||||||
state = InsertParserState::FindColumnNameEnd;
|
state = InsertParserState::ColumnNameEnd;
|
||||||
}
|
}
|
||||||
InsertParserState::FindColumnNameEnd => {
|
InsertParserState::ColumnNameEnd => {
|
||||||
if token == "," {
|
if token == "," {
|
||||||
state = InsertParserState::FindColumnName;
|
state = InsertParserState::ColumnName;
|
||||||
} else if token == ")" {
|
} else if token == ")" {
|
||||||
state = InsertParserState::FindValuesKeyword;
|
state = InsertParserState::ValuesKeyword;
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Unexpected token at or near '{}'. Expected comma or rparen.",
|
"Unexpected token at or near '{}'. Expected comma or rparen.",
|
||||||
|
@ -143,33 +143,33 @@ impl Command {
|
||||||
}
|
}
|
||||||
column_list.push(column_name.clone());
|
column_list.push(column_name.clone());
|
||||||
}
|
}
|
||||||
InsertParserState::FindValuesKeyword => {
|
InsertParserState::ValuesKeyword => {
|
||||||
if token != "VALUES" {
|
if token != "VALUES" {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Unexpected token at or near '{}'. Expected 'VALUES'.",
|
"Unexpected token at or near '{}'. Expected 'VALUES'.",
|
||||||
token
|
token
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
state = InsertParserState::FindValuesListBegin;
|
state = InsertParserState::ValuesListBegin;
|
||||||
}
|
}
|
||||||
InsertParserState::FindValuesListBegin => {
|
InsertParserState::ValuesListBegin => {
|
||||||
if token != "(" {
|
if token != "(" {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Unexpected token at or near '{}'. Expected start of values list",
|
"Unexpected token at or near '{}'. Expected start of values list",
|
||||||
token
|
token
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
state = InsertParserState::FindValue;
|
state = InsertParserState::Value;
|
||||||
}
|
}
|
||||||
InsertParserState::FindValue => {
|
InsertParserState::Value => {
|
||||||
column_val = token.to_string();
|
column_val = token.to_string();
|
||||||
state = InsertParserState::FindValueEnd;
|
state = InsertParserState::ValueEnd;
|
||||||
}
|
}
|
||||||
InsertParserState::FindValueEnd => {
|
InsertParserState::ValueEnd => {
|
||||||
if token == "," {
|
if token == "," {
|
||||||
state = InsertParserState::FindValue;
|
state = InsertParserState::Value;
|
||||||
} else if token == ")" {
|
} else if token == ")" {
|
||||||
state = InsertParserState::FindSemicolon;
|
state = InsertParserState::Semicolon;
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Unexpected token at or near '{}'. Expected comma or rparen.",
|
"Unexpected token at or near '{}'. Expected comma or rparen.",
|
||||||
|
@ -179,7 +179,7 @@ impl Command {
|
||||||
|
|
||||||
value_list.push(column_val.clone());
|
value_list.push(column_val.clone());
|
||||||
}
|
}
|
||||||
InsertParserState::FindSemicolon => {
|
InsertParserState::Semicolon => {
|
||||||
if token != ";" {
|
if token != ";" {
|
||||||
return Err(anyhow!("Expected semicolon at or near '{}'", token));
|
return Err(anyhow!("Expected semicolon at or near '{}'", token));
|
||||||
} else {
|
} else {
|
||||||
|
@ -208,32 +208,32 @@ impl Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_select_command(tokens: &mut Vec<String>) -> ::anyhow::Result<Command> {
|
fn parse_select_command(tokens: &mut Vec<String>) -> ::anyhow::Result<Command> {
|
||||||
let mut state: SelectParserState = SelectParserState::FindWildcard;
|
let mut state: SelectParserState = SelectParserState::Wildcard;
|
||||||
|
|
||||||
// intermediate tmp vars
|
// intermediate tmp vars
|
||||||
let mut table_name = String::new();
|
let mut table_name = String::new();
|
||||||
|
|
||||||
while let Some(token) = &tokens.pop() {
|
while let Some(token) = &tokens.pop() {
|
||||||
match state {
|
match state {
|
||||||
SelectParserState::FindWildcard => {
|
SelectParserState::Wildcard => {
|
||||||
if token != "*" {
|
if token != "*" {
|
||||||
return Err(anyhow!("Expected to find selection at or near '{}' (SQUIRREL does not support column seletion)", token));
|
return Err(anyhow!("Expected to find selection at or near '{}' (SQUIRREL does not support column seletion)", token));
|
||||||
} else {
|
} else {
|
||||||
state = SelectParserState::FindFrom;
|
state = SelectParserState::FromKeyword;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SelectParserState::FindFrom => {
|
SelectParserState::FromKeyword => {
|
||||||
if !token.eq_ignore_ascii_case("FROM") {
|
if !token.eq_ignore_ascii_case("FROM") {
|
||||||
return Err(anyhow!("Expected to find FROM at or near '{}'", token));
|
return Err(anyhow!("Expected to find FROM at or near '{}'", token));
|
||||||
} else {
|
} else {
|
||||||
state = SelectParserState::FindTableName;
|
state = SelectParserState::TableName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SelectParserState::FindTableName => {
|
SelectParserState::TableName => {
|
||||||
table_name = token.to_string();
|
table_name = token.to_string();
|
||||||
state = SelectParserState::FindSemicolon;
|
state = SelectParserState::Semicolon;
|
||||||
}
|
}
|
||||||
SelectParserState::FindSemicolon => {
|
SelectParserState::Semicolon => {
|
||||||
if token != ";" {
|
if token != ";" {
|
||||||
return Err(anyhow!("Expected semicolon at or near '{}'", token));
|
return Err(anyhow!("Expected semicolon at or near '{}'", token));
|
||||||
} else {
|
} else {
|
||||||
|
@ -247,7 +247,7 @@ impl Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_create_command(tokens: &mut Vec<String>) -> ::anyhow::Result<Command> {
|
fn parse_create_command(tokens: &mut Vec<String>) -> ::anyhow::Result<Command> {
|
||||||
let mut state: CreateParserState = CreateParserState::FindObject;
|
let mut state: CreateParserState = CreateParserState::Object;
|
||||||
let mut col_defs: Vec<ColumnDefinition> = vec![];
|
let mut col_defs: Vec<ColumnDefinition> = vec![];
|
||||||
|
|
||||||
// intermediate tmp vars
|
// intermediate tmp vars
|
||||||
|
@ -258,41 +258,41 @@ impl Command {
|
||||||
|
|
||||||
while let Some(token) = &tokens.pop() {
|
while let Some(token) = &tokens.pop() {
|
||||||
match state {
|
match state {
|
||||||
CreateParserState::FindObject => match token.to_uppercase().as_str() {
|
CreateParserState::Object => match token.to_uppercase().as_str() {
|
||||||
"TABLE" => {
|
"TABLE" => {
|
||||||
state = CreateParserState::FindTableName;
|
state = CreateParserState::TableName;
|
||||||
}
|
}
|
||||||
_ => return Err(anyhow!("Can't create object of type '{}'", token.as_str())),
|
_ => return Err(anyhow!("Can't create object of type '{}'", token.as_str())),
|
||||||
},
|
},
|
||||||
CreateParserState::FindTableName => {
|
CreateParserState::TableName => {
|
||||||
state = CreateParserState::FindColumnDefinitions;
|
state = CreateParserState::ColumnDefinitions;
|
||||||
table_name = token.to_string();
|
table_name = token.to_string();
|
||||||
}
|
}
|
||||||
CreateParserState::FindColumnDefinitions => {
|
CreateParserState::ColumnDefinitions => {
|
||||||
if token != "(" {
|
if token != "(" {
|
||||||
return Err(anyhow!("Could not find column list"));
|
return Err(anyhow!("Could not find column list"));
|
||||||
} else {
|
} else {
|
||||||
state = CreateParserState::FindColumnName;
|
state = CreateParserState::ColumnName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CreateParserState::FindColumnName => {
|
CreateParserState::ColumnName => {
|
||||||
col_name = token.to_string();
|
col_name = token.to_string();
|
||||||
state = CreateParserState::FindColumnDatatype;
|
state = CreateParserState::ColumnDatatype;
|
||||||
}
|
}
|
||||||
CreateParserState::FindColumnDatatype => {
|
CreateParserState::ColumnDatatype => {
|
||||||
let dtype = Datatype::from_str(token).unwrap();
|
let dtype = Datatype::parse_from_str(token).unwrap();
|
||||||
if dtype.has_len() {
|
if dtype.has_len() {
|
||||||
state = CreateParserState::FindColumnLength;
|
state = CreateParserState::ColumnLength;
|
||||||
} else {
|
} else {
|
||||||
state = CreateParserState::FindColumnDefinitionEnd;
|
state = CreateParserState::ColumnDefinitionEnd;
|
||||||
}
|
}
|
||||||
data_type = Some(dtype);
|
data_type = Some(dtype);
|
||||||
}
|
}
|
||||||
CreateParserState::FindColumnLength => {
|
CreateParserState::ColumnLength => {
|
||||||
length = token.parse()?;
|
length = token.parse()?;
|
||||||
state = CreateParserState::FindColumnDefinitionEnd;
|
state = CreateParserState::ColumnDefinitionEnd;
|
||||||
}
|
}
|
||||||
CreateParserState::FindColumnDefinitionEnd => {
|
CreateParserState::ColumnDefinitionEnd => {
|
||||||
let column_def = ColumnDefinition {
|
let column_def = ColumnDefinition {
|
||||||
data_type: data_type.unwrap(),
|
data_type: data_type.unwrap(),
|
||||||
length,
|
length,
|
||||||
|
@ -307,15 +307,15 @@ impl Command {
|
||||||
|
|
||||||
match token.as_str() {
|
match token.as_str() {
|
||||||
"," => {
|
"," => {
|
||||||
state = CreateParserState::FindColumnName;
|
state = CreateParserState::ColumnName;
|
||||||
}
|
}
|
||||||
")" => {
|
")" => {
|
||||||
state = CreateParserState::FindSemicolon;
|
state = CreateParserState::Semicolon;
|
||||||
}
|
}
|
||||||
_ => return Err(anyhow!("Expected end")),
|
_ => return Err(anyhow!("Expected end")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CreateParserState::FindSemicolon => {
|
CreateParserState::Semicolon => {
|
||||||
if token != ";" {
|
if token != ";" {
|
||||||
return Err(anyhow!("Expected semicolon at or near '{}'", token));
|
return Err(anyhow!("Expected semicolon at or near '{}'", token));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum Datatype {
|
pub enum Datatype {
|
||||||
Integer,
|
Integer,
|
||||||
|
@ -54,14 +56,15 @@ impl Datatype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn from_str(string: &str) -> Result<Datatype, String> {
|
|
||||||
|
pub fn parse_from_str(string: &str) -> ::anyhow::Result<Datatype> {
|
||||||
match string {
|
match string {
|
||||||
"varchar" => return Ok(Datatype::CharacterVarying),
|
"varchar" => Ok(Datatype::CharacterVarying),
|
||||||
"character varying" => return Ok(Datatype::CharacterVarying),
|
"character varying" => Ok(Datatype::CharacterVarying),
|
||||||
"integer" => return Ok(Datatype::Integer),
|
"integer" => Ok(Datatype::Integer),
|
||||||
"int" => return Ok(Datatype::Integer),
|
"int" => Ok(Datatype::Integer),
|
||||||
"int8" => return Ok(Datatype::Integer),
|
"int8" => Ok(Datatype::Integer),
|
||||||
_ => return Err(String::from("Undefined data type")),
|
_ => Err(anyhow!("Undefined data type")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod datatypes;
|
pub mod datatypes;
|
||||||
pub mod table;
|
pub mod table_definition;
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
use crate::Datatype;
|
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
|
||||||
pub struct ColumnDefinition {
|
|
||||||
pub name: String,
|
|
||||||
pub data_type: Datatype,
|
|
||||||
pub length: usize, // used for char(n), varchar(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
|
||||||
pub struct TableDefinition {
|
|
||||||
pub name: String,
|
|
||||||
pub column_defs: Vec<ColumnDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TableDefinition {
|
|
||||||
pub fn get_byte_size(&self) -> usize {
|
|
||||||
let mut sum: usize = 0;
|
|
||||||
for col_def in self.column_defs.iter() {
|
|
||||||
// TODO HACK FIXME
|
|
||||||
// We should keep track of length
|
|
||||||
// even for built-in datatypes.
|
|
||||||
sum += if col_def.length > 0 {
|
|
||||||
col_def.length
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
sum
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue