ColumnName ~> Column
This commit is contained in:
parent
85bc46c5b0
commit
0ec02eeef8
6 changed files with 45 additions and 46 deletions
|
|
@ -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()));
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue