ColumnName ~> Column

This commit is contained in:
Yuriy Dupyn 2024-01-28 18:29:22 +01:00
parent 85bc46c5b0
commit 0ec02eeef8
6 changed files with 45 additions and 46 deletions

View file

@ -5,7 +5,7 @@ use std::slice::SliceIndex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::restricted_row::RestrictedRow; use crate::restricted_row::RestrictedRow;
pub type ColumnPosition = usize; pub type Column = usize;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Row(Vec<Value>); pub struct Row(Vec<Value>);
@ -61,13 +61,13 @@ impl Row {
self.0.len() self.0.len()
} }
pub fn get(&self, column: ColumnPosition) -> Option<&Value> { pub fn get(&self, column: Column) -> Option<&Value> {
self.0.get(column) self.0.get(column)
} }
pub fn restrict_columns(&self, columns: &Vec<ColumnPosition>) -> RestrictedRow { pub fn restrict_columns(&self, columns: &Vec<Column>) -> RestrictedRow {
// If the index from `columns` is non-existant in `row`, it will just ignore it. // If the index from `columns` is non-existant in `row`, it will just ignore it.
let mut subrow: Vec<(ColumnPosition, Value)> = vec![]; let mut subrow: Vec<(Column, Value)> = vec![];
for column in columns { for column in columns {
if let Some(value) = self.get(*column) { if let Some(value) = self.get(*column) {
subrow.push((*column, value.clone())); subrow.push((*column, value.clone()));

View file

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::error::RuntimeError; use crate::error::RuntimeError;
use crate::internals::column_index::ColumnIndex; use crate::internals::column_index::ColumnIndex;
use crate::internals::row::{ColumnPosition, Row}; use crate::internals::row::{Column, Row};
use crate::restricted_row::RestrictedRow; use crate::restricted_row::RestrictedRow;
use crate::schema::{ColumnName, TableSchema, TableName}; use crate::schema::{ColumnName, TableSchema, TableName};
use crate::result::DbResult; use crate::result::DbResult;
@ -14,7 +14,7 @@ pub struct Table {
schema: TableSchema, schema: TableSchema,
rows: Rows, // TODO: Consider wrapping this in a lock. Also consider if we need to have the rows: Rows, // TODO: Consider wrapping this in a lock. Also consider if we need to have the
// same lock for both rows and indexes // same lock for both rows and indexes
indexes: HashMap<ColumnPosition, ColumnIndex>, indexes: HashMap<Column, ColumnIndex>,
} }
pub type Rows = BTreeMap<Uuid, Row>; pub type Rows = BTreeMap<Uuid, Row>;
@ -36,7 +36,7 @@ impl Table {
&self.rows &self.rows
} }
pub fn indexes(&self) -> &HashMap<ColumnPosition, ColumnIndex> { pub fn indexes(&self) -> &HashMap<Column, ColumnIndex> {
&self.indexes &self.indexes
} }
@ -55,7 +55,7 @@ impl Table {
.collect() .collect()
} }
fn get_rows_by_value(&self, column: ColumnPosition, value: &Value) -> Vec<Row> { fn get_rows_by_value(&self, column: Column, value: &Value) -> Vec<Row> {
// brute-force search // brute-force search
self.rows self.rows
.values() .values()
@ -69,7 +69,7 @@ impl Table {
.collect() .collect()
} }
pub fn select_all_rows<'a>(&'a self, selected_columns: Vec<ColumnPosition>) -> impl Iterator<Item=RestrictedRow> + 'a { pub fn select_all_rows<'a>(&'a self, selected_columns: Vec<Column>) -> impl Iterator<Item=RestrictedRow> + 'a {
self.rows self.rows
.values() .values()
.map(move |row| row.restrict_columns(&selected_columns)) .map(move |row| row.restrict_columns(&selected_columns))
@ -77,8 +77,8 @@ impl Table {
pub fn select_rows_where_eq<'a>( pub fn select_rows_where_eq<'a>(
&'a self, &'a self,
selected_columns: Vec<ColumnPosition>, selected_columns: Vec<Column>,
column: ColumnPosition, column: Column,
value: Value, value: Value,
) -> DbResult<impl Iterator<Item=RestrictedRow> + 'a> { ) -> DbResult<impl Iterator<Item=RestrictedRow> + 'a> {
let restrict_columns_of_row = move |row: Row| row.restrict_columns(&selected_columns); let restrict_columns_of_row = move |row: Row| row.restrict_columns(&selected_columns);
@ -149,7 +149,7 @@ impl Table {
total_count total_count
} }
fn delete_rows_by_value(&mut self, column: ColumnPosition, value: &Value) -> usize { fn delete_rows_by_value(&mut self, column: Column, value: &Value) -> usize {
let matched_ids: HashSet<Uuid> = self let matched_ids: HashSet<Uuid> = self
.rows .rows
.iter() .iter()
@ -173,7 +173,7 @@ impl Table {
pub fn delete_rows_where_eq( pub fn delete_rows_where_eq(
&mut self, &mut self,
column: ColumnPosition, column: Column,
value: Value, value: Value,
) -> DbResult<usize> { ) -> DbResult<usize> {
match value { match value {
@ -186,7 +186,7 @@ impl Table {
} }
// ======Indexing====== // ======Indexing======
pub fn attach_index(&mut self, column: ColumnPosition) -> DbResult<()> { pub fn attach_index(&mut self, column: Column) -> DbResult<()> {
if self.indexes.get(&column).is_some() { if self.indexes.get(&column).is_some() {
let column_name = self.schema.column_name_from_column(column).clone(); let column_name = self.schema.column_name_from_column(column).clone();
let table_name = self.schema.table_name().clone(); let table_name = self.schema.table_name().clone();
@ -200,7 +200,7 @@ impl Table {
fn fetch_ids_from_index( fn fetch_ids_from_index(
&self, &self,
column: ColumnPosition, column: Column,
value: &IndexableValue, value: &IndexableValue,
) -> DbResult<Option<HashSet<Uuid>>> { ) -> DbResult<Option<HashSet<Uuid>>> {
if self.schema.is_primary(column) { if self.schema.is_primary(column) {
@ -228,7 +228,7 @@ impl Table {
fn update_index_from_table( fn update_index_from_table(
column_index: &mut ColumnIndex, column_index: &mut ColumnIndex,
table: &Table, table: &Table,
column: ColumnPosition, column: Column,
) -> DbResult<()> { ) -> DbResult<()> {
for (id, row) in &table.rows { for (id, row) in &table.rows {
let value = match &row[column] { let value = match &row[column] {
@ -237,7 +237,6 @@ fn update_index_from_table(
let column_name: ColumnName = table let column_name: ColumnName = table
.schema .schema
.column_name_from_column(column); .column_name_from_column(column);
// TODO: Perhaps this should be handled in validation?
return Err(RuntimeError::AttemptToIndexNonIndexableColumn( return Err(RuntimeError::AttemptToIndexNonIndexableColumn(
table.table_name().to_string(), table.table_name().to_string(),
column_name, column_name,

View file

@ -1,4 +1,4 @@
use crate::internals::row::ColumnPosition; use crate::internals::row::Column;
use crate::schema::{TableName, TableSchema}; use crate::schema::{TableName, TableSchema};
use crate::internals::table::Table; use crate::internals::table::Table;
use crate::operation::{Operation, Condition}; use crate::operation::{Operation, Condition};
@ -145,7 +145,7 @@ impl State {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::internals::row::ColumnPosition; use crate::internals::row::Column;
use std::collections::HashSet; use std::collections::HashSet;
use crate::type_system::{DbType, IndexableValue, Value}; use crate::type_system::{DbType, IndexableValue, Value};
use crate::operation::Operation; use crate::operation::Operation;
@ -259,8 +259,8 @@ mod tests {
let users_schema = users_schema(); let users_schema = users_schema();
let users_position: TablePosition = 0; let users_position: TablePosition = 0;
let id_column: ColumnPosition = 0; let id_column: Column = 0;
let name_column: ColumnPosition = 1; let name_column: Column = 1;
state state
.interpret(CreateTable(users_schema.clone())) .interpret(CreateTable(users_schema.clone()))
@ -377,7 +377,7 @@ mod tests {
let users_schema = users_schema(); let users_schema = users_schema();
let users_position: TablePosition = 0; let users_position: TablePosition = 0;
let id_column: ColumnPosition = 0; let id_column: Column = 0;
state state
.interpret(CreateTable(users_schema.clone())) .interpret(CreateTable(users_schema.clone()))
@ -451,7 +451,7 @@ mod tests {
let users_schema = users_schema(); let users_schema = users_schema();
let users_position: TablePosition = 0; let users_position: TablePosition = 0;
let name_column: ColumnPosition = 1; let name_column: Column = 1;
state state
.interpret(CreateTable(users_schema.clone())) .interpret(CreateTable(users_schema.clone()))
@ -497,7 +497,7 @@ mod tests {
let table = &state.tables[0]; let table = &state.tables[0];
assert!(table.rows().len() == 2); assert!(table.rows().len() == 2);
let user: ColumnPosition = 1; let user: Column = 1;
assert!(table.indexes().contains_key(&user)); assert!(table.indexes().contains_key(&user));
let index = table.indexes().get(&user).unwrap(); let index = table.indexes().get(&user).unwrap();
@ -519,8 +519,8 @@ pub fn example() {
use Operation::*; use Operation::*;
use Value::*; use Value::*;
let id_column: ColumnPosition = 0; let id_column: Column = 0;
let name_column: ColumnPosition = 1; let name_column: Column = 1;
// let age_column: ColumnPosition = 2; // let age_column: ColumnPosition = 2;
let users_schema: TableSchema = { let users_schema: TableSchema = {

View file

@ -1,6 +1,6 @@
use crate::schema::TableSchema; use crate::schema::TableSchema;
use crate::type_system::Value; use crate::type_system::Value;
use crate::internals::row::ColumnPosition; use crate::internals::row::Column;
use crate::interpreter::TablePosition; use crate::interpreter::TablePosition;
// Validated operation. Constructed by validation crate. // Validated operation. Constructed by validation crate.
@ -10,15 +10,15 @@ pub enum Operation {
Insert(TablePosition, InsertionValues), Insert(TablePosition, InsertionValues),
Delete(TablePosition, Option<Condition>), Delete(TablePosition, Option<Condition>),
CreateTable(TableSchema), CreateTable(TableSchema),
CreateIndex(TablePosition, ColumnPosition), CreateIndex(TablePosition, Column),
} }
// Assumes that these are sorted by column position. // Assumes that these are sorted by column position.
pub type InsertionValues = Vec<Value>; pub type InsertionValues = Vec<Value>;
pub type ColumnSelection = Vec<ColumnPosition>; pub type ColumnSelection = Vec<Column>;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Condition { pub enum Condition {
Eq(ColumnPosition, Value), Eq(Column, Value),
} }

View file

@ -1,14 +1,14 @@
use std::ops::Index; use std::ops::Index;
use std::slice::SliceIndex; use std::slice::SliceIndex;
use crate::internals::row::ColumnPosition; use crate::internals::row::Column;
use crate::type_system::Value; use crate::type_system::Value;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RestrictedRow(Vec<(ColumnPosition, Value)>); pub struct RestrictedRow(Vec<(Column, Value)>);
impl<Idx> Index<Idx> for RestrictedRow impl<Idx> Index<Idx> for RestrictedRow
where where
Idx: SliceIndex<[(ColumnPosition, Value)]>, Idx: SliceIndex<[(Column, Value)]>,
{ {
type Output = Idx::Output; type Output = Idx::Output;
@ -17,8 +17,8 @@ where
} }
} }
impl From<Vec<(ColumnPosition, Value)>> for RestrictedRow { impl From<Vec<(Column, Value)>> for RestrictedRow {
fn from(v: Vec<(ColumnPosition, Value)>) -> Self { fn from(v: Vec<(Column, Value)>) -> Self {
RestrictedRow(v) RestrictedRow(v)
} }
} }
@ -28,7 +28,7 @@ impl RestrictedRow {
self.0.len() self.0.len()
} }
pub fn iter(&self) -> impl Iterator<Item=&(ColumnPosition, Value)> { pub fn iter(&self) -> impl Iterator<Item=&(Column, Value)> {
self.0.iter() self.0.iter()
} }
} }

View file

@ -1,4 +1,4 @@
use crate::internals::row::{ColumnPosition, Row}; use crate::internals::row::{Column, Row};
use crate::operation::{InsertionValues, ColumnSelection}; use crate::operation::{InsertionValues, ColumnSelection};
use crate::result::DbResult; use crate::result::DbResult;
use crate::type_system::{DbType, IndexableValue, Uuid, Value}; use crate::type_system::{DbType, IndexableValue, Uuid, Value};
@ -10,8 +10,8 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TableSchema { pub struct TableSchema {
table_name: TableName, // used for descriptive errors table_name: TableName, // used for descriptive errors
primary_key: ColumnPosition, primary_key: Column,
column_name_position_mapping: BiMap<ColumnName, ColumnPosition>, column_name_position_mapping: BiMap<ColumnName, Column>,
types: Vec<DbType>, types: Vec<DbType>,
} }
@ -20,11 +20,11 @@ pub type ColumnName = String;
impl TableSchema { impl TableSchema {
pub fn new(table_name: TableName, primary_column_name: ColumnName, columns: Vec<ColumnName>, types: Vec<DbType>) -> Self { pub fn new(table_name: TableName, primary_column_name: ColumnName, columns: Vec<ColumnName>, types: Vec<DbType>) -> Self {
let mut column_name_position_mapping: BiMap<ColumnName, ColumnPosition> = BiMap::new(); let mut column_name_position_mapping: BiMap<ColumnName, Column> = BiMap::new();
for (column, column_name) in columns.into_iter().enumerate() { for (column, column_name) in columns.into_iter().enumerate() {
column_name_position_mapping.insert(column_name, column); column_name_position_mapping.insert(column_name, column);
} }
let primary_key: ColumnPosition = match column_name_position_mapping.get_by_left(&primary_column_name).copied() { let primary_key: Column = match column_name_position_mapping.get_by_left(&primary_column_name).copied() {
Some(primary_key) => primary_key, Some(primary_key) => primary_key,
None => unreachable!() // SAFETY: Existence of unique primary key is ensured in validation. None => unreachable!() // SAFETY: Existence of unique primary key is ensured in validation.
}; };
@ -35,7 +35,7 @@ impl TableSchema {
&self.table_name &self.table_name
} }
pub fn column_type(&self, column: ColumnPosition) -> DbType { pub fn column_type(&self, column: Column) -> DbType {
self.types[column] self.types[column]
} }
@ -47,7 +47,7 @@ impl TableSchema {
self.column_name_position_mapping.contains_left(column_name) self.column_name_position_mapping.contains_left(column_name)
} }
pub fn get_column_position(&self, column_name: &ColumnName) -> Option<ColumnPosition> { pub fn get_column_position(&self, column_name: &ColumnName) -> Option<Column> {
self.column_name_position_mapping.get_by_left(column_name).copied() self.column_name_position_mapping.get_by_left(column_name).copied()
} }
@ -57,7 +57,7 @@ impl TableSchema {
selection selection
} }
pub fn get_column(&self, column_name: &ColumnName) -> Option<(ColumnPosition, DbType)> { pub fn get_column(&self, column_name: &ColumnName) -> Option<(Column, DbType)> {
let column = self.get_column_position(column_name)?; let column = self.get_column_position(column_name)?;
Some((column, self.column_type(column))) Some((column, self.column_type(column)))
} }
@ -67,12 +67,12 @@ impl TableSchema {
self.types.get(position).copied() self.types.get(position).copied()
} }
pub fn is_primary(&self, column: ColumnPosition) -> bool { pub fn is_primary(&self, column: Column) -> bool {
self.primary_key == column self.primary_key == column
} }
// Assumes `column` comes from a validated source. // Assumes `column` comes from a validated source.
pub fn column_name_from_column(&self, column: ColumnPosition) -> ColumnName { pub fn column_name_from_column(&self, column: Column) -> ColumnName {
match self match self
.column_name_position_mapping .column_name_position_mapping
.get_by_right(&column) .get_by_right(&column)