From 935d9814ae4563d113878258961d5bef3032366e Mon Sep 17 00:00:00 2001 From: Yuriy Dupyn <2153100+omedusyo@users.noreply.github.com> Date: Sat, 27 Jan 2024 18:54:54 +0100 Subject: [PATCH] Introduce new simplified Operation type for Interpreter --- minisql/src/internals/row.rs | 5 +++ minisql/src/interpreter.rs | 73 +++++++++++++++++++++++++++++++++++- minisql/src/operation.rs | 18 +++++++++ minisql/src/schema.rs | 17 ++++++++- 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/minisql/src/internals/row.rs b/minisql/src/internals/row.rs index ad8dc1e..c0c81c0 100644 --- a/minisql/src/internals/row.rs +++ b/minisql/src/internals/row.rs @@ -1,4 +1,5 @@ use crate::type_system::Value; +use crate::operation::InsertionValuesForInterpreter; use std::ops::{Index, IndexMut}; use std::slice::SliceIndex; @@ -42,6 +43,10 @@ impl Row { Row(vec![]) } + pub fn new_from_insertion_values(insertion_values: InsertionValuesForInterpreter) -> Self { + Row(insertion_values) + } + pub fn with_number_of_columns(number_of_columns: usize) -> Self { Row(Vec::with_capacity(number_of_columns)) } diff --git a/minisql/src/interpreter.rs b/minisql/src/interpreter.rs index e85d085..7907ec9 100644 --- a/minisql/src/interpreter.rs +++ b/minisql/src/interpreter.rs @@ -2,7 +2,7 @@ use crate::error::Error; use crate::internals::row::{ColumnPosition, Row}; use crate::schema::{TableName, TableSchema}; use crate::internals::table::Table; -use crate::operation::{ColumnSelection, Condition, Operation}; +use crate::operation::{ColumnSelection, Condition, Operation, OperationForInterpreter, ConditionForInterpreter, ColumnSelectionForInterpreter}; use crate::result::DbResult; use crate::type_system::{DbType, IndexableValue, Value}; use bimap::BiMap; @@ -65,6 +65,7 @@ impl State { m } + // TODO: Get rid of this fn table_from_name<'a>(&'a self, table_name: &TableName) -> DbResult<&'a Table> { match self.table_name_position_mapping.get_by_left(table_name) { Some(table_position) => { @@ -75,6 +76,10 @@ impl State { } } + fn table_at<'a>(&'a self, table_position: TablePosition) -> &'a Table { + &self.tables[table_position] + } + fn table_from_name_mut<'b: 'a, 'a>( &'b mut self, table_name: &TableName, @@ -88,6 +93,10 @@ impl State { } } + fn table_at_mut<'a>(&'a mut self, table_position: TablePosition) -> &'a mut Table { + &mut self.tables[table_position] + } + fn attach_table(&mut self, table_name: TableName, table: Table) { let new_table_position: TablePosition = self.tables.len(); self.table_name_position_mapping @@ -95,7 +104,67 @@ impl State { self.tables.push(table); } - pub fn interpret<'a>(&'a mut self, operation: Operation) -> DbResult> { + pub fn interpret_for_interpreter<'a>(&'a mut self, operation: OperationForInterpreter) -> DbResult> { + // TODO: lock stuff + use OperationForInterpreter::*; + + match operation { + Select(table_position, column_selection, maybe_condition) => { + let table: &Table = self.table_at(table_position); + + let selected_rows = match maybe_condition { + None => { + let x = table.select_all_rows(column_selection); + Box::new(x) as Box + 'a + Send> + }, + + Some(ConditionForInterpreter::Eq(eq_column, value)) => { + let x = + table.select_rows_where_eq( + column_selection, + eq_column, + value, + )?; + Box::new(x) as Box + 'a + Send> + } + }; + + Ok(Response::Selected(selected_rows)) + }, + Insert(table_position, values) => { + let table: &mut Table = self.table_at_mut(table_position); + + let (id, row) = table.schema().row_from_insertion_values_for_interpreter(values)?; + table.insert_row_at(id, row)?; + Ok(Response::Inserted) + } + Delete(table_position, maybe_condition) => { + let table: &mut Table = self.table_at_mut(table_position); + + let rows_affected = match maybe_condition { + None => table.delete_all_rows(), + Some(ConditionForInterpreter::Eq(eq_column, value)) => { + table.delete_rows_where_eq(eq_column, value)? + } + }; + + Ok(Response::Deleted(rows_affected)) + } + CreateTable(table_name, table_schema) => { + let table = Table::new(table_schema); + self.attach_table(table_name, table); + + Ok(Response::TableCreated) + } + CreateIndex(table_position, column) => { + let table: &mut Table = self.table_at_mut(table_position); + table.attach_index(column)?; + Ok(Response::IndexCreated) + } + } + } + + pub fn interpret<'a>(&'a mut self, operation: Operation) -> DbResult> { // TODO: lock stuff use Operation::*; diff --git a/minisql/src/operation.rs b/minisql/src/operation.rs index 3b060c9..7c45fe3 100644 --- a/minisql/src/operation.rs +++ b/minisql/src/operation.rs @@ -1,5 +1,7 @@ use crate::schema::{ColumnName, TableName, TableSchema}; use crate::type_system::Value; +use crate::internals::row::ColumnPosition; +use crate::interpreter::TablePosition; // ==============SQL operations================ // TODO: Note that every operation has a table name. @@ -16,13 +18,25 @@ pub enum Operation { // DropTable(TableName), } +pub enum OperationForInterpreter { + Select(TablePosition, ColumnSelectionForInterpreter, Option), + Insert(TablePosition, InsertionValuesForInterpreter), + Delete(TablePosition, Option), + CreateTable(TableName, TableSchema), + CreateIndex(TablePosition, ColumnPosition), +} + pub type InsertionValues = Vec<(ColumnName, Value)>; +pub type InsertionValuesForInterpreter = Vec; + pub enum ColumnSelection { All, Columns(Vec), } +pub type ColumnSelectionForInterpreter = Vec; + pub enum Condition { // And(Box, Box), // Or(Box, Box), @@ -34,6 +48,10 @@ pub enum Condition { // StringCondition(StringCondition), } +pub enum ConditionForInterpreter { + Eq(ColumnPosition, Value), +} + // enum StringCondition { // Prefix(ColumnName, String), // Substring(ColumnName, String), diff --git a/minisql/src/schema.rs b/minisql/src/schema.rs index e029606..90022d2 100644 --- a/minisql/src/schema.rs +++ b/minisql/src/schema.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::internals::row::{ColumnPosition, Row}; -use crate::operation::{ColumnSelection, InsertionValues}; +use crate::operation::{ColumnSelection, InsertionValues, InsertionValuesForInterpreter, ColumnSelectionForInterpreter}; use crate::result::DbResult; use crate::type_system::{DbType, IndexableValue, Uuid, Value}; use bimap::BiMap; @@ -136,6 +136,21 @@ impl TableSchema { self.column_name_position_mapping.len() } + pub fn row_from_insertion_values_for_interpreter( + &self, + insertion_values: InsertionValuesForInterpreter, + ) -> DbResult<(Uuid, Row)> { + let row: Row = Row::new_from_insertion_values(insertion_values); + + let id: Uuid = match row.get(self.primary_key) { + Some(Value::Indexable(IndexableValue::Uuid(id))) => *id, + Some(_) => unreachable!(), // SAFETY: Should be guaranteed by validation + None => unreachable!(), // SAFETY: Should be guaranteed by validation + }; + + Ok((id, row)) + } + pub fn row_from_insertion_values( &self, insertion_values: InsertionValues,