Refine CREATE TABLE and CREATE INDEX
This commit is contained in:
parent
d555e8565f
commit
0aa3b28e74
1 changed files with 49 additions and 29 deletions
78
src/main.rs
78
src/main.rs
|
|
@ -90,7 +90,7 @@ impl DbValue {
|
||||||
// table-metadata and data
|
// table-metadata and data
|
||||||
|
|
||||||
type TableName = String;
|
type TableName = String;
|
||||||
type TablePosition = u32;
|
type TablePosition = usize;
|
||||||
|
|
||||||
struct Table {
|
struct Table {
|
||||||
schema: TableSchema,
|
schema: TableSchema,
|
||||||
|
|
@ -117,10 +117,6 @@ struct TableSchema {
|
||||||
types: Vec<DbType>,
|
types: Vec<DbType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
fn column_position(table_meta: TableSchema, column_name: ColumnName) -> Option<ColumnPosition> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
// Use `TablePosition` as index
|
// Use `TablePosition` as index
|
||||||
type Tables = Vec<Table>;
|
type Tables = Vec<Table>;
|
||||||
|
|
||||||
|
|
@ -146,17 +142,35 @@ fn select_columns(row: &Row, columns: &Vec<ColumnPosition>) -> Row {
|
||||||
|
|
||||||
// ==============Interpreter================
|
// ==============Interpreter================
|
||||||
struct State {
|
struct State {
|
||||||
table_positions: HashMap<TableName, TablePosition>,
|
table_name_position_mapping: BiMap<TableName, TablePosition>,
|
||||||
tables: Vec<Table>,
|
tables: Vec<Table>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn table_from_name<'b: 'a, 'a>(&'b self, table_name: TableName) -> Option<&'a Table> {
|
fn table_from_name<'b: 'a, 'a>(&'b self, table_name: &TableName) -> DbResult<&'a Table> {
|
||||||
todo!()
|
match self.table_name_position_mapping.get_by_left(table_name) {
|
||||||
|
Some(table_position) => {
|
||||||
|
let table = &self.tables[*table_position];
|
||||||
|
Ok(table)
|
||||||
|
},
|
||||||
|
None => Err(Error::TableDoesNotExist(table_name.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table_from_name_mut<'b: 'a, 'a>(&'b mut self, table_name: &TableName) -> DbResult<&'a mut Table> {
|
||||||
|
match self.table_name_position_mapping.get_by_left(table_name) {
|
||||||
|
Some(table_position) => {
|
||||||
|
let table = &mut self.tables[*table_position];
|
||||||
|
Ok(table)
|
||||||
|
},
|
||||||
|
None => Err(Error::TableDoesNotExist(table_name.clone()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attach_table(&mut self, table_name: TableName, table: Table) {
|
fn attach_table(&mut self, table_name: TableName, table: Table) {
|
||||||
todo!()
|
let new_table_position: TablePosition = self.tables.len();
|
||||||
|
self.table_name_position_mapping.insert(table_name, new_table_position);
|
||||||
|
self.tables.push(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,13 +179,6 @@ trait SqlConsumer {
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should return a reference to the table
|
|
||||||
// 'tables_life contains 'table_life
|
|
||||||
fn get_table<'tables_life: 'table_life, 'table_life>(tables: &'tables_life Tables, table_name: &TableName) -> &'table_life Table {
|
|
||||||
// let table_position:
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Decide if we want for this to return a response (but then you have to deal with lifetimes,
|
// TODO: Decide if we want for this to return a response (but then you have to deal with lifetimes,
|
||||||
// because you'll be forced to put an iterator/slice into the Response data-structure.
|
// because you'll be forced to put an iterator/slice into the Response data-structure.
|
||||||
// Alternative is to pass a row-consumer to the functionas that knows how to communicate with
|
// Alternative is to pass a row-consumer to the functionas that knows how to communicate with
|
||||||
|
|
@ -182,17 +189,17 @@ fn interpret(table_name: TableName, operation: Operation, state: &mut State, con
|
||||||
|
|
||||||
match operation {
|
match operation {
|
||||||
Select(table_name, column_selection, maybe_condition) => {
|
Select(table_name, column_selection, maybe_condition) => {
|
||||||
let table: &Table = todo!();
|
let table: &Table = state.table_from_name(&table_name)?;
|
||||||
Ok(Response::Selected(table.select_where(column_selection, maybe_condition)?))
|
Ok(Response::Selected(table.select_where(column_selection, maybe_condition)?))
|
||||||
},
|
},
|
||||||
Insert(table_name, values) => {
|
Insert(table_name, values) => {
|
||||||
let table: &mut Table = todo!();
|
let table: &mut Table = state.table_from_name_mut(&table_name)?;
|
||||||
|
|
||||||
let _ = table.insert(values)?;
|
let _ = table.insert(values)?;
|
||||||
Ok(Response::Inserted())
|
Ok(Response::Inserted)
|
||||||
},
|
},
|
||||||
Delete(table_name, maybe_condition) => {
|
Delete(table_name, maybe_condition) => {
|
||||||
let table: &mut Table = todo!();
|
let table: &mut Table = state.table_from_name_mut(&table_name)?;
|
||||||
|
|
||||||
let rows_affected = table.delete_where(maybe_condition)?;
|
let rows_affected = table.delete_where(maybe_condition)?;
|
||||||
Ok(Response::Deleted(rows_affected))
|
Ok(Response::Deleted(rows_affected))
|
||||||
|
|
@ -200,22 +207,28 @@ fn interpret(table_name: TableName, operation: Operation, state: &mut State, con
|
||||||
CreateTable(table_name, table_schema) => {
|
CreateTable(table_name, table_schema) => {
|
||||||
let table = Table::new(table_schema);
|
let table = Table::new(table_schema);
|
||||||
state.attach_table(table_name, table);
|
state.attach_table(table_name, table);
|
||||||
todo!()
|
Ok(Response::TableCreated)
|
||||||
},
|
},
|
||||||
CreateIndex(table_name, column_name) => {
|
CreateIndex(table_name, column_name) => {
|
||||||
let table: &mut Table = todo!();
|
// TODO: This is incomplete. It can happen that an index is created
|
||||||
let column_position: ColumnPosition = todo!();
|
// after the table has some rows for a while.
|
||||||
|
// In such a case the index needs to be built over all those existing rows.
|
||||||
|
let table: &mut Table = state.table_from_name_mut(&table_name)?;
|
||||||
|
let column_position: ColumnPosition = table.schema.column_position_from_column_name(&column_name)?;
|
||||||
|
|
||||||
let index: ColumnIndex = ColumnIndex::new();
|
let index: ColumnIndex = ColumnIndex::new(&table.rows);
|
||||||
table.attach_index(column_position, index);
|
table.attach_index(column_position, index);
|
||||||
todo!()
|
Ok(Response::IndexCreated)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColumnIndex {
|
impl ColumnIndex {
|
||||||
fn new() -> Self {
|
fn new(rows: &Rows) -> Self {
|
||||||
Self { index: BTreeMap::new() }
|
let index = BTreeMap::new();
|
||||||
|
// TODO: Take into account already existing rows
|
||||||
|
todo!();
|
||||||
|
Self { index }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,6 +249,10 @@ impl TableSchema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn column_position_from_column_name(&self, column_name: &ColumnName) -> DbResult<ColumnPosition> {
|
||||||
|
self.get_column(column_name).map(|(_, column_position)| column_position)
|
||||||
|
}
|
||||||
|
|
||||||
fn is_primary(&self, column_position: ColumnPosition) -> bool {
|
fn is_primary(&self, column_position: ColumnPosition) -> bool {
|
||||||
self.primary_key == column_position
|
self.primary_key == column_position
|
||||||
}
|
}
|
||||||
|
|
@ -243,7 +260,7 @@ impl TableSchema {
|
||||||
fn column_positions_from_column_names(&self, column_names: &[ColumnName]) -> DbResult<Vec<ColumnPosition>> {
|
fn column_positions_from_column_names(&self, column_names: &[ColumnName]) -> DbResult<Vec<ColumnPosition>> {
|
||||||
let mut positions: Vec<ColumnPosition> = Vec::with_capacity(column_names.len());
|
let mut positions: Vec<ColumnPosition> = Vec::with_capacity(column_names.len());
|
||||||
for column_name in column_names {
|
for column_name in column_names {
|
||||||
let (_, column_position) = self.get_column(column_name)?;
|
let column_position = self.column_position_from_column_name(column_name)?;
|
||||||
positions.push(column_position)
|
positions.push(column_position)
|
||||||
}
|
}
|
||||||
Ok(positions)
|
Ok(positions)
|
||||||
|
|
@ -512,14 +529,17 @@ impl ColumnIndex {
|
||||||
|
|
||||||
enum Response {
|
enum Response {
|
||||||
Selected(Vec<Row>),
|
Selected(Vec<Row>),
|
||||||
Inserted(),
|
Inserted,
|
||||||
Deleted(usize), // how many were deleted
|
Deleted(usize), // how many were deleted
|
||||||
|
TableCreated,
|
||||||
|
IndexCreated,
|
||||||
}
|
}
|
||||||
|
|
||||||
type DbResult<A> = Result<A, Error>;
|
type DbResult<A> = Result<A, Error>;
|
||||||
|
|
||||||
// #[derive(Debug)]
|
// #[derive(Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
|
TableDoesNotExist(TableName),
|
||||||
ColumnDoesNotExist(TableName, ColumnName),
|
ColumnDoesNotExist(TableName, ColumnName),
|
||||||
ColumnPositionDoesNotExist(TableName, ColumnPosition),
|
ColumnPositionDoesNotExist(TableName, ColumnPosition),
|
||||||
ValueDoesNotMatchExpectedType(TableName, ColumnName, DbType, DbValue),
|
ValueDoesNotMatchExpectedType(TableName, ColumnName, DbType, DbValue),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue