pub struct Table {
pub tb_name: String,
pub columns: Vec<Column>,
pub rows: Arc<Mutex<HashMap<String, Row>>>,
pub secondary_indexes: Vec<SecondaryIndex>,
pub last_rowid: i64,
pub primary_key: String,
}Expand description
The schema for each SQL Table is represented in memory by following structure.
rows is Arc<Mutex<...>> rather than Rc<RefCell<...>> so Table
(and by extension Database) is Send + Sync — the Tauri desktop
app holds the engine in shared state behind a Mutex<Database>, and
Tauri’s state container requires its contents to be thread-safe.
Fields§
§tb_name: StringName of the table
columns: Vec<Column>Schema for each column, in declaration order.
rows: Arc<Mutex<HashMap<String, Row>>>Per-column row storage, keyed by column name. Every column’s
Row::T(BTreeMap) is keyed by rowid, so all columns share the same
keyset after each write.
secondary_indexes: Vec<SecondaryIndex>Secondary indexes on this table (Phase 3e). One auto-created entry
per UNIQUE or PRIMARY KEY column; explicit CREATE INDEX statements
add more. Looking up an index: iterate by column name, or by index
name via Table::index_by_name.
last_rowid: i64ROWID of most recent insert.
primary_key: StringPRIMARY KEY column name, or “-1” if the table has no PRIMARY KEY.
Implementations§
Source§impl Table
impl Table
pub fn new(create_query: CreateQuery) -> Self
Sourcepub fn deep_clone(&self) -> Self
pub fn deep_clone(&self) -> Self
Deep-clones a Table for transaction snapshots (Phase 4f).
The normal Clone derive would shallow-clone the Arc<Mutex<_>>
wrapping our row storage, leaving both copies sharing the same
inner map — mutating the snapshot would corrupt the live table
and vice versa. Instead we lock, clone the inner HashMap, and
wrap it in a fresh Arc<Mutex<_>>. Columns and indexes derive
Clone directly (all their fields are plain data).
Sourcepub fn index_for_column(&self, column: &str) -> Option<&SecondaryIndex>
pub fn index_for_column(&self, column: &str) -> Option<&SecondaryIndex>
Finds an auto- or explicit-index entry for a given column. Returns
None if the column isn’t indexed.
Sourcepub fn index_by_name(&self, name: &str) -> Option<&SecondaryIndex>
pub fn index_by_name(&self, name: &str) -> Option<&SecondaryIndex>
Finds a secondary index by its own name (e.g., sqlrite_autoindex_users_email
or a user-provided CREATE INDEX name). Used by Phase 3e.2 to look up
explicit indexes when DROP INDEX lands.
Sourcepub fn contains_column(&self, column: String) -> bool
pub fn contains_column(&self, column: String) -> bool
Returns a bool informing if a Column with a specific name exists or not
Sourcepub fn column_names(&self) -> Vec<String>
pub fn column_names(&self) -> Vec<String>
Returns the list of column names in declaration order.
Sourcepub fn rowids(&self) -> Vec<i64>
pub fn rowids(&self) -> Vec<i64>
Returns all rowids currently stored in the table, in ascending order. Every column’s BTreeMap has the same keyset, so we just read from the first column.
Sourcepub fn get_value(&self, column: &str, rowid: i64) -> Option<Value>
pub fn get_value(&self, column: &str, rowid: i64) -> Option<Value>
Reads a single cell at (column, rowid).
Sourcepub fn delete_row(&mut self, rowid: i64)
pub fn delete_row(&mut self, rowid: i64)
Removes the row identified by rowid from every column’s storage and
from every secondary index entry.
Sourcepub fn restore_row(
&mut self,
rowid: i64,
values: Vec<Option<Value>>,
) -> Result<()>
pub fn restore_row( &mut self, rowid: i64, values: Vec<Option<Value>>, ) -> Result<()>
Replays a single row at rowid when loading a table from disk. Takes
one typed value per column (in declaration order); None means the
stored cell carried a NULL for that column. Unlike insert_row this
trusts the on-disk state and does not re-check UNIQUE — we’re
rebuilding a state that was already consistent when it was saved.
Sourcepub fn extract_row(&self, rowid: i64) -> Vec<Option<Value>>
pub fn extract_row(&self, rowid: i64) -> Vec<Option<Value>>
Extracts a row as an ordered Vec<Option<Value>> matching the column
declaration order. Returns None entries for columns that hold NULL.
Used by save_database to turn a table’s in-memory state into cells.
Sourcepub fn set_value(
&mut self,
column: &str,
rowid: i64,
new_val: Value,
) -> Result<()>
pub fn set_value( &mut self, column: &str, rowid: i64, new_val: Value, ) -> Result<()>
Overwrites the cell at (column, rowid) with new_val. Enforces the
column’s datatype and UNIQUE constraint, and updates any secondary
index.
Returns Err if the column doesn’t exist, the value type is incompatible,
or writing would violate UNIQUE.
Sourcepub fn get_column(&mut self, column_name: String) -> Result<&Column>
pub fn get_column(&mut self, column_name: String) -> Result<&Column>
Returns an immutable reference of sql::db::table::Column if the table contains a
column with the specified key as a column name.
Sourcepub fn validate_unique_constraint(
&mut self,
cols: &Vec<String>,
values: &Vec<String>,
) -> Result<()>
pub fn validate_unique_constraint( &mut self, cols: &Vec<String>, values: &Vec<String>, ) -> Result<()>
Validates if columns and values being inserted violate the UNIQUE constraint. PRIMARY KEY columns are automatically UNIQUE. Uses the corresponding secondary index when one exists (O(log N) lookup); falls back to a linear scan for indexable-but-not-indexed situations (e.g. a Real UNIQUE column — Real isn’t in the auto-indexed set).
Sourcepub fn insert_row(
&mut self,
cols: &Vec<String>,
values: &Vec<String>,
) -> Result<()>
pub fn insert_row( &mut self, cols: &Vec<String>, values: &Vec<String>, ) -> Result<()>
Inserts all VALUES in its approprieta COLUMNS, using the ROWID an embedded INDEX on all ROWS
Every Table keeps track of the last_rowid in order to facilitate what the next one would be.
One limitation of this data structure is that we can only have one write transaction at a time, otherwise
we could have a race condition on the last_rowid.
Since we are loosely modeling after SQLite, this is also a limitation of SQLite (allowing only one write transcation at a time), So we are good. :)
Returns Err (leaving the table unchanged) when the user supplies an
incompatibly-typed value — no more panics on bad input.
Sourcepub fn print_table_schema(&self) -> Result<usize>
pub fn print_table_schema(&self) -> Result<usize>
Print the table schema to standard output in a pretty formatted way.
§Example
let table = Table::new(payload);
table.print_table_schema();
Prints to standard output:
+-------------+-----------+-------------+--------+----------+
| Column Name | Data Type | PRIMARY KEY | UNIQUE | NOT NULL |
+-------------+-----------+-------------+--------+----------+
| id | Integer | true | true | true |
+-------------+-----------+-------------+--------+----------+
| name | Text | false | true | false |
+-------------+-----------+-------------+--------+----------+
| email | Text | false | false | false |
+-------------+-----------+-------------+--------+----------+Sourcepub fn print_table_data(&self)
pub fn print_table_data(&self)
Print the table data to standard output in a pretty formatted way.
§Example
let db_table = db.get_table_mut(table_name.to_string()).unwrap();
db_table.print_table_data();
Prints to standard output:
+----+---------+------------------------+
| id | name | email |
+----+---------+------------------------+
| 1 | "Jack" | "jack@mail.com" |
+----+---------+------------------------+
| 10 | "Bob" | "bob@main.com" |
+----+---------+------------------------+
| 11 | "Bill" | "bill@main.com" |
+----+---------+------------------------+