shape_runtime/context/
data_access.rs1use crate::data::OwnedDataRow as RowValue;
6use crate::data::Timeframe;
7use shape_ast::error::{Result, ShapeError};
8
9impl super::ExecutionContext {
10 pub fn set_current_row(&mut self, index: usize) -> Result<()> {
12 self.current_row_index = index;
14 Ok(())
15 }
16
17 pub fn current_row_index(&self) -> usize {
19 self.current_row_index
20 }
21
22 pub fn get_current_row_index(&self) -> usize {
24 self.current_row_index
25 }
26
27 pub fn row_count(&self) -> usize {
29 if let Some(ref cache) = self.data_cache {
30 if let (Ok(id), Ok(timeframe)) = (self.get_current_id(), self.get_current_timeframe()) {
31 return cache.row_count(&id, &timeframe);
32 }
33 }
34 0
35 }
36
37 pub fn get_row_timestamp(&self, index: usize) -> Result<i64> {
39 if let Some(ref cache) = self.data_cache {
40 let id = self.get_current_id()?;
41 let timeframe = self.get_current_timeframe()?;
42
43 if let Some(row) = cache.get_row(&id, &timeframe, index) {
44 return Ok(row.timestamp);
45 }
46 }
47
48 Err(ShapeError::DataError {
49 message: format!("No timestamp available at index {}", index),
50 symbol: self.current_id.clone(),
51 timeframe: self.current_timeframe.as_ref().map(|t| t.to_string()),
52 })
53 }
54
55 pub fn get_row(&mut self, relative_index: i32) -> Result<RowValue> {
57 tracing::trace!("get_row called with relative_index: {}", relative_index);
58
59 if let Some(ref guard) = self.lookahead_guard {
61 guard.check_row_index(relative_index, "get_row")?;
62 }
63
64 if let Some(ref cache) = self.data_cache {
66 let id = self.get_current_id()?;
67 let timeframe = self.get_current_timeframe()?;
68 let absolute_index = (self.current_row_index as i32 + relative_index) as usize;
69
70 if let Some(row) = cache.get_row(&id, &timeframe, absolute_index) {
71 return Ok(row);
72 }
73 }
74
75 Err(ShapeError::DataError {
78 message: format!(
79 "No data available at index {}. Data must be prefetched before execution.",
80 relative_index
81 ),
82 symbol: self.current_id.clone(), timeframe: self.current_timeframe.as_ref().map(|tf| tf.to_string()),
84 })
85 }
86
87 pub fn get_row_range(&mut self, start: i32, end: i32) -> Result<Vec<RowValue>> {
89 if let Some(ref guard) = self.lookahead_guard {
91 guard.check_row_index(start, "get_row_range_start")?;
93 guard.check_row_index(end, "get_row_range_end")?;
94 }
95
96 if start > end {
97 return Err(ShapeError::RuntimeError {
98 message: format!("Invalid row range: {} to {}", start, end),
99 location: None,
100 });
101 }
102
103 if let Some(ref cache) = self.data_cache {
105 let id = self.get_current_id()?;
106 let timeframe = self.get_current_timeframe()?;
107
108 let mut rows = Vec::new();
109 for i in start..=end {
110 let absolute_index = (self.current_row_index as i32 + i) as usize;
111 if let Some(row) = cache.get_row(&id, &timeframe, absolute_index) {
112 rows.push(row);
113 }
114 }
115 return Ok(rows);
116 }
117
118 Ok(Vec::new())
119 }
120
121 pub fn get_row_with_timeframe(
123 &mut self,
124 index: i32,
125 timeframe: &Timeframe,
126 ) -> Result<RowValue> {
127 if let Some(ref cache) = self.data_cache {
129 let id = self.get_current_id()?;
130 let absolute_index = (self.current_row_index as i32 + index) as usize;
131
132 if let Some(row) = cache.get_row(&id, timeframe, absolute_index) {
133 return Ok(row);
134 }
135 }
136
137 Err(ShapeError::DataError {
138 message: format!(
139 "No data available for timeframe {} at index {}",
140 timeframe, index
141 ),
142 symbol: self.current_id.clone(),
143 timeframe: Some(timeframe.to_string()),
144 })
145 }
146
147 pub fn get_row_range_with_timeframe(
149 &mut self,
150 start: i32,
151 end: i32,
152 timeframe: &Timeframe,
153 ) -> Result<Vec<RowValue>> {
154 if start > end {
155 return Err(ShapeError::RuntimeError {
156 message: format!("Invalid row range: {} to {}", start, end),
157 location: None,
158 });
159 }
160
161 if let Some(ref cache) = self.data_cache {
162 let id = self.get_current_id()?;
163
164 let mut rows = Vec::new();
165 for i in start..=end {
166 let absolute_index = (self.current_row_index as i32 + i) as usize;
167 if let Some(row) = cache.get_row(&id, timeframe, absolute_index) {
168 rows.push(row);
169 }
170 }
171 return Ok(rows);
172 }
173
174 Ok(Vec::new())
175 }
176
177 pub fn get_row_relative_to_reference(&mut self, relative_index: i32) -> Result<RowValue> {
179 self.get_row(relative_index)
181 }
182
183 pub fn get_row_range_relative_to_reference(
185 &mut self,
186 start: i32,
187 end: i32,
188 ) -> Result<Vec<RowValue>> {
189 self.get_row_range(start, end)
190 }
191
192 pub fn get_all_rows(&mut self) -> Result<Vec<RowValue>> {
194 if let Some(ref cache) = self.data_cache {
195 let id = self.get_current_id()?;
196 let timeframe = self.get_current_timeframe()?;
197
198 let count = cache.row_count(&id, &timeframe);
199 let mut rows = Vec::with_capacity(count);
200 for i in 0..count {
201 if let Some(row) = cache.get_row(&id, &timeframe, i) {
202 rows.push(row);
203 }
204 }
205 return Ok(rows);
206 }
207
208 Ok(Vec::new())
209 }
210}