Move index update into attach_index

This commit is contained in:
Yuriy Dupyn 2024-01-08 13:29:49 +01:00
parent 2549a4dac1
commit 0996d0dbe1
2 changed files with 40 additions and 39 deletions

View file

@ -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(())
}

View file

@ -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:
@ -494,7 +459,9 @@ mod tests {
.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)),