use std::{error::Error, fmt::Debug};
use async_trait::async_trait;
use hamelin_lib::catalog::{Catalog, Column};
use hamelin_lib::err::ContextualTranslationErrors;
use hamelin_lib::tree::ast::identifier::Identifier;
use crate::results::ResultSet;
pub use hamelin_lib::TimeRange;
#[derive(Debug)]
pub struct CompiledQuery {
pub display: String,
pub columns: Vec<Column>,
}
#[async_trait]
pub trait Executor: Debug + Send + Sync {
async fn translate(
&self,
hamelin: &str,
time_range: Option<&str>,
) -> Result<CompiledQuery, ExecutorError>;
async fn ir(
&self,
hamelin: &str,
time_range: Option<&str>,
) -> Result<CompiledQuery, ExecutorError>;
async fn explain(
&self,
hamelin: &str,
time_range: Option<&str>,
) -> Result<String, ExecutorError>;
async fn execute_query(
&self,
hamelin: &str,
time_range: Option<&str>,
) -> Result<ResultSet, ExecutorError>;
async fn execute_dml(
&self,
hamelin: &str,
time_range: Option<&str>,
) -> Result<usize, ExecutorError>;
async fn create_dataset(
&self,
dataset: Identifier,
columns: Vec<Column>,
) -> Result<(), ExecutorError>;
async fn resolve_datasets(
&self,
datasets: &[Identifier],
) -> Result<Vec<Vec<Column>>, ExecutorError>;
async fn reflect_catalog(&self) -> Result<Catalog, ExecutorError>;
}
#[derive(Debug, thiserror::Error)]
pub enum ExecutorError {
#[error("Server error: {0}")]
ServerError(Box<dyn Error + Send + Sync + 'static>),
#[error("Query error: {0}")]
QueryError(Box<dyn Error + Send + Sync + 'static>),
#[error("Connection error: {0}")]
ConnectionError(Box<dyn Error + Send + Sync + 'static>),
#[error("Configuration error: {0}")]
ConfigurationError(Box<dyn Error + Send + Sync + 'static>),
#[error("Unexpected result set: {0}")]
UnexpectedResultSet(Box<dyn Error + Send + Sync + 'static>),
#[error("Compile error: {0}")]
CompileError(ContextualTranslationErrors),
}
impl From<ContextualTranslationErrors> for ExecutorError {
fn from(value: ContextualTranslationErrors) -> Self {
ExecutorError::CompileError(value)
}
}