uqa_sql/semantics/
parameters.rs1use std::collections::BTreeMap;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum ParameterAssignment {
13 Session,
14 Local,
15 Save,
16}
17
18#[derive(Clone, Copy, Debug)]
19pub struct ParameterScope(usize);
20
21#[derive(Clone)]
23pub struct ParameterScopes<T> {
24 transaction: BTreeMap<String, T>,
25 functions: Vec<BTreeMap<String, T>>,
26}
27
28impl<T> Default for ParameterScopes<T> {
29 fn default() -> Self {
30 Self {
31 transaction: BTreeMap::new(),
32 functions: Vec::new(),
33 }
34 }
35}
36
37impl<T> ParameterScopes<T> {
38 pub fn session_assignment(&mut self, name: &str) {
40 self.transaction.remove(name);
41 for saved in &mut self.functions {
42 saved.remove(name);
43 }
44 }
45
46 pub fn enter_function(&mut self) -> ParameterScope {
47 self.functions.push(BTreeMap::new());
48 ParameterScope(self.functions.len())
49 }
50
51 pub fn leave_function(&mut self, scope: ParameterScope) -> BTreeMap<String, T> {
52 assert_eq!(scope.0, self.functions.len(), "parameter scope order");
53 self.functions.pop().expect("active parameter scope")
54 }
55
56 pub fn assigned(
58 &mut self,
59 name: String,
60 previous: T,
61 action: ParameterAssignment,
62 in_transaction: bool,
63 ) -> Option<T> {
64 match action {
65 ParameterAssignment::Session => {
66 self.session_assignment(&name);
67 }
68 ParameterAssignment::Local => {
69 if self.functions.iter().any(|saved| saved.contains_key(&name)) {
70 return None;
71 }
72 if !in_transaction {
73 return Some(previous);
74 }
75 self.transaction.entry(name).or_insert(previous);
76 }
77 ParameterAssignment::Save => {
78 self.functions
79 .last_mut()
80 .expect("function configuration requires a parameter scope")
81 .entry(name)
82 .or_insert(previous);
83 }
84 }
85 None
86 }
87
88 pub fn finish_transaction(&mut self) -> BTreeMap<String, T> {
89 std::mem::take(&mut self.transaction)
90 }
91
92 pub fn reset_all(&mut self) {
94 fn authorization(name: &str) -> bool {
95 matches!(name, "role" | "session_authorization")
96 }
97 self.transaction.retain(|name, _| authorization(name));
98 for saved in &mut self.functions {
99 saved.retain(|name, _| authorization(name));
100 }
101 }
102}
103
104#[cfg(test)]
105mod tests;