sql_cli/data/
evaluation_context.rs1use regex::Regex;
2use std::collections::HashMap;
3use std::sync::Arc;
4
5#[derive(Debug, Clone)]
8pub struct EvaluationContext {
9 regex_cache: HashMap<String, Arc<Regex>>,
12
13 case_insensitive: bool,
15
16 regex_compilations: usize,
18 regex_cache_hits: usize,
19}
20
21impl EvaluationContext {
22 pub fn new(case_insensitive: bool) -> Self {
23 Self {
24 regex_cache: HashMap::new(),
25 case_insensitive,
26 regex_compilations: 0,
27 regex_cache_hits: 0,
28 }
29 }
30
31 pub fn get_or_compile_like_regex(&mut self, like_pattern: &str) -> Result<Arc<Regex>, String> {
33 if let Some(regex) = self.regex_cache.get(like_pattern) {
35 self.regex_cache_hits += 1;
36 return Ok(Arc::clone(regex));
37 }
38
39 let regex_pattern = like_pattern.replace('%', ".*").replace('_', ".");
41
42 let regex = regex::RegexBuilder::new(&format!("^{}$", regex_pattern))
44 .case_insensitive(self.case_insensitive)
45 .build()
46 .map_err(|e| format!("Invalid LIKE pattern '{}': {}", like_pattern, e))?;
47
48 let regex_arc = Arc::new(regex);
49 self.regex_cache
50 .insert(like_pattern.to_string(), Arc::clone(®ex_arc));
51 self.regex_compilations += 1;
52
53 Ok(regex_arc)
54 }
55
56 pub fn get_stats(&self) -> (usize, usize) {
57 (self.regex_compilations, self.regex_cache_hits)
58 }
59
60 pub fn is_case_insensitive(&self) -> bool {
61 self.case_insensitive
62 }
63}
64
65impl Default for EvaluationContext {
66 fn default() -> Self {
67 Self::new(false)
68 }
69}