gluesql_core/executor/context/
row_context.rs1use {
2 crate::data::{Row, Value},
3 std::{borrow::Cow, fmt::Debug, rc::Rc},
4};
5
6#[derive(Debug)]
7pub enum RowContext<'a> {
8 Data {
9 table_alias: &'a str,
10 row: Cow<'a, Row>,
11 next: Option<Rc<RowContext<'a>>>,
12 },
13 RefVecData {
14 columns: &'a [String],
15 values: &'a [Value],
16 },
17 Bridge {
18 left: Rc<RowContext<'a>>,
19 right: Rc<RowContext<'a>>,
20 },
21}
22
23impl<'a> RowContext<'a> {
24 pub fn new(table_alias: &'a str, row: Cow<'a, Row>, next: Option<Rc<RowContext<'a>>>) -> Self {
25 Self::Data {
26 table_alias,
27 row,
28 next,
29 }
30 }
31
32 pub fn concat(left: Rc<RowContext<'a>>, right: Rc<RowContext<'a>>) -> Self {
33 Self::Bridge { left, right }
34 }
35
36 pub fn get_value(&'a self, target: &str) -> Option<&'a Value> {
37 match self {
38 Self::Data {
39 row, next: None, ..
40 } => row.get_value(target),
41 Self::Data {
42 row,
43 next: Some(next),
44 ..
45 } => row.get_value(target).or_else(|| next.get_value(target)),
46 Self::Bridge { left, right } => {
47 left.get_value(target).or_else(|| right.get_value(target))
48 }
49 Self::RefVecData { columns, values } => columns
50 .iter()
51 .position(|column| column == target)
52 .and_then(|index| values.get(index)),
53 }
54 }
55
56 pub fn get_alias_value(&'a self, target_table_alias: &str, target: &str) -> Option<&'a Value> {
57 match self {
58 Self::Data {
59 table_alias,
60 row,
61 next,
62 } if *table_alias == target_table_alias => {
63 let value = row.get_value(target);
64
65 if value.is_some() {
66 value
67 } else {
68 next.as_ref()
69 .and_then(|context| context.get_alias_value(target_table_alias, target))
70 }
71 }
72 Self::Data {
73 next: Some(next), ..
74 } => next.get_alias_value(target_table_alias, target),
75 Self::Bridge { left, right } => left
76 .get_alias_value(target_table_alias, target)
77 .or_else(|| right.get_alias_value(target_table_alias, target)),
78 _ => None,
79 }
80 }
81
82 pub fn get_alias_entries(&self, alias: &str) -> Option<Vec<(&String, Value)>> {
83 match self {
84 Self::Data {
85 table_alias, row, ..
86 } if *table_alias == alias => Some(row.iter().map(|(k, v)| (k, v.clone())).collect()),
87 Self::Data {
88 next: Some(next), ..
89 } => next.get_alias_entries(alias),
90 Self::Bridge { left, right } => left
91 .get_alias_entries(alias)
92 .or_else(|| right.get_alias_entries(alias)),
93 _ => None,
94 }
95 }
96
97 pub fn get_all_entries(&self) -> Vec<(&String, Value)> {
98 match self {
99 Self::Data {
100 row, next: None, ..
101 } => row.iter().map(|(k, v)| (k, v.clone())).collect(),
102 Self::Data {
103 row,
104 next: Some(next),
105 ..
106 } => next
107 .get_all_entries()
108 .into_iter()
109 .chain(row.iter().map(|(k, v)| (k, v.clone())))
110 .collect(),
111 Self::Bridge { left, right } => {
112 [left.get_all_entries(), right.get_all_entries()].concat()
113 }
114 _ => vec![],
115 }
116 }
117}