From f0d29eb3996b93dc72c8b21093121b4a8bb6bcab Mon Sep 17 00:00:00 2001 From: Yuriy Dupyn <2153100+omedusyo@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:56:38 +0100 Subject: [PATCH] Make TableSchema struct fields private --- minisql/src/internals/schema.rs | 14 +++++++- minisql/src/internals/table.rs | 16 +++++---- minisql/src/interpreter.rs | 64 ++++++++++++++++----------------- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/minisql/src/internals/schema.rs b/minisql/src/internals/schema.rs index d174215..c23c24a 100644 --- a/minisql/src/internals/schema.rs +++ b/minisql/src/internals/schema.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; // then you can give the metadata to the parser without giving it the data. #[derive(Debug)] pub struct TableSchema { - pub table_name: TableName, // used for descriptive errors + table_name: TableName, // used for descriptive errors pub primary_key: ColumnPosition, pub column_name_position_mapping: BiMap, pub types: Vec, @@ -20,6 +20,18 @@ pub type TableName = String; pub type ColumnName = String; impl TableSchema { + pub fn new(table_name: TableName, primary_key: ColumnPosition, column_name_position_map: Vec<(ColumnName, ColumnPosition)>, types: Vec) -> Self { + let mut column_name_position_mapping: BiMap = BiMap::new(); + for (column_name, column_position) in column_name_position_map { + column_name_position_mapping.insert(column_name, column_position); + } + Self { table_name, primary_key, column_name_position_mapping, types } + } + + pub fn table_name(&self) -> &TableName { + &self.table_name + } + fn get_column(&self, column_name: &ColumnName) -> DbResult<(DbType, ColumnPosition)> { match self.column_name_position_mapping.get_by_left(column_name) { Some(column_position) => match self.types.get(*column_position) { diff --git a/minisql/src/internals/table.rs b/minisql/src/internals/table.rs index a36b2e6..6728a5d 100644 --- a/minisql/src/internals/table.rs +++ b/minisql/src/internals/table.rs @@ -3,7 +3,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use crate::error::Error; use crate::internals::column_index::ColumnIndex; use crate::internals::row::{ColumnPosition, Row}; -use crate::internals::schema::{ColumnName, TableSchema}; +use crate::internals::schema::{ColumnName, TableSchema, TableName}; use crate::result::DbResult; use crate::type_system::{IndexableValue, Uuid, Value}; @@ -38,6 +38,10 @@ impl Table { &self.indexes } + pub fn table_name(&self) -> &TableName { + &self.schema.table_name() + } + // ======Selection====== fn get_row_by_id(&self, id: Uuid) -> Option { self.rows.get(&id).cloned() @@ -101,7 +105,7 @@ impl Table { pub fn insert_row_at(&mut self, id: Uuid, row: Row) -> DbResult<()> { if self.rows.get(&id).is_some() { return Err(Error::AttemptingToInsertAlreadyPresentId( - self.schema.table_name.clone(), + self.table_name().clone(), id, )); } @@ -112,7 +116,7 @@ impl Table { Some(_) => {} None => { return Err(Error::ColumnPositionDoesNotExist( - self.schema.table_name.clone(), + self.schema.table_name().clone(), // Note that I can't simply use self.table_name() here because of rust borrowing rules. *column_position, )) } @@ -204,7 +208,7 @@ impl Table { .column_name_from_column_position(column_position)?; let type_ = self.schema.types[column_position]; Err(Error::ValueDoesNotMatchExpectedType( - self.schema.table_name.clone(), + self.table_name().clone(), column_name, type_, Value::Indexable(value.clone()), @@ -238,13 +242,13 @@ fn update_index_from_table( .schema .column_name_from_column_position(column_position)?; return Err(Error::AttemptToIndexNonIndexableColumn( - table.schema.table_name.to_string(), + table.table_name().to_string(), column_name, )); } None => { return Err(Error::ColumnPositionDoesNotExist( - table.schema.table_name.to_string(), + table.table_name().to_string(), column_position, )) } diff --git a/minisql/src/interpreter.rs b/minisql/src/interpreter.rs index 38bd354..2ee109d 100644 --- a/minisql/src/interpreter.rs +++ b/minisql/src/interpreter.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::internals::row::{ColumnPosition, Row}; -use crate::internals::schema::{ColumnName, TableName, TableSchema}; +use crate::internals::schema::{TableName, TableSchema}; use crate::internals::table::Table; use crate::operation::{ColumnSelection, Condition, Operation}; use crate::result::DbResult; @@ -154,25 +154,23 @@ mod tests { let name: ColumnPosition = 1; let age: ColumnPosition = 2; - TableSchema { - table_name: "users".to_string(), - primary_key: id, - column_name_position_mapping: { - let mut mapping: BiMap = BiMap::new(); - mapping.insert("id".to_string(), id); - mapping.insert("name".to_string(), name); - mapping.insert("age".to_string(), age); - mapping - }, - types: vec![DbType::Uuid, DbType::String, DbType::Int], - } + TableSchema::new( + "users".to_string(), + id, + vec!( + ("id".to_string(), id), + ("name".to_string(), name), + ("age".to_string(), age), + ), + vec![DbType::Uuid, DbType::String, DbType::Int], + ) } #[test] fn test_table_creation() { let mut state = State::new(); let users_schema = users_schema(); - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); state .interpret(Operation::CreateTable(users.clone(), users_schema)) @@ -182,14 +180,14 @@ mod tests { let table = &state.tables[0]; assert!(table.rows().len() == 0); - assert!(table.schema().table_name == users); + assert!(table.table_name() == &users); } #[test] fn test_select_empty() { let mut state = State::new(); let users_schema = users_schema(); - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); state .interpret(Operation::CreateTable(users.clone(), users_schema)) @@ -223,7 +221,7 @@ mod tests { let mut state = State::new(); let users_schema = users_schema(); - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); state .interpret(Operation::CreateTable(users.clone(), users_schema)) @@ -272,7 +270,7 @@ mod tests { let mut state = State::new(); let users_schema = users_schema(); - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); state .interpret(CreateTable(users.clone(), users_schema)) @@ -384,7 +382,7 @@ mod tests { let mut state = State::new(); let users_schema = users_schema(); - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); state .interpret(CreateTable(users.clone(), users_schema)) @@ -453,7 +451,7 @@ mod tests { let mut state = State::new(); let users_schema = users_schema(); - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); state .interpret(CreateTable(users.clone(), users_schema)) @@ -521,25 +519,23 @@ pub fn example() { use Operation::*; use Value::*; - let users_schema = { + let users_schema: TableSchema = { let id: ColumnPosition = 0; let name: ColumnPosition = 1; let age: ColumnPosition = 2; - TableSchema { - table_name: "users".to_string(), - primary_key: id, - column_name_position_mapping: { - let mut mapping: BiMap = BiMap::new(); - mapping.insert("id".to_string(), id); - mapping.insert("name".to_string(), name); - mapping.insert("age".to_string(), age); - mapping - }, - types: vec![DbType::Uuid, DbType::String, DbType::Int], - } + TableSchema::new( + "users".to_string(), + id, + vec!( + ("id".to_string(), id), + ("name".to_string(), name), + ("age".to_string(), age), + ), + vec![DbType::Uuid, DbType::String, DbType::Int], + ) }; - let users = users_schema.table_name.clone(); + let users = users_schema.table_name().clone(); let mut state = State::new(); state