Skip to content

Commit

Permalink
Huge refactoring in progress for v2
Browse files Browse the repository at this point in the history
  • Loading branch information
paolorechia committed Jan 8, 2024
1 parent b51d4a4 commit cda84a9
Show file tree
Hide file tree
Showing 21 changed files with 188 additions and 153 deletions.
13 changes: 2 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,5 @@ authors = ["Paolo Rechia"]
[dependencies]
log = "0.4.20"
env_logger = { version = "0.10.1", features = ["color"] }
steeldb-parser = { path = "steeldb-parser", optional = true }
hyper = { version = "1", features = ["full"], optional = true}
tokio = { version = "1", features = ["full"], optional = true}
http-body-util = {version = "0.1", optional = true}
hyper-util = { version = "0.1", features = ["full"], optional = true}

[features]
default = ["database"]
database = ["dep:steeldb-parser"]
client = ["dep:hyper", "dep:tokio", "dep:http-body-util", "dep:hyper-util"]
server = ["dep:hyper", "dep:tokio", "dep:http-body-util", "dep:hyper-util", "dep:steeldb-parser"]
steeldb-parser = { path = "steeldb-parser" }
steeldb-core = { path = "steeldb-core" }
23 changes: 1 addition & 22 deletions src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,20 @@
//! It's the root module of the SteelDB package, being the entrypoint into the Database code.
//! Everything that should be accessed is re-exported in the 'lib.rs' file.
pub mod datatypes;

mod logger;

pub mod table;

#[cfg(feature = "database")]
mod table_impl;
mod in_memory_table;

#[cfg(feature = "database")]
mod command;

#[cfg(feature = "database")]
pub mod config;

#[cfg(feature = "database")]
pub mod console_printer;

#[cfg(feature = "database")]
mod file_io;

#[cfg(feature = "database")]
mod parser;

#[cfg(feature = "database")]
pub mod repl;

#[cfg(feature = "database")]
pub mod steeldb;

#[cfg(feature = "database")]
mod tests;

#[cfg(feature = "database")]
mod virtual_machine;

#[cfg(feature = "server")]
pub mod server;
4 changes: 2 additions & 2 deletions src/database/command.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Defines commands that the VirtualMachine may execute.
use crate::database::table::Table;
use crate::database::in_memory_table::InMemoryTable;

/// All known commands are defined in this enum.
pub enum Command {
Expand All @@ -12,7 +12,7 @@ pub enum Command {
/// Defines possible results from a command execution.
pub enum CommandResult {
/// Command returned a table.
RetrievedDataSuccess(Table),
RetrievedDataSuccess(InMemoryTable),
/// Command failed by an unexpected reason.
Error(String),
/// Command succeded but has no output.
Expand Down
28 changes: 1 addition & 27 deletions src/database/file_io.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,12 @@
//! This module defines structs / methods to save/read data to/from disk.
use crate::database::datatypes::DataType;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Read, Write};
use steeldb_core::DataType;

/// Defines the string 'TABLE COLUMNAR FORMAT HEADER\n' that goes to the top of the columnar file.
const COLUMNAR_HEADER: [u8; 29] = *b"TABLE COLUMNAR FORMAT HEADER\n";

// Enums
/// Defines the supported file formats by the Database
#[derive(Debug)]
pub enum FileFormat {
/// The only supported file for now is the SimpleColumnar, which is a naive ASCII format.
/// Here is an example of this format:
/// ```txt
/// TABLE COLUMNAR FORMAT HEADER
/// Field name: final_grade; Type: f32; Number of elements: 3
/// 4.0
/// 3.2
/// 5
/// Field name: name; Type: String; Number of elements: 3
/// John Man
/// Lenon
/// Mary
/// Field name: annual_salary; Type: i32; Number of elements: 3
/// 60000
/// 200000
/// 3012000
///
/// ```
/// Notice that the newline at the end is not optional.
SimpleColumnar,
}

// Traits
/// The public interface of a table Writer. Used for dynamic dispatching in runtime.
pub trait Writer {
Expand Down
51 changes: 41 additions & 10 deletions src/database/table_impl.rs → src/database/in_memory_table.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
//! In memory data representations.
use crate::database::config::DATA_DIR;
use crate::database::file_io::{ColumnarReader, ColumnarWriter, FileFormat, Reader, Writer};
use crate::database::table::{SaveMode, Table, TableErrors};
use crate::database::file_io::{ColumnarReader, ColumnarWriter, Reader, Writer};
use log::info;
use std::collections::HashMap;
use std::fs::OpenOptions;
use std::path::Path;
use steeldb_core::{DataType, FileFormat, SaveMode, Table, TableErrors};

impl Table {
/// This defines a way to keep the data in-memory by the SteelDB.
/// It also represents the Table that the user receives back when querying the database.
/// This is currently in a columnar format.
/// Most of the exposed functionality here is a low level API meant to be used during the
/// database development. It is not meant to be used directly by database users.
#[derive(Debug)]
pub struct InMemoryTable {
/// The table name, this is used as an identifier for retrieving the correct table.
pub name: String,
/// The table fields or schema.
pub fields: HashMap<String, DataType>,
/// The actual data stored in columnar format.
pub columns: HashMap<String, Vec<DataType>>,
/// Used when retrieving data, allowing for projection push-down on query.
/// That is, the Database do not read columns that were not specified in the query.
pub select_columns: Vec<String>,
}

impl InMemoryTable {
/// Creates the data dir if it does not yet exist.
pub fn init_data_dir() {
if !Path::new(DATA_DIR).exists() {
Expand All @@ -20,9 +39,20 @@ impl Table {
FileFormat::SimpleColumnar => format!("{}/{}.columnar", DATA_DIR, name),
}
}
pub fn new() -> InMemoryTable {
InMemoryTable {
name: String::new(),
fields: HashMap::<String, DataType>::new(),
columns: HashMap::<String, Vec<DataType>>::new(),
select_columns: Vec::<String>::new(),
}
}
}

impl Table for InMemoryTable {
/// Saves the table to disk.
pub fn save(&self, mode: SaveMode, format: FileFormat) -> Result<(), TableErrors> {
let s = Table::get_table_path(&self.name, &format);
fn save(&self, mode: SaveMode, format: FileFormat) -> Result<(), TableErrors> {
let s = InMemoryTable::get_table_path(&self.name, &format);
let path = Path::new(&s);
info!(
"Saving table in format {:?} ({:?}) to path: {:?}",
Expand Down Expand Up @@ -71,12 +101,13 @@ impl Table {
return Ok(());
}
/// Loads the table from disk.
pub fn load(
fn load(
&self,
table_name: String,
select_columns: Vec<String>,
format: FileFormat,
) -> Result<Table, TableErrors> {
let s = Table::get_table_path(&table_name, &format);
) -> Result<Box<dyn Table>, 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 Expand Up @@ -106,12 +137,12 @@ impl Table {
return Err(TableErrors::ColumnNotFound(select_col.clone()));
}
}
let table = Table {
let table = InMemoryTable {
name: table_name,
fields,
columns,
select_columns,
};
return Ok(table);
return Ok(Box::new(table));
}
}
1 change: 0 additions & 1 deletion src/database/server.rs

This file was deleted.

17 changes: 2 additions & 15 deletions src/database/steeldb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use crate::database::command::CommandResult;
use crate::database::logger::logger_init;
use crate::database::parser::{parse, ParseError};
use crate::database::table::Table;
use crate::database::virtual_machine::VirtualMachine;
use log::{error, info};
use steeldb_core::ExecutionResult;

/// The main struct exposed by the crate.
/// See the crate root documentation on how to use it.
Expand All @@ -15,19 +15,6 @@ pub struct SteelDB {
virtual_machine: VirtualMachine,
}

/// The return type given by the [SteelDB::execute] function.
pub enum ExecutionResult {
/// A result where a table was successfully computed/retrieved, and is available for inspection.
TableResult(Table),
/// 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.
ParseError(String),
/// Command error. Something went wrong when executing the command.
/// Examples include `ColumnNotFound`, `TableNotFound` etc.
CommandError(String),
}

impl SteelDB {
/// SteelDB constructor, should be called to initialize logger and virtual machine.
pub fn new() -> SteelDB {
Expand All @@ -49,7 +36,7 @@ impl SteelDB {
match command_result {
CommandResult::RetrievedDataSuccess(table) => {
info!("Retrieved data successfully");
return ExecutionResult::TableResult(table);
return ExecutionResult::TableResult(Box::new(table));
}
CommandResult::VoidSuccess => {
info!("Command successful");
Expand Down
48 changes: 0 additions & 48 deletions src/database/table.rs

This file was deleted.

16 changes: 8 additions & 8 deletions src/database/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
#[cfg(test)]
mod tests {
use crate::database::config::DATA_DIR;
use crate::database::datatypes::DataType;
use crate::database::file_io::FileFormat;
use crate::database::table::{SaveMode, Table, TableErrors};
use crate::database::in_memory_table::InMemoryTable;
use std::collections::HashMap;
use std::path::Path;
use steeldb_core::DataType;
use steeldb_core::{FileFormat, SaveMode, Table, TableErrors};

pub fn load_test_table(
table_name: String,
select_columns: Vec<String>,
) -> Result<Table, TableErrors> {
) -> Result<InMemoryTable, TableErrors> {
let mut fields = HashMap::<String, DataType>::new();
fields.insert("name".to_string(), DataType::String("name".to_string()));
fields.insert("annual_salary".to_string(), DataType::Integer32(0));
Expand Down Expand Up @@ -39,7 +39,7 @@ mod tests {
columns.insert("annual_salary".to_string(), annual_salary_column);
columns.insert("final_grade".to_string(), final_grade_column);

let mut test_table = Table {
let mut test_table = InMemoryTable {
name: table_name,
fields: fields,
columns: columns,
Expand All @@ -64,7 +64,7 @@ mod tests {
}

fn write_test_table(table_name: &str) {
Table::init_data_dir();
InMemoryTable::init_data_dir();
let mut filename = table_name.to_string();
filename.push_str(".columnar");

Expand Down Expand Up @@ -104,7 +104,7 @@ mod tests {
"annual_salary".to_string(),
"final_grade".to_string(),
];
let load_result = Table::load(
let load_result = InMemoryTable::new().load(
table_name.to_string(),
select_columns,
FileFormat::SimpleColumnar,
Expand Down Expand Up @@ -162,7 +162,7 @@ mod tests {
let table_name = "test_column_not_found";
write_test_table(&table_name);
let select_columns = vec!["durp".to_string()];
let load_result = Table::load(
let load_result = InMemoryTable::new().load(
table_name.to_string(),
select_columns,
FileFormat::SimpleColumnar,
Expand Down
8 changes: 5 additions & 3 deletions src/database/virtual_machine.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//! VirtualMachine that takes parsed interpreted as commands and executes them.
//! This effectively maps the Parser output into an actual code.
use crate::database::command::{Command, CommandResult};
use crate::database::file_io::FileFormat;
use crate::database::table::Table;
use crate::database::in_memory_table::InMemoryTable;
use steeldb_core::FileFormat;
use steeldb_core::Table;

/// For now, an empty struct, but could be extended.
pub struct VirtualMachine {}
Expand All @@ -24,7 +25,8 @@ impl VirtualMachine {
// this assumes the parser built a list of commands in the right order of execution
for command in commands {
if let Command::SelectFrom(columns, table_name) = command {
let table_result = Table::load(table_name, columns, FileFormat::SimpleColumnar);
let table_result =
InMemoryTable::new().load(table_name, columns, FileFormat::SimpleColumnar);

// if we found an error, we want to immediately abort the nested execution
if table_result.is_err() {
Expand Down
6 changes: 2 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@
mod database;

pub use database::config;
pub use database::datatypes::DataType;
pub use database::repl::Repl;
pub use database::steeldb::{ExecutionResult, SteelDB};
pub use database::table::Table;
pub use database::steeldb::SteelDB;
pub use steeldb_core::{DataType, Table};

/// Crate version defined in `Cargo.toml` file, retrieved at runtime.
/// This is displayed in the REPL.
Expand Down
Loading

0 comments on commit cda84a9

Please sign in to comment.