diff --git a/minisql/src/interpreter2.rs b/minisql/src/interpreter2.rs index 120c113..3a13950 100644 --- a/minisql/src/interpreter2.rs +++ b/minisql/src/interpreter2.rs @@ -3,10 +3,13 @@ use crate::restricted_row::RestrictedRow; use crate::result::DbResult; use crate::schema::{Column, TableName, TablePosition, TableSchema}; use crate::type_system::Value; -use bimap::BiMap; -use serde::{Deserialize, Serialize}; +use crate::error::RuntimeError; +use crate::response_writer::ResponseWriter; -use storage_engine::store::{Store}; +use bimap::BiMap; + +use storage_engine::store::Store; +use storage_engine::cursor::{ReadCursor, WriteCursor}; // ==============Interpreter================ #[derive(Debug)] @@ -31,6 +34,18 @@ impl Default for State { } } +impl Table { + async fn read(&self) -> DbResult> { + let cursor = self.store.read_cursor().await.map_err(|err| RuntimeError::StorageEngineError(self.schema.table_name().to_string(), err))?; + Ok(cursor) + } + + async fn write(&mut self) -> DbResult> { + let cursor = self.store.write_cursor().await.map_err(|err| RuntimeError::StorageEngineError(self.schema.table_name().to_string(), err))?; + Ok(cursor) + } +} + impl State { pub fn new() -> Self { Self { @@ -50,17 +65,43 @@ impl State { todo!() } - pub async fn interpret(&mut self, operation: Operation) -> DbResult<()> { + fn table_at(&self, table_position: TablePosition) -> &Table { + &self.tables[table_position] + } + + fn table_at_mut(&mut self, table_position: TablePosition) -> &mut Table { + &mut self.tables[table_position] + } + + pub async fn interpret(&mut self, response_writer: &mut Writer, operation: Operation) -> DbResult<()> { use Operation::*; match operation { Select(table_position, column_selection, maybe_condition) => { + let table: &Table = self.table_at(table_position); + let cursor = table.read().await?; + + let selected_rows = match maybe_condition { + None => { + // select all rows + todo!() + } + + Some(Condition::Eq(eq_column, value)) => { + todo!() + } + }; + todo!() } Insert(table_position, values) => { + let table: &mut Table = self.table_at_mut(table_position); + let cursor = table.write().await?; todo!() } Delete(table_position, maybe_condition) => { + let table: &mut Table = self.table_at_mut(table_position); + let cursor = table.write().await?; todo!() } CreateTable(table_schema) => { diff --git a/storage_engine/src/cursor.rs b/storage_engine/src/cursor.rs index 80d8de8..2aab2b6 100644 --- a/storage_engine/src/cursor.rs +++ b/storage_engine/src/cursor.rs @@ -13,7 +13,8 @@ use crate::segments::store_header::StoreHeader; use crate::store::{Store, FilePosition, Column, Result, ROWS_FILE_NAME, GARBAGE_COLLECTION_INTERMEDIATE_ROWS_FILE_NAME}; use crate::index::Index; use crate::cursor_capabilities::primitive::{CursorCanRead, CursorCanWrite}; -use crate::cursor_capabilities::header_access::{CursorCanReadHeader, CursorCanWriteHeader}; +use crate::cursor_capabilities::traversal::CursorCanTraverse; +use crate::cursor_capabilities::entry_modification::CursorCanModifyEntries; use crate::cursor_capabilities::index_access::{CursorCanWriteToIndex, CursorCanReadIndex}; const GARBAGE_COLLECTION_TRIGGER: usize = 100; @@ -82,24 +83,24 @@ impl CursorCanWrite for AppendOnlyCursor {} // ===capability to access header=== -impl CursorCanReadHeader for ReadCursor<'_, T> { +impl CursorCanTraverse for ReadCursor<'_, T> { fn header(&self) -> &StoreHeader { &self.header } } -impl CursorCanReadHeader for WriteCursor<'_, T> { +impl CursorCanTraverse for WriteCursor<'_, T> { fn header(&self) -> &StoreHeader { &self.header } } -impl CursorCanReadHeader for AppendOnlyCursor { +impl CursorCanTraverse for AppendOnlyCursor { fn header(&self) -> &StoreHeader { &self.header } } -impl CursorCanWriteHeader for WriteCursor<'_, T> { +impl CursorCanModifyEntries for WriteCursor<'_, T> { fn header_mut(&mut self) -> &mut StoreHeader { self.header } fn set_eof_file_position(&mut self, new_file_position: FilePosition) { self.eof_file_position = new_file_position } } -impl CursorCanWriteHeader for AppendOnlyCursor { +impl CursorCanModifyEntries for AppendOnlyCursor { fn header_mut(&mut self) -> &mut StoreHeader { &mut self.header } fn set_eof_file_position(&mut self, new_file_position: FilePosition) { self.eof_file_position = new_file_position } } diff --git a/storage_engine/src/cursor_capabilities/entry_modification.rs b/storage_engine/src/cursor_capabilities/entry_modification.rs new file mode 100644 index 0000000..6622347 --- /dev/null +++ b/storage_engine/src/cursor_capabilities/entry_modification.rs @@ -0,0 +1,67 @@ +use async_trait::async_trait; + +use bincode; +use bincode::Encode; +use crate::binary_coding::encode; + +use crate::segments::entry::Entry; +use crate::segments::store_header::StoreHeader; +use crate::store::{FilePosition, Result}; +use crate::cursor_capabilities::primitive::{CursorCanRead, CursorCanWrite}; +use crate::cursor_capabilities::traversal::CursorCanTraverse; + +#[async_trait] +pub trait CursorCanModifyEntries: CursorCanTraverse + CursorCanWrite { + fn header_mut(&mut self) -> &mut StoreHeader; + fn set_eof_file_position(&mut self, new_file_position: FilePosition); + + // ===Store Header Manipulation=== + async fn increment_total_count(&mut self) -> Result<()> + where T: Send + { + self.seek_to_start().await?; + self.seek_to(StoreHeader::TOTAL_COUNT_OFFSET as u64).await?; + let new_count = self.header_mut().increment_total_count(); + self.write_bytes(&encode::(&new_count)?).await?; + Ok(()) + } + + async fn increment_deleted_count(&mut self) -> Result<()> + where T: Send + { + self.seek_to_start().await?; + self.seek_to(StoreHeader::DELETED_COUNT_OFFSET as u64).await?; + let new_count = self.header_mut().increment_deleted_count(); + self.write_bytes(&encode::(&new_count)?).await?; + Ok(()) + } + + async fn set_header(&mut self, header: &StoreHeader) -> Result<()> + where T: Send + { + self.seek_to_start().await?; + let encoded_header: Vec = header.encode()?; + self.write_bytes(&encoded_header).await?; + + Ok(()) + } + + // ===Append Entry=== + + // Moves cursor to the end. + // Returns file position to the start of the new entry. + async fn append_entry_no_indexing(&mut self, entry: &Entry) -> Result + where T: Encode + Send + Sync + { + self.increment_total_count().await?; + + let encoded_entry: Vec = entry.encode()?; + let file_position = self.seek_to_end().await?; + self.write_bytes(&encoded_entry).await?; + + let eof_file_position: FilePosition = self.current_file_position().await?; + self.set_eof_file_position(eof_file_position); + + Ok(file_position) + } +} diff --git a/storage_engine/src/cursor_capabilities/index_access.rs b/storage_engine/src/cursor_capabilities/index_access.rs index 1eca46c..81ee38e 100644 --- a/storage_engine/src/cursor_capabilities/index_access.rs +++ b/storage_engine/src/cursor_capabilities/index_access.rs @@ -9,10 +9,11 @@ use crate::error::Error; use crate::segments::entry::{Entry, EntryDetailed}; use crate::store::{FilePosition, Column, Result}; use crate::index::Index; -use crate::cursor_capabilities::header_access::{CursorCanReadHeader, CursorCanWriteHeader}; +use crate::cursor_capabilities::traversal::CursorCanTraverse; +use crate::cursor_capabilities::entry_modification::CursorCanModifyEntries; #[async_trait] -pub trait CursorCanReadIndex: CursorCanReadHeader { +pub trait CursorCanReadIndex: CursorCanTraverse { fn indexes(&mut self) -> &[Option>]; async fn index_lookup(&mut self, column: Column, value: &T) -> Result>> @@ -52,7 +53,7 @@ pub trait CursorCanReadIndex: CursorCanReadHeader { } #[async_trait] -pub trait CursorCanWriteToIndex: CursorCanReadIndex + CursorCanWriteHeader { +pub trait CursorCanWriteToIndex: CursorCanReadIndex + CursorCanModifyEntries { fn indexes_mut(&mut self) -> &mut [Option>]; // Assumes that the column is indexable. diff --git a/storage_engine/src/cursor_capabilities/mod.rs b/storage_engine/src/cursor_capabilities/mod.rs index 6d301cb..d3a3bcb 100644 --- a/storage_engine/src/cursor_capabilities/mod.rs +++ b/storage_engine/src/cursor_capabilities/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod primitive; -pub(crate) mod header_access; +pub(crate) mod traversal; +pub(crate) mod entry_modification; pub(crate) mod index_access; diff --git a/storage_engine/src/cursor_capabilities/header_access.rs b/storage_engine/src/cursor_capabilities/traversal.rs similarity index 74% rename from storage_engine/src/cursor_capabilities/header_access.rs rename to storage_engine/src/cursor_capabilities/traversal.rs index 96bdbea..00a1da6 100644 --- a/storage_engine/src/cursor_capabilities/header_access.rs +++ b/storage_engine/src/cursor_capabilities/traversal.rs @@ -2,18 +2,19 @@ use tokio::io::AsyncReadExt; use async_trait::async_trait; use bincode; -use bincode::{Decode, Encode}; -use crate::binary_coding::{encode, decode}; +use bincode::Decode; +use crate::binary_coding::decode; use crate::error::{Error, DecodeErrorKind}; -use crate::segments::entry::{Entry, EntryDetailed}; +use crate::segments::entry::EntryDetailed; use crate::segments::entry_header::EntryHeaderWithDataSize; use crate::segments::store_header::StoreHeader; use crate::store::{FilePosition, Column, Result}; -use crate::cursor_capabilities::primitive::{CursorCanRead, CursorCanWrite}; +use crate::cursor_capabilities::primitive::CursorCanRead; + #[async_trait] -pub trait CursorCanReadHeader: CursorCanRead { +pub trait CursorCanTraverse: CursorCanRead { fn header(&self) -> &StoreHeader; async fn seek_to_start_of_data(&mut self) -> Result { @@ -172,59 +173,3 @@ pub trait CursorCanReadHeader: CursorCanRead { Ok(bytes) } } - -#[async_trait] -pub trait CursorCanWriteHeader: CursorCanReadHeader + CursorCanWrite { - fn header_mut(&mut self) -> &mut StoreHeader; - fn set_eof_file_position(&mut self, new_file_position: FilePosition); - - // ===Store Header Manipulation=== - async fn increment_total_count(&mut self) -> Result<()> - where T: Send - { - self.seek_to_start().await?; - self.seek_to(StoreHeader::TOTAL_COUNT_OFFSET as u64).await?; - let new_count = self.header_mut().increment_total_count(); - self.write_bytes(&encode::(&new_count)?).await?; - Ok(()) - } - - async fn increment_deleted_count(&mut self) -> Result<()> - where T: Send - { - self.seek_to_start().await?; - self.seek_to(StoreHeader::DELETED_COUNT_OFFSET as u64).await?; - let new_count = self.header_mut().increment_deleted_count(); - self.write_bytes(&encode::(&new_count)?).await?; - Ok(()) - } - - async fn set_header(&mut self, header: &StoreHeader) -> Result<()> - where T: Send - { - self.seek_to_start().await?; - let encoded_header: Vec = header.encode()?; - self.write_bytes(&encoded_header).await?; - - Ok(()) - } - - // ===Append Entry=== - - // Moves cursor to the end. - // Returns file position to the start of the new entry. - async fn append_entry_no_indexing(&mut self, entry: &Entry) -> Result - where T: Encode + Send + Sync - { - self.increment_total_count().await?; - - let encoded_entry: Vec = entry.encode()?; - let file_position = self.seek_to_end().await?; - self.write_bytes(&encoded_entry).await?; - - let eof_file_position: FilePosition = self.current_file_position().await?; - self.set_eof_file_position(eof_file_position); - - Ok(file_position) - } -} diff --git a/storage_engine/src/store.rs b/storage_engine/src/store.rs index 7798e10..ec2dca1 100644 --- a/storage_engine/src/store.rs +++ b/storage_engine/src/store.rs @@ -6,7 +6,7 @@ use bincode::{Decode, Encode}; use crate::error::Error; use crate::cursor::{ReadCursor, WriteCursor}; -use crate::cursor_capabilities::header_access::CursorCanReadHeader; +use crate::cursor_capabilities::traversal::CursorCanTraverse; use crate::segments::store_header::StoreHeader; use crate::index::Index; @@ -208,8 +208,8 @@ impl Store { mod tests { use super::*; use crate::segments::entry::Entry; - use crate::cursor_capabilities::header_access::CursorCanReadHeader; use crate::cursor_capabilities::index_access::{CursorCanWriteToIndex, CursorCanReadIndex}; + use crate::cursor_capabilities::traversal::CursorCanTraverse; impl Drop for Store { fn drop(&mut self) {