diff --git a/src/main.rs b/src/main.rs index 91035a1..142732a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -188,14 +188,14 @@ fn interpret(table_name: TableName, operation: Operation, state: &mut State, con Insert(table_name, values) => { let table: &mut Table = todo!(); - table.insert(values); - todo!() + let _ = table.insert(values)?; + Ok(Response::Inserted()) }, Delete(table_name, maybe_condition) => { let table: &mut Table = todo!(); - table.delete_where(maybe_condition); - todo!() + let rows_affected = table.delete_where(maybe_condition)?; + Ok(Response::Deleted(rows_affected)) }, CreateTable(table_name, table_schema) => { let table = Table::new(table_schema); @@ -353,6 +353,34 @@ impl Table { .collect() } + fn delete_row_by_id(&mut self, id: UUID) -> usize { + if let Some(row) = self.rows.remove(&id) { + for (column_position, column_index) in &mut self.indexes { + if let DbValue::Indexable(value) = &row[*column_position] { + column_index.remove(value, id) + }; + } + 1 + } else { + 0 + } + } + + fn delete_rows_by_ids(&mut self, ids: HashSet) -> usize { + let mut total_count = 0; + for id in ids { + total_count += self.delete_row_by_id(id) + } + total_count + } + + fn delete_rows_by_value(&mut self, column_position: ColumnPosition, value: &DbValue) -> usize { + let matched_ids: HashSet = self.rows.iter() + .filter_map(|(id, row)| if row.get(column_position) == Some(value) { Some(*id) } else { None }) + .collect(); + self.delete_rows_by_ids(matched_ids) + } + fn select_where(&self, column_selection: ColumnSelection, maybe_condition: Option) -> DbResult> { let selected_column_positions = self.schema.column_positions_from_column_selection(&column_selection)?; match maybe_condition { @@ -414,10 +442,47 @@ impl Table { Ok(()) } - fn delete_where(&mut self, maybe_condition: Option) { + fn delete_where(&mut self, maybe_condition: Option) -> DbResult { // kinda similar to select with respect to the conditions // update index - todo!() + 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) + }, + + Some(Condition::Eq(eq_column_name, value)) => { + let (type_, eq_column_position) = self.schema.get_column(&eq_column_name)?; + if self.schema.is_primary(eq_column_position) { + match value { + DbValue::Indexable(IndexableDbValue::UUID(uuid)) => { + Ok(self.delete_row_by_id(uuid)) + }, + _ => + return Err(Error::ValueDoesNotMatchExpectedType(self.schema.table_name.clone(), eq_column_name.clone(), type_, value.clone())) + } + + } else { + match value { + DbValue::Indexable(value) => { + match self.indexes.get(&eq_column_position) { + Some(column_index) => { + let ids = column_index.get(value); + 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)) + } + } + } + } } } @@ -440,7 +505,7 @@ impl ColumnIndex { } } - fn remove(&mut self, id: UUID) { + fn remove(&mut self, value: &IndexableDbValue, id: UUID) { todo!() } }