sqlite-clone/sqlite_core/src/input_buffer.rs
kjuulh 4fd34f973f
All checks were successful
continuous-integration/drone/push Build is passing
Add test
2022-04-02 21:58:23 +02:00

93 lines
3.3 KiB
Rust

use crate::interaction::Interaction;
use crate::statement::{ExecuteResult, StatementResultType};
use crate::table::Table;
use crate::{interaction, statement};
use std::ops::Deref;
use std::sync::Arc;
pub struct InputBuffer {
buffer: Option<String>,
table: Table,
interaction: Arc<dyn interaction::Interaction>,
}
impl InputBuffer {
pub fn new(interaction: Arc<dyn Interaction>) -> Self {
return Self {
buffer: None,
table: Table::new(),
interaction,
};
}
pub fn print_prompt(&mut self) -> &mut Self {
self.interaction.output(String::from("db > "));
self
}
pub fn read_input(&mut self) -> Result<&mut Self, String> {
self.buffer = Some(String::new());
match &mut self.buffer {
Some(input_buffer) => {
if let Ok(input) = self.interaction.input() {
*input_buffer = input.to_string();
Ok(self)
} else {
Err(String::from("could not handle input"))
}
}
_ => Err(String::from("Could not initialize buffer")),
}
}
pub fn parse(&mut self, on_exit: fn() -> ()) {
match &self.buffer {
Some(command) => {
if command.starts_with(".") {
Self::handle_meta_statement(command, on_exit);
} else {
match Self::prepare_statement(&command.replace("\n", "")) {
Ok(statement) => {
let execution_result = statement.execute(&mut self.table);
match execution_result {
ExecuteResult::Success {
statement_result_type: StatementResultType::Insert,
} => self
.interaction
.deref()
.output(String::from("insert success\n")),
ExecuteResult::Success {
statement_result_type: StatementResultType::Select { rows },
} => {
for row in rows {
self.interaction.output(row.print())
}
self.interaction.output(String::from("select success\n"))
}
_ => self.interaction.output(String::from("failure\n")),
}
}
Err(e) => {
self.interaction.output(format!("{}\n", e));
}
}
}
}
None => {}
}
}
fn prepare_statement(command: &String) -> Result<statement::Statement, String> {
return statement::Statement::parse_statement(command);
}
fn handle_meta_statement(command: &String, on_exit: fn()) {
match command.replace("\n", "").trim() {
".exit" => on_exit(),
cmd => {
println!("Could not handle command: {cmd}")
}
}
}
}