use rustc_hash::FxHashMap;
use crate::core::{IsolationLevel, Result, Schema, SchemaColumn};
use crate::storage::expression::Expression;
use crate::storage::traits::{QueryResult, Table};
pub trait Transaction: Send {
fn begin(&mut self) -> Result<()>;
fn commit(&mut self) -> Result<()>;
fn rollback(&mut self) -> Result<()>;
fn create_savepoint(&mut self, name: &str) -> Result<()>;
fn release_savepoint(&mut self, name: &str) -> Result<()>;
fn rollback_to_savepoint(&mut self, name: &str) -> Result<()>;
fn get_savepoint_timestamp(&self, name: &str) -> Option<i64>;
fn id(&self) -> i64;
fn set_isolation_level(&mut self, level: IsolationLevel) -> Result<()>;
fn create_table(&mut self, name: &str, schema: Schema) -> Result<Box<dyn Table>>;
fn drop_table(&mut self, name: &str) -> Result<()>;
fn get_table(&self, name: &str) -> Result<Box<dyn Table>>;
fn list_tables(&self) -> Result<Vec<String>>;
fn rename_table(&mut self, old_name: &str, new_name: &str) -> Result<()>;
fn create_table_index(
&mut self,
table_name: &str,
index_name: &str,
columns: &[String],
is_unique: bool,
) -> Result<()>;
fn drop_table_index(&mut self, table_name: &str, index_name: &str) -> Result<()>;
fn create_table_btree_index(
&mut self,
table_name: &str,
column_name: &str,
is_unique: bool,
custom_name: Option<&str>,
) -> Result<()>;
fn drop_table_btree_index(&mut self, table_name: &str, column_name: &str) -> Result<()>;
fn add_table_column(&mut self, table_name: &str, column: SchemaColumn) -> Result<()>;
fn drop_table_column(&mut self, table_name: &str, column_name: &str) -> Result<()>;
fn rename_table_column(
&mut self,
table_name: &str,
old_name: &str,
new_name: &str,
) -> Result<()>;
fn modify_table_column(&mut self, table_name: &str, column: SchemaColumn) -> Result<()>;
fn select(
&self,
table_name: &str,
columns_to_fetch: &[String],
expr: Option<&dyn Expression>,
original_columns: Option<&[String]>,
) -> Result<Box<dyn QueryResult>>;
fn select_with_aliases(
&self,
table_name: &str,
columns_to_fetch: &[String],
expr: Option<&dyn Expression>,
aliases: &FxHashMap<String, String>,
original_columns: Option<&[String]>,
) -> Result<Box<dyn QueryResult>>;
fn select_as_of(
&self,
table_name: &str,
columns_to_fetch: &[String],
expr: Option<&dyn Expression>,
temporal_type: &str,
temporal_value: i64,
original_columns: Option<&[String]>,
) -> Result<Box<dyn QueryResult>>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TemporalType {
Transaction,
Timestamp,
}
impl std::str::FromStr for TemporalType {
type Err = ();
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s.to_uppercase().as_str() {
"TRANSACTION" => Ok(Self::Transaction),
"TIMESTAMP" => Ok(Self::Timestamp),
_ => Err(()),
}
}
}
impl TemporalType {
pub fn parse(s: &str) -> Option<Self> {
s.parse().ok()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_temporal_type_from_str() {
assert_eq!(
TemporalType::parse("TRANSACTION"),
Some(TemporalType::Transaction)
);
assert_eq!(
TemporalType::parse("transaction"),
Some(TemporalType::Transaction)
);
assert_eq!(
TemporalType::parse("TIMESTAMP"),
Some(TemporalType::Timestamp)
);
assert_eq!(
TemporalType::parse("timestamp"),
Some(TemporalType::Timestamp)
);
assert_eq!(TemporalType::parse("INVALID"), None);
}
fn _assert_object_safe(_: &dyn Transaction) {}
}