diff --git a/minisql/src/main.rs b/minisql/src/main.rs index f3344bd..26d346f 100644 --- a/minisql/src/main.rs +++ b/minisql/src/main.rs @@ -59,7 +59,7 @@ enum IndexableDbValue { String(String), Int(u64), UUID(UUID), - // TODO: what bout null? + // TODO: what about null? } #[derive(Debug, Clone, Copy)] @@ -149,7 +149,7 @@ fn restrict_columns(row: &Row, columns: &Vec) -> Row { #[derive(Debug)] struct State { table_name_position_mapping: BiMap, - tables: Vec, + tables: Tables, } impl State { @@ -414,33 +414,18 @@ impl Table { Ok(self.rows.values().map(|row| restrict_columns(row, &selected_column_positions)).collect()), 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)) => { - match self.get_row_by_id(uuid) { - Some(row) => Ok(vec![restrict_columns(&row, &selected_column_positions)]), - None => Ok(vec![]), - } - }, - _ => 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.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()) + 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()) } } } @@ -479,31 +464,42 @@ impl Table { }, 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())) - } + 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)) + } + } + } + } - } 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)) - } + fn fetch_ids_from_index(&self, column_position: ColumnPosition, value: &IndexableDbValue) -> DbResult>> { + if self.schema.is_primary(column_position) { + match value { + IndexableDbValue::UUID(id) => + Ok(Some(HashSet::from([*id]))), + _ => { + let column_name: ColumnName = self.schema.column_name_from_column_position(column_position)?; + let type_ = self.schema.types[column_position]; + Err(Error::ValueDoesNotMatchExpectedType(self.schema.table_name.clone(), column_name, type_, DbValue::Indexable(value.clone()))) + } + } + } else { + match self.indexes.get(&column_position) { + Some(index) => { + let ids = index.get(value); + Ok(Some(ids)) + }, + None => { + Ok(None) } } } @@ -516,8 +512,8 @@ impl ColumnIndex { Self { index } } - fn get(&self, value: IndexableDbValue) -> HashSet { - match self.index.get(&value) { + fn get(&self, value: &IndexableDbValue) -> HashSet { + match self.index.get(value) { Some(set) => set.clone(), None => HashSet::new(), } @@ -593,7 +589,6 @@ enum Error { } fn main() { - println!("Hello, world!"); } @@ -826,4 +821,6 @@ mod tests { assert!(row[1] == name1); assert!(row[2] == age1); } + + // TODO: Test CreateIndex }