drasi_core/evaluation/
context.rs

1// Copyright 2024 The Drasi Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use drasi_query_ast::ast;
16use std::collections::BTreeMap;
17use std::sync::Arc;
18
19use crate::evaluation::variable_value::VariableValue;
20use crate::interface::QueryClock;
21use crate::models::{Element, ElementTimestamp};
22use crate::path_solver::solution::SolutionSignature;
23
24pub type QueryVariables = BTreeMap<Box<str>, VariableValue>;
25
26#[derive(Debug, Clone)]
27pub enum SideEffects {
28    Apply,
29    RevertForUpdate,
30    RevertForDelete,
31    Snapshot,
32}
33
34#[derive(Debug, Clone, PartialEq)]
35pub enum QueryPartEvaluationContext {
36    Adding {
37        after: QueryVariables,
38    },
39    Updating {
40        before: QueryVariables,
41        after: QueryVariables,
42    },
43    Removing {
44        before: QueryVariables,
45    },
46    Aggregation {
47        before: Option<QueryVariables>,
48        after: QueryVariables,
49        grouping_keys: Vec<String>,
50        default_before: bool,
51        default_after: bool,
52    },
53    Noop,
54}
55
56impl QueryPartEvaluationContext {}
57
58#[derive(Debug, Clone)]
59pub struct ExpressionEvaluationContext<'a> {
60    variables: &'a QueryVariables,
61    side_effects: SideEffects,
62    output_grouping_key: Option<&'a Vec<ast::Expression>>,
63    input_grouping_hash: u64,
64    clock: Arc<dyn QueryClock>,
65    solution_signature: Option<SolutionSignature>,
66    anchor_element: Option<Arc<Element>>,
67}
68
69impl<'a> ExpressionEvaluationContext<'a> {
70    pub fn new(
71        variables: &'a QueryVariables,
72        clock: Arc<dyn QueryClock>,
73    ) -> ExpressionEvaluationContext<'a> {
74        ExpressionEvaluationContext {
75            variables,
76            side_effects: SideEffects::Apply,
77            output_grouping_key: None,
78            input_grouping_hash: u64::default(),
79            clock,
80            solution_signature: None,
81            anchor_element: None,
82        }
83    }
84
85    pub fn from_before_change(
86        variables: &'a QueryVariables,
87        side_effect_directive: SideEffects,
88        change_context: &ChangeContext,
89    ) -> ExpressionEvaluationContext<'a> {
90        ExpressionEvaluationContext {
91            variables,
92            side_effects: side_effect_directive,
93            output_grouping_key: None,
94            input_grouping_hash: change_context.before_grouping_hash,
95            clock: change_context.before_clock.clone(),
96            solution_signature: Some(change_context.solution_signature),
97            anchor_element: change_context.before_anchor_element.clone(),
98        }
99    }
100
101    pub fn from_after_change(
102        variables: &'a QueryVariables,
103        change_context: &ChangeContext,
104    ) -> ExpressionEvaluationContext<'a> {
105        ExpressionEvaluationContext {
106            variables,
107            side_effects: SideEffects::Apply,
108            output_grouping_key: None,
109            input_grouping_hash: change_context.after_grouping_hash,
110            clock: change_context.after_clock.clone(),
111            solution_signature: Some(change_context.solution_signature),
112            anchor_element: change_context.after_anchor_element.clone(),
113        }
114    }
115
116    pub fn replace_variables(&mut self, new_data: &'a QueryVariables) {
117        self.variables = new_data;
118    }
119
120    pub fn get_variable(&self, name: Arc<str>) -> Option<&VariableValue> {
121        self.variables.get(&name.to_string().into_boxed_str())
122    }
123
124    pub fn clone_variables(&self) -> QueryVariables {
125        self.variables.clone()
126    }
127
128    pub fn set_side_effects(&mut self, directive: SideEffects) {
129        self.side_effects = directive;
130    }
131
132    pub fn get_side_effects(&self) -> &SideEffects {
133        &self.side_effects
134    }
135
136    pub fn set_output_grouping_key(&mut self, grouping_key: &'a Vec<ast::Expression>) {
137        self.output_grouping_key = Some(grouping_key);
138    }
139
140    pub fn get_output_grouping_key(&self) -> Option<&Vec<ast::Expression>> {
141        self.output_grouping_key
142    }
143
144    pub fn get_transaction_time(&self) -> ElementTimestamp {
145        self.clock.get_transaction_time()
146    }
147
148    pub fn get_realtime(&self) -> ElementTimestamp {
149        self.clock.get_realtime()
150    }
151
152    pub fn get_clock(&self) -> Arc<dyn QueryClock> {
153        self.clock.clone()
154    }
155
156    pub fn get_solution_signature(&self) -> Option<SolutionSignature> {
157        self.solution_signature
158    }
159
160    pub fn get_anchor_element(&self) -> Option<Arc<Element>> {
161        self.anchor_element.clone()
162    }
163
164    pub fn get_input_grouping_hash(&self) -> u64 {
165        self.input_grouping_hash
166    }
167}
168
169#[derive(Debug, Clone)]
170pub struct ChangeContext {
171    pub solution_signature: SolutionSignature,
172    pub before_anchor_element: Option<Arc<Element>>,
173    pub after_anchor_element: Option<Arc<Element>>,
174    pub before_clock: Arc<dyn QueryClock>,
175    pub after_clock: Arc<dyn QueryClock>,
176    pub is_future_reprocess: bool,
177    pub before_grouping_hash: u64,
178    pub after_grouping_hash: u64,
179}