use std::io::ErrorKind;
use std::path::PathBuf;
use futures::future::join_all;
use crate::ast::types::TableName;
use crate::errors::predule::ExecuteError;
use crate::errors::RRDBError;
use crate::executor::config::row::TableDataRow;
use crate::executor::encoder::storage::StorageEncoder;
use crate::executor::predule::Executor;
impl Executor {
pub async fn full_scan(
&self,
table_name: TableName,
) -> Result<Vec<(PathBuf, TableDataRow)>, RRDBError> {
let encoder = StorageEncoder::new();
let database_name = table_name.database_name.unwrap();
let table_name = table_name.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);
let rows_path = table_path.clone().join("rows");
match std::fs::read_dir(&rows_path) {
Ok(read_dir_result) => {
let futures = read_dir_result.map(|e| async {
match e {
Ok(entry) => match entry.file_type() {
Ok(file_type) => {
if file_type.is_file() {
let path = entry.path();
match tokio::fs::read(&path).await {
Ok(result) => {
match encoder.decode::<TableDataRow>(result.as_slice())
{
Some(decoded) => Ok((path.to_path_buf(), decoded)),
None => Err(ExecuteError::wrap(format!(
"full scan failed {:?}",
path
))),
}
}
Err(error) => Err(ExecuteError::wrap(format!(
"full scan failed {}",
error
))),
}
} else {
Err(ExecuteError::wrap("full scan failed"))
}
}
Err(error) => {
Err(ExecuteError::wrap(format!("full scan failed {}", error)))
}
},
Err(error) => Err(ExecuteError::wrap(format!("full scan failed {}", error))),
}
});
let rows = join_all(futures)
.await
.into_iter()
.collect::<Result<Vec<_>, _>>();
match rows {
Ok(rows) => Ok(rows),
Err(error) => Err(ExecuteError::wrap(error.to_string())),
}
}
Err(error) => match error.kind() {
ErrorKind::NotFound => Err(ExecuteError::wrap("base path not exists (3)")),
_ => Err(ExecuteError::wrap("full scan failed")),
},
}
}
pub async fn index_scan(&self, _table_name: TableName) {}
}