diff --git a/akd/crates/akd_storage/src/lib.rs b/akd/crates/akd_storage/src/lib.rs index e964aeb4d3..fa23c7505a 100644 --- a/akd/crates/akd_storage/src/lib.rs +++ b/akd/crates/akd_storage/src/lib.rs @@ -1,2 +1,5 @@ mod migrations; -mod ms_sql; +mod sql_params; +mod ms_sql_storable; +pub mod ms_sql; +mod temp_table; diff --git a/akd/crates/akd_storage/src/migrations.rs b/akd/crates/akd_storage/src/migrations.rs index 0e63522c5a..bb80dc1315 100644 --- a/akd/crates/akd_storage/src/migrations.rs +++ b/akd/crates/akd_storage/src/migrations.rs @@ -4,6 +4,5 @@ use ms_database::{load_migrations, Migration}; pub(crate) const TABLE_AZKS: &str = "akd_azks"; pub(crate) const TABLE_HISTORY_TREE_NODES: &str = "akd_history_tree_nodes"; pub(crate) const TABLE_VALUES: &str = "akd_values"; -pub(crate) const TEMP_IDS_TABLE: &str = "#akd_temp_ids"; pub(crate) const MIGRATIONS: &[Migration] = load_migrations!("migrations/ms_sql"); diff --git a/akd/crates/akd_storage/src/temp_table.rs b/akd/crates/akd_storage/src/temp_table.rs new file mode 100644 index 0000000000..a06da767b9 --- /dev/null +++ b/akd/crates/akd_storage/src/temp_table.rs @@ -0,0 +1,142 @@ +use std::str::FromStr; + +use akd::storage::{types::StorageType, Storable}; + +pub(crate) enum TempTable { + Ids(StorageType), + Azks, + HistoryTreeNodes, + Values, +} + +impl TempTable { + pub fn for_ids_for(storage_type: &StorageType) -> Self { + TempTable::Ids(storage_type.clone()) + } + + pub fn for_ids() -> Self { + TempTable::Ids(St::data_type()) + } + + pub fn drop(&self) -> String { + format!("DROP TABLE IF EXISTS {}", self.to_string()) + } + + pub fn can_create(&self) -> bool { + match self { + TempTable::Ids(storage_type) => match storage_type { + StorageType::Azks => false, + _ => true, + }, + _ => true, + } + } + + pub fn create(&self) -> String { + match self { + TempTable::Azks => format!( + r#" + CREATE TABLE {} ( + [key] SMALLINT NOT NULL PRIMARY KEY, + [epoch] BIGINT NOT NULL, + [num_nodes] BIGINT NOT NULL + ); + "#, + TEMP_AZKS_TABLE + ), + TempTable::HistoryTreeNodes => format!( + r#" + CREATE TABLE {} ( + label_len INT NOT NULL CHECK (label_len >= 0), + label_val VARBINARY(32) NOT NULL, + last_epoch BIGINT NOT NULL CHECK (last_epoch >= 0), + least_descendant_ep BIGINT NOT NULL CHECK (least_descendant_ep >= 0), + parent_label_len INT NOT NULL CHECK (parent_label_len >= 0), + parent_label_val VARBINARY(32) NOT NULL, + node_type SMALLINT NOT NULL CHECK (node_type >= 0), + left_child_len INT NULL CHECK (left_child_len IS NULL OR left_child_len >= 0), + left_child_label_val VARBINARY(32) NULL, + right_child_len INT NULL CHECK (right_child_len IS NULL OR right_child_len >= 0), + right_child_label_val VARBINARY(32) NULL, + [hash] VARBINARY(32) NOT NULL, + p_last_epoch BIGINT NULL CHECK (p_last_epoch IS NULL OR p_last_epoch >= 0), + p_least_descendant_ep BIGINT NULL CHECK (p_least_descendant_ep IS NULL OR p_least_descendant_ep >= 0), + p_parent_label_len INT NULL CHECK (p_parent_label_len IS NULL OR p_parent_label_len >= 0), + p_parent_label_val VARBINARY(32) NULL, + p_node_type SMALLINT NULL CHECK (p_node_type IS NULL OR p_node_type >= 0), + p_left_child_len INT NULL CHECK (p_left_child_len IS NULL OR p_left_child_len >= 0), + p_left_child_label_val VARBINARY(32) NULL, + p_right_child_len INT NULL CHECK (p_right_child_len IS NULL OR p_right_child_len >= 0), + p_right_child_label_val VARBINARY(32) NULL, + p_hash VARBINARY(32) NULL, + PRIMARY KEY (label_len, label_val) + ); + "#, + TEMP_AZKS_TABLE + ), + TempTable::Values => format!( + r#" + CREATE TABLE {} ( + raw_label VARBINARY(256) NOT NULL, + epoch BIGINT NOT NULL CHECK (epoch >= 0), + [version] BIGINT NOT NULL CHECK ([version] >= 0), + node_label_val VARBINARY(32) NOT NULL, + node_label_len INT NOT NULL CHECK (node_label_len >= 0), + [data] VARBINARY(2000) NULL, + PRIMARY KEY (raw_label, epoch) + ); + "#, + TEMP_VALUES_TABLE + ), + TempTable::Ids(storage_type) => match storage_type { + StorageType::Azks => panic!("TempTable::Ids should not be created for Azks"), + StorageType::TreeNode => format!( + r#" + CREATE TABLE {} ( + label_len INT NOT NULL, + label_val VARBINARY(32) NOT NULL, + PRIMARY KEY (label_len, label_val) + ); + "#, + TEMP_IDS_TABLE + ), + StorageType::ValueState => format!( + r#" + CREATE TABLE {} ( + raw_label VARBINARY(256) NOT NULL, + epoch BIGINT NOT NULL, + PRIMARY KEY (raw_label, epoch) + ); + "#, + TEMP_IDS_TABLE + ), + } + } + } +} + +impl ToString for TempTable { + fn to_string(&self) -> String { + match self { + TempTable::Ids(_) => TEMP_IDS_TABLE.to_string(), + TempTable::Azks => TEMP_AZKS_TABLE.to_string(), + TempTable::HistoryTreeNodes => TEMP_HISTORY_TREE_NODES_TABLE.to_string(), + TempTable::Values => TEMP_VALUES_TABLE.to_string(), + } + } +} + +impl From for TempTable { + fn from(storage_type: StorageType) -> Self { + match storage_type { + StorageType::Azks => TempTable::Azks, + StorageType::TreeNode => TempTable::HistoryTreeNodes, + StorageType::ValueState => TempTable::Values, + } + } +} + +pub(crate) const TEMP_IDS_TABLE: &str = "#akd_temp_ids"; +pub(crate) const TEMP_AZKS_TABLE: &str = "#akd_temp_azks"; +pub(crate) const TEMP_HISTORY_TREE_NODES_TABLE: &str = "#akd_temp_history_tree_nodes"; +pub(crate) const TEMP_VALUES_TABLE: &str = "#akd_temp_values";