feat: connect server to the new interpreter

This commit is contained in:
Jindřich Moravec 2024-02-05 21:59:33 +01:00
parent 9b9f9f16f6
commit f5d45f6a1d
6 changed files with 70 additions and 145 deletions

View file

@ -17,8 +17,8 @@ pub struct Configuration {
help = "Port for the server to listen on"
)]
port: u16,
#[arg(short, long, help = "Path to the data file")]
file: PathBuf,
#[arg(short, long, help = "Path to the folder for database data")]
folder: PathBuf,
#[arg(short, long, help = "Delay between rows in milliseconds")]
throttle: Option<u64>,
}
@ -30,8 +30,8 @@ impl Configuration {
}
#[inline]
pub fn get_file_path(&self) -> &PathBuf {
&self.file
pub fn get_folder_path(&self) -> &PathBuf {
&self.folder
}
#[inline]

View file

@ -1,14 +1,13 @@
use std::collections::HashMap;
use std::io::ErrorKind;
use std::sync::Arc;
use clap::Parser;
use tokio::io::{BufReader, BufWriter};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::{Mutex, RwLock};
use tokio::sync::Mutex;
use minisql::interpreter::{Response, State};
use minisql::response_writer::{CompleteStatus, ResponseWriter};
use minisql::interpreter2::StateHandler;
use minisql::response_writer::ResponseWriter;
use parser::parse_and_validate;
use proto::handshake::errors::ServerHandshakeError;
use proto::handshake::request::HandshakeRequest;
@ -22,23 +21,21 @@ use proto::writer::protowriter::{ProtoFlush, ProtoWriter};
use crate::cancellation::ResetCancelToken;
use crate::config::Configuration;
use crate::persistence::state_to_file;
use crate::proto_wrapper::ServerProtoWrapper;
mod cancellation;
mod config;
mod persistence;
mod proto_wrapper;
type TokenStore = Arc<Mutex<HashMap<(i32, i32), ResetCancelToken>>>;
type SharedDbState = Arc<RwLock<State>>;
type SharedDbState = Arc<StateHandler>;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let config = Configuration::parse();
let config = Arc::new(config);
let state = Arc::new(RwLock::new(get_state(&config).await?));
let state = Arc::new(get_state(&config).await?);
let tokens = Arc::new(Mutex::new(HashMap::<(i32, i32), ResetCancelToken>::new()));
let addr = config.get_socket_address();
@ -59,15 +56,12 @@ async fn main() -> anyhow::Result<()> {
}
}
async fn get_state(config: &Configuration) -> anyhow::Result<State> {
let result = persistence::state_from_file(config.get_file_path()).await;
match result {
Err(ref e) if e.kind() == ErrorKind::NotFound => {
println!("WARNING: No DB state file found, creating new one");
Ok(State::new())
}
Err(e) => Err(e)?,
Ok(state) => Ok(state),
async fn get_state(config: &Configuration) -> anyhow::Result<StateHandler> {
let path = config.get_folder_path();
if StateHandler::is_existing_db(&path) {
Ok(StateHandler::connect(path.clone()).await?)
} else {
Ok(StateHandler::new(path.clone()).await?)
}
}
@ -191,75 +185,11 @@ where
token.reset();
let operation = {
let state = state.read().await;
let db_schema = state.db_schema();
let db_schema = state.read_state().await.db_schema();
parse_and_validate(query, &db_schema)?
};
let need_write = {
let mut state = state.write().await;
let response = state.interpret(operation)?;
match response {
Response::Deleted(i) => {
writer
.write_command_complete(CompleteStatus::Delete(i))
.await?;
true
}
Response::Inserted => {
writer
.write_command_complete(CompleteStatus::Insert { oid: 0, rows: 1 })
.await?;
true
}
Response::Selected(schema, columns, mut rows) => {
writer.write_table_header(schema, &columns).await?;
match rows.next() {
Some(row) => {
writer.write_table_row(&row).await?;
let mut sent_rows = 1;
for row in rows {
sent_rows += 1;
writer.write_table_row(&row).await?;
if token.is_canceled() {
token.reset();
break;
}
}
writer
.write_command_complete(CompleteStatus::Select(sent_rows))
.await?;
}
_ => {
writer
.write_command_complete(CompleteStatus::Select(0))
.await?;
}
}
false
}
Response::TableCreated => {
writer
.write_command_complete(CompleteStatus::CreateTable)
.await?;
true
}
Response::IndexCreated => {
writer
.write_command_complete(CompleteStatus::CreateIndex)
.await?;
true
}
}
};
if need_write {
let state = state.read().await;
state_to_file(&state, config.get_file_path()).await?;
}
// TODO: PASS DOWN RESET CANCEL TOKEN
state.interpret(writer, operation).await?;
Ok(())
}

View file

@ -1,15 +0,0 @@
use minisql::interpreter::State;
use std::path::PathBuf;
use tokio::{fs, io};
pub async fn state_from_file(path: &PathBuf) -> io::Result<State> {
let content = fs::read_to_string(path).await?;
let state = serde_json::from_str(&content)?;
Ok(state)
}
pub async fn state_to_file(state: &State, path: &PathBuf) -> io::Result<()> {
let content = serde_json::to_string(state)?;
fs::write(path, content).await?;
Ok(())
}