Make TableSchema struct fields private

This commit is contained in:
Yuriy Dupyn 2024-01-08 13:56:38 +01:00
parent 966c9bf284
commit f0d29eb399
3 changed files with 53 additions and 41 deletions

View file

@ -10,7 +10,7 @@ use std::collections::HashMap;
// then you can give the metadata to the parser without giving it the data. // then you can give the metadata to the parser without giving it the data.
#[derive(Debug)] #[derive(Debug)]
pub struct TableSchema { pub struct TableSchema {
pub table_name: TableName, // used for descriptive errors table_name: TableName, // used for descriptive errors
pub primary_key: ColumnPosition, pub primary_key: ColumnPosition,
pub column_name_position_mapping: BiMap<ColumnName, ColumnPosition>, pub column_name_position_mapping: BiMap<ColumnName, ColumnPosition>,
pub types: Vec<DbType>, pub types: Vec<DbType>,
@ -20,6 +20,18 @@ pub type TableName = String;
pub type ColumnName = String; pub type ColumnName = String;
impl TableSchema { impl TableSchema {
pub fn new(table_name: TableName, primary_key: ColumnPosition, column_name_position_map: Vec<(ColumnName, ColumnPosition)>, types: Vec<DbType>) -> Self {
let mut column_name_position_mapping: BiMap<ColumnName, ColumnPosition> = 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)> { fn get_column(&self, column_name: &ColumnName) -> DbResult<(DbType, ColumnPosition)> {
match self.column_name_position_mapping.get_by_left(column_name) { match self.column_name_position_mapping.get_by_left(column_name) {
Some(column_position) => match self.types.get(*column_position) { Some(column_position) => match self.types.get(*column_position) {

View file

@ -3,7 +3,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use crate::error::Error; use crate::error::Error;
use crate::internals::column_index::ColumnIndex; use crate::internals::column_index::ColumnIndex;
use crate::internals::row::{ColumnPosition, Row}; 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::result::DbResult;
use crate::type_system::{IndexableValue, Uuid, Value}; use crate::type_system::{IndexableValue, Uuid, Value};
@ -38,6 +38,10 @@ impl Table {
&self.indexes &self.indexes
} }
pub fn table_name(&self) -> &TableName {
&self.schema.table_name()
}
// ======Selection====== // ======Selection======
fn get_row_by_id(&self, id: Uuid) -> Option<Row> { fn get_row_by_id(&self, id: Uuid) -> Option<Row> {
self.rows.get(&id).cloned() self.rows.get(&id).cloned()
@ -101,7 +105,7 @@ impl Table {
pub fn insert_row_at(&mut self, id: Uuid, row: Row) -> DbResult<()> { pub fn insert_row_at(&mut self, id: Uuid, row: Row) -> DbResult<()> {
if self.rows.get(&id).is_some() { if self.rows.get(&id).is_some() {
return Err(Error::AttemptingToInsertAlreadyPresentId( return Err(Error::AttemptingToInsertAlreadyPresentId(
self.schema.table_name.clone(), self.table_name().clone(),
id, id,
)); ));
} }
@ -112,7 +116,7 @@ impl Table {
Some(_) => {} Some(_) => {}
None => { None => {
return Err(Error::ColumnPositionDoesNotExist( 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, *column_position,
)) ))
} }
@ -204,7 +208,7 @@ impl Table {
.column_name_from_column_position(column_position)?; .column_name_from_column_position(column_position)?;
let type_ = self.schema.types[column_position]; let type_ = self.schema.types[column_position];
Err(Error::ValueDoesNotMatchExpectedType( Err(Error::ValueDoesNotMatchExpectedType(
self.schema.table_name.clone(), self.table_name().clone(),
column_name, column_name,
type_, type_,
Value::Indexable(value.clone()), Value::Indexable(value.clone()),
@ -238,13 +242,13 @@ fn update_index_from_table(
.schema .schema
.column_name_from_column_position(column_position)?; .column_name_from_column_position(column_position)?;
return Err(Error::AttemptToIndexNonIndexableColumn( return Err(Error::AttemptToIndexNonIndexableColumn(
table.schema.table_name.to_string(), table.table_name().to_string(),
column_name, column_name,
)); ));
} }
None => { None => {
return Err(Error::ColumnPositionDoesNotExist( return Err(Error::ColumnPositionDoesNotExist(
table.schema.table_name.to_string(), table.table_name().to_string(),
column_position, column_position,
)) ))
} }

View file

@ -1,6 +1,6 @@
use crate::error::Error; use crate::error::Error;
use crate::internals::row::{ColumnPosition, Row}; 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::internals::table::Table;
use crate::operation::{ColumnSelection, Condition, Operation}; use crate::operation::{ColumnSelection, Condition, Operation};
use crate::result::DbResult; use crate::result::DbResult;
@ -154,25 +154,23 @@ mod tests {
let name: ColumnPosition = 1; let name: ColumnPosition = 1;
let age: ColumnPosition = 2; let age: ColumnPosition = 2;
TableSchema { TableSchema::new(
table_name: "users".to_string(), "users".to_string(),
primary_key: id, id,
column_name_position_mapping: { vec!(
let mut mapping: BiMap<ColumnName, ColumnPosition> = BiMap::new(); ("id".to_string(), id),
mapping.insert("id".to_string(), id); ("name".to_string(), name),
mapping.insert("name".to_string(), name); ("age".to_string(), age),
mapping.insert("age".to_string(), age); ),
mapping vec![DbType::Uuid, DbType::String, DbType::Int],
}, )
types: vec![DbType::Uuid, DbType::String, DbType::Int],
}
} }
#[test] #[test]
fn test_table_creation() { fn test_table_creation() {
let mut state = State::new(); let mut state = State::new();
let users_schema = users_schema(); let users_schema = users_schema();
let users = users_schema.table_name.clone(); let users = users_schema.table_name().clone();
state state
.interpret(Operation::CreateTable(users.clone(), users_schema)) .interpret(Operation::CreateTable(users.clone(), users_schema))
@ -182,14 +180,14 @@ mod tests {
let table = &state.tables[0]; let table = &state.tables[0];
assert!(table.rows().len() == 0); assert!(table.rows().len() == 0);
assert!(table.schema().table_name == users); assert!(table.table_name() == &users);
} }
#[test] #[test]
fn test_select_empty() { fn test_select_empty() {
let mut state = State::new(); let mut state = State::new();
let users_schema = users_schema(); let users_schema = users_schema();
let users = users_schema.table_name.clone(); let users = users_schema.table_name().clone();
state state
.interpret(Operation::CreateTable(users.clone(), users_schema)) .interpret(Operation::CreateTable(users.clone(), users_schema))
@ -223,7 +221,7 @@ mod tests {
let mut state = State::new(); let mut state = State::new();
let users_schema = users_schema(); let users_schema = users_schema();
let users = users_schema.table_name.clone(); let users = users_schema.table_name().clone();
state state
.interpret(Operation::CreateTable(users.clone(), users_schema)) .interpret(Operation::CreateTable(users.clone(), users_schema))
@ -272,7 +270,7 @@ mod tests {
let mut state = State::new(); let mut state = State::new();
let users_schema = users_schema(); let users_schema = users_schema();
let users = users_schema.table_name.clone(); let users = users_schema.table_name().clone();
state state
.interpret(CreateTable(users.clone(), users_schema)) .interpret(CreateTable(users.clone(), users_schema))
@ -384,7 +382,7 @@ mod tests {
let mut state = State::new(); let mut state = State::new();
let users_schema = users_schema(); let users_schema = users_schema();
let users = users_schema.table_name.clone(); let users = users_schema.table_name().clone();
state state
.interpret(CreateTable(users.clone(), users_schema)) .interpret(CreateTable(users.clone(), users_schema))
@ -453,7 +451,7 @@ mod tests {
let mut state = State::new(); let mut state = State::new();
let users_schema = users_schema(); let users_schema = users_schema();
let users = users_schema.table_name.clone(); let users = users_schema.table_name().clone();
state state
.interpret(CreateTable(users.clone(), users_schema)) .interpret(CreateTable(users.clone(), users_schema))
@ -521,25 +519,23 @@ pub fn example() {
use Operation::*; use Operation::*;
use Value::*; use Value::*;
let users_schema = { let users_schema: TableSchema = {
let id: ColumnPosition = 0; let id: ColumnPosition = 0;
let name: ColumnPosition = 1; let name: ColumnPosition = 1;
let age: ColumnPosition = 2; let age: ColumnPosition = 2;
TableSchema { TableSchema::new(
table_name: "users".to_string(), "users".to_string(),
primary_key: id, id,
column_name_position_mapping: { vec!(
let mut mapping: BiMap<ColumnName, ColumnPosition> = BiMap::new(); ("id".to_string(), id),
mapping.insert("id".to_string(), id); ("name".to_string(), name),
mapping.insert("name".to_string(), name); ("age".to_string(), age),
mapping.insert("age".to_string(), age); ),
mapping vec![DbType::Uuid, DbType::String, DbType::Int],
}, )
types: 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(); let mut state = State::new();
state state