diff --git a/minisql/src/internals/table.rs b/minisql/src/internals/table.rs index 9cf0cac..975a4b8 100644 --- a/minisql/src/internals/table.rs +++ b/minisql/src/internals/table.rs @@ -171,8 +171,11 @@ impl Table { } // ======Indexing====== - pub fn attach_index(&mut self, column_position: ColumnPosition, column_index: ColumnIndex) { + pub fn attach_index(&mut self, column_position: ColumnPosition) -> DbResult<()> { + let mut column_index: ColumnIndex = ColumnIndex::new(); + update_index_from_table(&mut column_index, self, column_position)?; self.indexes.insert(column_position, column_index); + Ok(()) } fn fetch_ids_from_index( @@ -207,3 +210,34 @@ impl Table { } } } + +// Should be used in the case when an index is created after the table has existed for a +// while. In such a case you need to build the index from the already existing rows. +fn update_index_from_table( + column_index: &mut ColumnIndex, + table: &Table, + column_position: ColumnPosition, +) -> DbResult<()> { + for (id, row) in &table.rows { + let value = match row.get(column_position) { + Some(Value::Indexable(value)) => value.clone(), + Some(_) => { + let column_name: ColumnName = table + .schema + .column_name_from_column_position(column_position)?; + return Err(Error::AttemptToIndexNonIndexableColumn( + table.schema.table_name.to_string(), + column_name, + )); + } + None => { + return Err(Error::ColumnPositionDoesNotExist( + table.schema.table_name.to_string(), + column_position, + )) + } + }; + column_index.add(value, *id) + } + Ok(()) +} diff --git a/minisql/src/interpreter.rs b/minisql/src/interpreter.rs index 8bce46b..1554570 100644 --- a/minisql/src/interpreter.rs +++ b/minisql/src/interpreter.rs @@ -1,5 +1,4 @@ use crate::error::Error; -use crate::internals::column_index::ColumnIndex; use crate::internals::row::{ColumnPosition, Row}; use crate::internals::schema::{ColumnName, TableName, TableSchema}; use crate::internals::table::Table; @@ -134,47 +133,13 @@ impl State { .schema .column_position_from_column_name(&column_name)?; - let mut index: ColumnIndex = ColumnIndex::new(); - update_index_from_table(&mut index, table, column_position)?; - - table.attach_index(column_position, index); + table.attach_index(column_position)?; Ok(Response::IndexCreated) } } } } -// Should be used in the case when an index is created after the table has existed for a -// while. In such a case you need to build the index from the already existing rows. -fn update_index_from_table( - column_index: &mut ColumnIndex, - table: &Table, - column_position: ColumnPosition, -) -> DbResult<()> { - for (id, row) in &table.rows { - let value = match row.get(column_position) { - Some(Value::Indexable(value)) => value.clone(), - Some(_) => { - let column_name: ColumnName = table - .schema - .column_name_from_column_position(column_position)?; - return Err(Error::AttemptToIndexNonIndexableColumn( - table.schema.table_name.to_string(), - column_name, - )); - } - None => { - return Err(Error::ColumnPositionDoesNotExist( - table.schema.table_name.to_string(), - column_position, - )) - } - }; - column_index.add(value, *id) - } - Ok(()) -} - // TODO: Give a better name to something that you can respond to with rows trait SqlResponseConsumer { // TODO: @@ -493,8 +458,10 @@ mod tests { state .interpret(CreateTable(users.clone(), users_schema)) .unwrap(); - - state.interpret(CreateIndex(users.clone(), "name".to_string())).unwrap(); + + state + .interpret(CreateIndex(users.clone(), "name".to_string())) + .unwrap(); let (id0, name0, age0) = ( Indexable(Uuid(0)),