From f9b874f30212fbbdcb912b9efbba1de8030fb711 Mon Sep 17 00:00:00 2001 From: Yuriy Dupyn <2153100+omedusyo@users.noreply.github.com> Date: Fri, 29 Dec 2023 06:33:30 +0100 Subject: [PATCH] Simplify select_all and delete_all --- minisql/src/interpreter.rs | 2 +- minisql/src/table.rs | 160 ++++++++++++++++++++----------------- 2 files changed, 86 insertions(+), 76 deletions(-) diff --git a/minisql/src/interpreter.rs b/minisql/src/interpreter.rs index ee77ece..aba4abe 100644 --- a/minisql/src/interpreter.rs +++ b/minisql/src/interpreter.rs @@ -86,7 +86,7 @@ impl State { Delete(table_name, maybe_condition) => { let table: &mut Table = self.table_from_name_mut(&table_name)?; - let rows_affected = table.delete_where(maybe_condition)?; + let rows_affected = table.delete_rows_where(maybe_condition)?; Ok(Response::Deleted(rows_affected)) }, CreateTable(table_name, table_schema) => { diff --git a/minisql/src/table.rs b/minisql/src/table.rs index a6bf175..80c24c4 100644 --- a/minisql/src/table.rs +++ b/minisql/src/table.rs @@ -17,16 +17,13 @@ pub struct Table { } -// Use `ColumnPosition` as index -pub type Row = Vec; - pub type Rows = // TODO: This should be some sort of an interface to a dictionary // s.t. in the background it may modify stuff in memory or talk to the disk BTreeMap; - // interface - // insert(id, value) +// Use `ColumnPosition` as index +pub type Row = Vec; fn restrict_columns(row: &Row, columns: &Vec) -> Row { // If the index from `columns` is non-existant in `row`, it will just ignore it. @@ -51,10 +48,7 @@ impl Table { } } - pub fn attach_index(&mut self, column_position: ColumnPosition, column_index: ColumnIndex) { - self.indexes.insert(column_position, column_index); - } - + // ======Selection====== fn get_row_by_id(&self, id: UUID) -> Option { self.rows.get(&id).cloned() } @@ -72,6 +66,61 @@ impl Table { .collect() } + fn select_all_rows(&self, selected_column_positions: &Vec) -> Vec { + self.rows.values().map(|row| restrict_columns(row, &selected_column_positions)).collect() + } + + fn select_rows_where_eq(&self, selected_column_positions: &Vec, column_position: ColumnPosition, value: DbValue) -> DbResult> { + match value { + DbValue::Indexable(value) => { + match self.fetch_ids_from_index(column_position, &value)? { + Some(ids) => + Ok(self.get_rows_by_ids(ids).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()), + None => + Ok(self.get_rows_by_value(column_position, &DbValue::Indexable(value)).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()) + } + }, + _ => { + Ok(self.get_rows_by_value(column_position, &value).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()) + } + } + } + + pub fn select_where(&self, column_selection: ColumnSelection, condition: Option) -> DbResult> { + let selected_column_positions: Vec = self.schema.column_positions_from_column_selection(&column_selection)?; + match condition { + None => Ok(self.select_all_rows(&selected_column_positions)), + + Some(Condition::Eq(eq_column_name, value)) => { + let eq_column_position = self.schema.column_position_from_column_name(&eq_column_name)?; + self.select_rows_where_eq(&selected_column_positions, eq_column_position, value) + } + } + } + + // ======Insertion====== + pub fn insert(&mut self, values: InsertionValues) -> DbResult<()> { + let (id, row) = self.schema.row_from_insertion_values(values)?; + + if self.rows.get(&id).is_some() { + return Err(Error::AttemptingToInsertAlreadyPresentId(self.schema.table_name.clone(), id)) + } + + for (column_position, column_index) in &mut self.indexes { + match row.get(*column_position) { + Some(DbValue::Indexable(val)) => { + column_index.add(val.clone(), id) + }, + Some(_) => {}, + None => return Err(Error::ColumnPositionDoesNotExist(self.schema.table_name.clone(), *column_position)) + } + } + + let _ = self.rows.insert(id, row); + Ok(()) + } + + // ======Deletion====== fn delete_row_by_id(&mut self, id: UUID) -> usize { match self.rows.remove(&id) { Some(row) => { @@ -101,82 +150,43 @@ impl Table { self.delete_rows_by_ids(matched_ids) } - pub fn select_where(&self, column_selection: ColumnSelection, condition: Option) -> DbResult> { - let selected_column_positions = self.schema.column_positions_from_column_selection(&column_selection)?; - match condition { - None => - // select all - Ok(self.rows.values().map(|row| restrict_columns(row, &selected_column_positions)).collect()), + fn delete_all_rows(&mut self) -> usize { + let number_of_rows = self.rows.len(); + self.rows = BTreeMap::new(); + self.indexes = HashMap::new(); + number_of_rows + } - Some(Condition::Eq(eq_column_name, value)) => { - let eq_column_position = self.schema.column_position_from_column_name(&eq_column_name)?; - match value { - DbValue::Indexable(value) => { - match self.fetch_ids_from_index(eq_column_position, &value)? { - Some(ids) => - Ok(self.get_rows_by_ids(ids).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()), - None => - Ok(self.get_rows_by_value(eq_column_position, &DbValue::Indexable(value)).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()) - } - }, - _ => { - Ok(self.get_rows_by_value(eq_column_position, &value).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()) - } + fn delete_rows_where_eq(&mut self, column_position: ColumnPosition, value: DbValue) -> DbResult { + match value { + DbValue::Indexable(value) => { + match self.fetch_ids_from_index(column_position, &value)? { + Some(ids) => + Ok(self.delete_rows_by_ids(ids)), + None => + Ok(self.delete_rows_by_value(column_position, &DbValue::Indexable(value))) } - } - } - } - - pub fn insert(&mut self, values: InsertionValues) -> DbResult<()> { - let (id, row) = self.schema.row_from_insertion_values(values)?; - - if self.rows.get(&id).is_some() { - return Err(Error::AttemptingToInsertAlreadyPresentId(self.schema.table_name.clone(), id)) - } - - for (column_position, column_index) in &mut self.indexes { - match row.get(*column_position) { - Some(DbValue::Indexable(val)) => { - column_index.add(val.clone(), id) - }, - Some(_) => {}, - None => return Err(Error::ColumnPositionDoesNotExist(self.schema.table_name.clone(), *column_position)) - } - } - - let _ = self.rows.insert(id, row); - Ok(()) - } - - // TODO: Split into delete all and delete_where(condition) - pub fn delete_where(&mut self, maybe_condition: Option) -> DbResult { - match maybe_condition { - None => { - // delete all - let number_of_rows = self.rows.len(); - self.rows = BTreeMap::new(); - self.indexes = HashMap::new(); - Ok(number_of_rows) }, + _ => + Ok(self.delete_rows_by_value(column_position, &value)) + } + } + pub fn delete_rows_where(&mut self, maybe_condition: Option) -> DbResult { + match maybe_condition { + None => Ok(self.delete_all_rows()), Some(Condition::Eq(eq_column_name, value)) => { let eq_column_position = self.schema.column_position_from_column_name(&eq_column_name)?; - match value { - DbValue::Indexable(value) => { - match self.fetch_ids_from_index(eq_column_position, &value)? { - Some(ids) => - Ok(self.delete_rows_by_ids(ids)), - None => - Ok(self.delete_rows_by_value(eq_column_position, &DbValue::Indexable(value))) - } - }, - _ => - Ok(self.delete_rows_by_value(eq_column_position, &value)) - } + self.delete_rows_where_eq(eq_column_position, value) } } } + // ======Indexing====== + pub fn attach_index(&mut self, column_position: ColumnPosition, column_index: ColumnIndex) { + self.indexes.insert(column_position, column_index); + } + fn fetch_ids_from_index(&self, column_position: ColumnPosition, value: &IndexableDbValue) -> DbResult>> { if self.schema.is_primary(column_position) { match value {