Skip to content

Commit

Permalink
Shared database ref across http requests
Browse files Browse the repository at this point in the history
  • Loading branch information
paolorechia committed Jan 10, 2024
1 parent 9109b4b commit 2c65d36
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/database/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub enum Command {
/// Defines possible results from a command execution.
pub enum CommandResult {
/// Command returned a table.
RetrievedDataSuccess(Box<dyn Table>),
RetrievedDataSuccess(Box<dyn Table + Sync + Send>),
/// Command failed by an unexpected reason.
Error(String),
/// Command succeded but has no output.
Expand Down
2 changes: 1 addition & 1 deletion src/database/in_memory_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl Table for InMemoryTable {
table_name: String,
select_columns: Vec<String>,
format: FileFormat,
) -> Result<Box<dyn Table>, TableErrors> {
) -> Result<Box<dyn Table + Sync + Send>, TableErrors> {
let s = InMemoryTable::get_table_path(&table_name, &format);
let path = Path::new(&s);
info!("Loading table in format {:?} from path: {:?}", format, path);
Expand Down
6 changes: 4 additions & 2 deletions src/database/virtual_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ impl VirtualMachine {

// if we found an error, we want to immediately abort the nested execution
if table_result.is_err() {
let error = format!("{:?}", table_result.unwrap_err());
return CommandResult::Error(error);
// TODO: fix this
// Debug trait is incompatible with Sync (apparently)
// let error = format!("{:?}", table_result.unwrap_err());
return CommandResult::Error("One or more commands failed".to_string());
} else {
// if our command succeeds, we want to save the result in case the next command needs it
let table = table_result.unwrap();
Expand Down
5 changes: 2 additions & 3 deletions steeldb-core/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub trait Table {
table_name: String,
select_columns: Vec<String>,
format: FileFormat,
) -> Result<Box<dyn Table>, TableErrors>;
) -> Result<Box<dyn Table + Sync + Send>, TableErrors>;
fn get_table_name(&self) -> String;
fn get_columns(&self) -> &HashMap<String, Vec<DataType>>;
fn get_select_columns(&self) -> &Vec<String>;
Expand All @@ -53,10 +53,9 @@ impl Debug for dyn Table {


/// The return type given by the [SteelDB::execute] function.
#[derive(Debug)]
pub enum ExecutionResult {
/// A result where a table was successfully computed/retrieved, and is available for inspection.
TableResult(Box<dyn Table>),
TableResult(Box<dyn Table + Sync + Send>),
/// A result where a command was successfully executed, but with no output.
VoidOK,
/// Parse error. The given input string was not valid for the parser.
Expand Down
28 changes: 20 additions & 8 deletions steeldb-server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
use axum::{extract::State, http::StatusCode, routing::post, Json, Router};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
use steeldb::SteelDB;
use steeldb_core::json_result::TableJSON;
use steeldb_core::SteelDBInterface;

use axum::{http::StatusCode, routing::post, Json, Router};
use steeldb_core::{ExecutionResult, SteelDBInterface};

#[tokio::main]
async fn main() {
let database = Arc::new(Mutex::new(SteelDB::new()));

// build our application with a route
let app = Router::new()
// `GET /` goes to `root`
.route("/query", post(handle_query));
.route("/query", post(handle_query))
.with_state(database);

// run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}

async fn handle_query(// this argument tells axum to parse the request body
async fn handle_query(
State(database): State<Arc<Mutex<SteelDB>>>,
// this argument tells axum to parse the request body
// as JSON into a `CreateUser` type
// Json(payload): Json<CreateUser>,
) -> (StatusCode, Json<TableJSON>) {
Expand All @@ -27,9 +33,15 @@ async fn handle_query(// this argument tells axum to parse the request body
columns: HashMap::new(),
select_columns: Vec::new(),
};
let mut database = SteelDB::new();
let result = database.execute("select name;".to_owned());

let db_mutex = Arc::clone(&database);
tokio::spawn(async move {
let mut result: Option<ExecutionResult> = None;
{
let mut db = db_mutex.lock().unwrap();
result = Some(db.execute("select name;".to_owned()));
}
return result;
});
// this will be converted into a JSON response
// with a status code of `201 Created`
(StatusCode::CREATED, Json(hello_response))
Expand Down

0 comments on commit 2c65d36

Please sign in to comment.