use std::io::ErrorKind;
use crate::ast::ddl::create_table::CreateTableQuery;
use crate::errors::predule::ExecuteError;
use crate::errors::RRDBError;
use crate::executor::config::table::TableConfig;
use crate::executor::encoder::storage::StorageEncoder;
use crate::executor::predule::{ExecuteResult, Executor};
use crate::executor::result::{ExecuteColumn, ExecuteColumnType, ExecuteField, ExecuteRow};
impl Executor {
pub async fn create_table(&self, query: CreateTableQuery) -> Result<ExecuteResult, RRDBError> {
let encoder = StorageEncoder::new();
let database_name = query.table.clone().unwrap().database_name.unwrap();
let table_name = query.table.clone().unwrap().table_name;
let base_path = self.get_data_directory();
let database_path = base_path.clone().join(&database_name);
let table_path = database_path.clone().join("tables").join(&table_name);
if let Err(error) = tokio::fs::create_dir(&table_path).await {
match error.kind() {
ErrorKind::AlreadyExists => return Err(ExecuteError::wrap("already exists table")),
_ => {
return Err(ExecuteError::wrap("table create failed"));
}
}
}
let config_path = table_path.clone().join("table.config");
let table_info: TableConfig = query.into();
if let Err(error) = tokio::fs::write(&config_path, encoder.encode(table_info)).await {
return Err(ExecuteError::wrap(error.to_string()));
}
let rows_path = table_path.clone().join("rows");
if let Err(error) = tokio::fs::create_dir(&rows_path).await {
return Err(ExecuteError::wrap(error.to_string()));
}
let index_path = table_path.clone().join("index");
if let Err(error) = tokio::fs::create_dir(&index_path).await {
return Err(ExecuteError::wrap(error.to_string()));
}
Ok(ExecuteResult {
columns: (vec![ExecuteColumn {
name: "desc".into(),
data_type: ExecuteColumnType::String,
}]),
rows: (vec![ExecuteRow {
fields: vec![ExecuteField::String(format!(
"table created: {}",
table_name
))],
}]),
})
}
}