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))
|
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();
|
let mut values: HashMap<ColumnName, DbValue> = HashMap::new();
|
||||||
for (column_name, db_value) in &insertion_values {
|
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) => {
|
Some(val) => {
|
||||||
match val {
|
match val {
|
||||||
DbValue::Indexable(IndexableDbValue::UUID(id)) => {
|
DbValue::Indexable(IndexableDbValue::UUID(id)) => {
|
||||||
id
|
*id
|
||||||
},
|
},
|
||||||
_ =>
|
_ =>
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
@ -126,7 +126,6 @@ impl TableSchema {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((*id, row))
|
Ok((id, row))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,81 @@
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
|
|
||||||
|
use std::slice::SliceIndex;
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
use crate::base::{TableSchema, ColumnPosition, ColumnName, DbResult};
|
use crate::base::{TableSchema, ColumnPosition, ColumnName, DbResult};
|
||||||
use crate::type_system::{UUID, DbValue, IndexableDbValue};
|
use crate::type_system::{UUID, DbValue, IndexableDbValue};
|
||||||
use crate::column_index::ColumnIndex;
|
use crate::column_index::ColumnIndex;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
// ======Table Row======
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub type Rows =
|
pub type Rows =
|
||||||
// TODO: This should be some sort of an interface to a dictionary
|
// 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
|
// s.t. in the background it may modify stuff in memory or talk to the disk
|
||||||
BTreeMap<UUID, Row>;
|
BTreeMap<UUID, Row>;
|
||||||
|
|
||||||
// Use `ColumnPosition` as index
|
// 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.
|
// 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 {
|
for column_position in columns {
|
||||||
match row.get(*column_position) {
|
match self.get(*column_position) {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
subrow.push(value.clone())
|
subrow.0.push(value.clone())
|
||||||
},
|
},
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +83,20 @@ fn restrict_columns(row: &Row, columns: &Vec<ColumnPosition>) -> Row {
|
||||||
subrow
|
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 {
|
impl Table {
|
||||||
pub fn new(table_schema: TableSchema) -> Self {
|
pub fn new(table_schema: TableSchema) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -66,7 +125,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_all_rows(&self, selected_column_positions: &Vec<ColumnPosition>) -> Vec<Row> {
|
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>> {
|
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) => {
|
DbValue::Indexable(value) => {
|
||||||
match self.fetch_ids_from_index(column_position, &value)? {
|
match self.fetch_ids_from_index(column_position, &value)? {
|
||||||
Some(ids) =>
|
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 =>
|
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 {
|
impl DbValue {
|
||||||
fn to_type(self) -> DbType {
|
pub fn to_type(self) -> DbType {
|
||||||
match self {
|
match self {
|
||||||
Self::Number(_) => DbType::Number,
|
Self::Number(_) => DbType::Number,
|
||||||
Self::Indexable(val) =>
|
Self::Indexable(val) =>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue