Make Row a wrapper type
This commit is contained in:
parent
bfb5042896
commit
f7a6cc2549
4 changed files with 91 additions and 33 deletions
|
|
@ -93,7 +93,7 @@ impl TableSchema {
|
|||
return Err(Error::MismatchBetweenInsertValuesAndColumns(self.table_name.clone(), insertion_values))
|
||||
}
|
||||
|
||||
let mut row: Row = Vec::with_capacity(number_of_columns);
|
||||
let mut row: Row = Row::with_number_of_columns(number_of_columns);
|
||||
|
||||
let mut values: HashMap<ColumnName, DbValue> = HashMap::new();
|
||||
for (column_name, db_value) in &insertion_values {
|
||||
|
|
@ -112,11 +112,11 @@ impl TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
let id = match row.get(self.primary_key) {
|
||||
let id: UUID = match row.get(self.primary_key) {
|
||||
Some(val) => {
|
||||
match val {
|
||||
DbValue::Indexable(IndexableDbValue::UUID(id)) => {
|
||||
id
|
||||
*id
|
||||
},
|
||||
_ =>
|
||||
unreachable!()
|
||||
|
|
@ -126,7 +126,6 @@ impl TableSchema {
|
|||
unreachable!()
|
||||
};
|
||||
|
||||
Ok((*id, row))
|
||||
Ok((id, row))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,81 @@
|
|||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
|
||||
use std::slice::SliceIndex;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use crate::base::{TableSchema, ColumnPosition, ColumnName, DbResult};
|
||||
use crate::type_system::{UUID, DbValue, IndexableDbValue};
|
||||
use crate::column_index::ColumnIndex;
|
||||
use crate::error::Error;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Table {
|
||||
pub schema: TableSchema,
|
||||
pub rows: Rows, // TODO: Consider wrapping this in a lock. Also consider if we need to have the
|
||||
// same lock for both rows and indexes
|
||||
pub indexes:
|
||||
HashMap<ColumnPosition, ColumnIndex> // TODO: Consider generalizing `ColumnPosition` to something that would also apply to a pair of `ColumnNames` etc
|
||||
}
|
||||
|
||||
|
||||
// ======Table Row======
|
||||
pub type Rows =
|
||||
// TODO: This should be some sort of an interface to a dictionary
|
||||
// s.t. in the background it may modify stuff in memory or talk to the disk
|
||||
BTreeMap<UUID, Row>;
|
||||
|
||||
// Use `ColumnPosition` as index
|
||||
pub type Row = Vec<DbValue>;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Row(Vec<DbValue>);
|
||||
|
||||
fn restrict_columns(row: &Row, columns: &Vec<ColumnPosition>) -> Row {
|
||||
impl<Idx> Index<Idx> for Row
|
||||
where
|
||||
Idx: SliceIndex<[DbValue]>,
|
||||
{
|
||||
type Output = Idx::Output;
|
||||
|
||||
fn index(&self, index: Idx) -> &Self::Output {
|
||||
&self.0[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<Idx> IndexMut<Idx> for Row
|
||||
where
|
||||
Idx: SliceIndex<[DbValue]>,
|
||||
{
|
||||
fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
|
||||
&mut self.0[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<DbValue> for Row {
|
||||
fn from_iter<I: IntoIterator<Item=DbValue>>(iter: I) -> Self {
|
||||
let mut v = vec![];
|
||||
for x in iter {
|
||||
v.push(x)
|
||||
}
|
||||
Row(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl Row {
|
||||
pub fn new() -> Self {
|
||||
Row(vec![])
|
||||
}
|
||||
|
||||
pub fn with_number_of_columns(number_of_columns: usize) -> Self {
|
||||
Row(Vec::with_capacity(number_of_columns))
|
||||
}
|
||||
|
||||
pub fn push(&mut self, value: DbValue) {
|
||||
self.0.push(value)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn get(&self, column_position: ColumnPosition) -> Option<&DbValue> {
|
||||
self.0.get(column_position)
|
||||
}
|
||||
|
||||
pub fn restrict_columns(&self, columns: &Vec<ColumnPosition>) -> Row {
|
||||
// If the index from `columns` is non-existant in `row`, it will just ignore it.
|
||||
let mut subrow: Row = vec![];
|
||||
let mut subrow: Row = Row::new();
|
||||
for column_position in columns {
|
||||
match row.get(*column_position) {
|
||||
match self.get(*column_position) {
|
||||
Some(value) => {
|
||||
subrow.push(value.clone())
|
||||
subrow.0.push(value.clone())
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
|
@ -38,6 +83,20 @@ fn restrict_columns(row: &Row, columns: &Vec<ColumnPosition>) -> Row {
|
|||
subrow
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ======Table======
|
||||
#[derive(Debug)]
|
||||
pub struct Table {
|
||||
pub schema: TableSchema,
|
||||
pub rows: Rows, // TODO: Consider wrapping this in a lock. Also consider if we need to have the
|
||||
// same lock for both rows and indexes
|
||||
pub indexes:
|
||||
HashMap<ColumnPosition, ColumnIndex>
|
||||
}
|
||||
|
||||
|
||||
impl Table {
|
||||
pub fn new(table_schema: TableSchema) -> Self {
|
||||
Self {
|
||||
|
|
@ -66,7 +125,7 @@ impl Table {
|
|||
}
|
||||
|
||||
pub fn select_all_rows(&self, selected_column_positions: &Vec<ColumnPosition>) -> Vec<Row> {
|
||||
self.rows.values().map(|row| restrict_columns(row, &selected_column_positions)).collect()
|
||||
self.rows.values().map(|row| row.restrict_columns(&selected_column_positions)).collect()
|
||||
}
|
||||
|
||||
pub fn select_rows_where_eq(&self, selected_column_positions: &Vec<ColumnPosition>, column_position: ColumnPosition, value: DbValue) -> DbResult<Vec<Row>> {
|
||||
|
|
@ -74,13 +133,13 @@ impl Table {
|
|||
DbValue::Indexable(value) => {
|
||||
match self.fetch_ids_from_index(column_position, &value)? {
|
||||
Some(ids) =>
|
||||
Ok(self.get_rows_by_ids(ids).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect()),
|
||||
Ok(self.get_rows_by_ids(ids).iter().map(|row| row.restrict_columns(&selected_column_positions)).collect()),
|
||||
None =>
|
||||
Ok(self.get_rows_by_value(column_position, &DbValue::Indexable(value)).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect())
|
||||
Ok(self.get_rows_by_value(column_position, &DbValue::Indexable(value)).iter().map(|row| row.restrict_columns(&selected_column_positions)).collect())
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Ok(self.get_rows_by_value(column_position, &value).iter().map(|row| restrict_columns(row, &selected_column_positions)).collect())
|
||||
Ok(self.get_rows_by_value(column_position, &value).iter().map(|row| row.restrict_columns(&selected_column_positions)).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ pub enum IndexableDbValue {
|
|||
}
|
||||
|
||||
impl DbValue {
|
||||
fn to_type(self) -> DbType {
|
||||
pub fn to_type(self) -> DbType {
|
||||
match self {
|
||||
Self::Number(_) => DbType::Number,
|
||||
Self::Indexable(val) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue