use crate::executor::expression::evaluation_context::graph_storage::GraphStorageRef;
use crate::executor::expression::functions::global_registry_ref;
use crate::storage::StorageReader;
use linkrs_core::Value;
use parking_lot::RwLock;
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Debug)]
pub struct DefaultExpressionContext {
variables: HashMap<String, Value>,
parameters: Option<Arc<HashMap<String, Value>>>,
session_variables: Option<Arc<HashMap<String, Value>>>,
storage: Option<Arc<RwLock<dyn StorageReader>>>,
space: String,
sequence_manager: Option<Arc<linkrs_core::metadata::SequenceManager>>,
}
impl DefaultExpressionContext {
pub fn new() -> Self {
Self {
variables: HashMap::new(),
parameters: None,
session_variables: None,
storage: None,
space: String::new(),
sequence_manager: None,
}
}
pub fn with_storage(storage: Arc<RwLock<dyn StorageReader>>, space: String) -> Self {
Self {
variables: HashMap::new(),
parameters: None,
session_variables: None,
storage: Some(storage),
space,
sequence_manager: None,
}
}
pub fn with_parameters(mut self, parameters: Arc<HashMap<String, Value>>) -> Self {
self.parameters = Some(parameters);
self
}
pub fn with_session_variables(mut self, variables: Arc<HashMap<String, Value>>) -> Self {
self.session_variables = Some(variables);
self
}
pub fn add_variable(mut self, name: String, value: Value) -> Self {
self.variables.insert(name, value);
self
}
pub fn with_variables<I>(mut self, variables: I) -> Self
where
I: IntoIterator<Item = (String, Value)>,
{
for (name, value) in variables {
self.variables.insert(name, value);
}
self
}
pub fn from_execution_context(ctx: &crate::executor::base::ExecutionContext) -> Self {
Self {
variables: ctx.variables.read().clone(),
parameters: None,
session_variables: None,
storage: None,
space: String::new(),
sequence_manager: ctx.sequence_manager.clone(),
}
}
pub fn sync_to_execution_context(self, ctx: &crate::executor::base::ExecutionContext) {
for (name, value) in self.variables {
ctx.set_variable(name, value);
}
}
pub fn get_all_variables(&self) -> &HashMap<String, Value> {
&self.variables
}
}
impl Default for DefaultExpressionContext {
fn default() -> Self {
Self::new()
}
}
impl crate::executor::expression::evaluator::traits::ExpressionContext
for DefaultExpressionContext
{
fn get_variable(&self, name: &str) -> Option<Value> {
self.variables.get(name).cloned()
}
fn set_variable(&mut self, name: String, value: Value) {
self.variables.insert(name, value);
}
fn get_parameter(&self, name: &str) -> Option<Value> {
self.parameters
.as_ref()
.and_then(|params| params.get(name).cloned())
}
fn get_session_variable(
&self,
name: &str,
) -> Result<Value, crate::executor::expression::ExpressionError> {
self.session_variables
.as_ref()
.and_then(|vars| vars.get(name).cloned())
.ok_or_else(|| {
crate::executor::expression::ExpressionError::type_error(format!(
"Session variable `{}` is not defined",
name
))
})
}
fn get_function(
&self,
name: &str,
) -> Option<crate::executor::expression::functions::OwnedFunctionRef> {
let registry = global_registry_ref();
registry
.get_builtin(name)
.map(|f| crate::executor::expression::functions::OwnedFunctionRef::Builtin(f.clone()))
.or_else(|| {
registry.get_custom(name).map(|f| {
crate::executor::expression::functions::OwnedFunctionRef::Custom(f.clone())
})
})
}
fn get_graph_storage(&self) -> Option<GraphStorageRef> {
self.storage
.as_ref()
.map(|s| GraphStorageRef::new(s.clone(), self.space.clone()))
}
fn get_sequence_manager(&self) -> Option<Arc<linkrs_core::metadata::SequenceManager>> {
self.sequence_manager.clone()
}
}