use std::error::Error;
use std::io::ErrorKind;
use crate::lib::ast::other::DescTableQuery;
use crate::lib::errors::predule::ExecuteError;
use crate::lib::executor::predule::{
ExecuteColumn, ExecuteColumnType, ExecuteField, ExecuteResult, ExecuteRow, Executor,
StorageEncoder, TableConfig,
};
impl Executor {
pub async fn desc_table(&self, query: DescTableQuery) -> Result<ExecuteResult, Box<dyn Error>> {
let encoder = StorageEncoder::new();
let database_name = query.table_name.database_name.unwrap();
let table_name = query.table_name.table_name;
let base_path = self.get_base_path();
let mut table_path = base_path;
table_path.push(&database_name);
table_path.push(&table_name);
table_path.push("table.config");
match std::fs::read(&table_path) {
Ok(read_result) => {
let table_info: TableConfig = encoder
.decode(read_result.as_slice())
.ok_or_else(|| ExecuteError::boxed("config decode error"))?;
Ok(ExecuteResult {
columns: (vec![
ExecuteColumn {
name: "Field".into(),
data_type: ExecuteColumnType::String,
},
ExecuteColumn {
name: "Type".into(),
data_type: ExecuteColumnType::String,
},
ExecuteColumn {
name: "Null".into(),
data_type: ExecuteColumnType::String,
},
ExecuteColumn {
name: "Default".into(),
data_type: ExecuteColumnType::String,
},
ExecuteColumn {
name: "Comment".into(),
data_type: ExecuteColumnType::String,
},
]),
rows: table_info
.columns
.iter()
.map(|e| ExecuteRow {
fields: vec![
ExecuteField::String(e.name.to_owned()),
ExecuteField::String(e.data_type.to_owned().into()),
ExecuteField::String(if e.not_null { "NO" } else { "YES" }.into()),
ExecuteField::String(format!("{:?}", e.default)), ExecuteField::String(e.comment.to_owned()),
],
})
.collect(),
})
}
Err(error) => match error.kind() {
ErrorKind::NotFound => Err(ExecuteError::boxed(format!(
"table '{}' not exists",
table_name
))),
_ => Err(ExecuteError::boxed("database listup failed")),
},
}
}
}