surrealdb_core/sql/value/
fetch.rs1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::err::Error;
4use crate::sql::edges::Edges;
5use crate::sql::field::{Field, Fields};
6use crate::sql::part::Next;
7use crate::sql::part::Part;
8use crate::sql::statements::select::SelectStatement;
9use crate::sql::value::{Value, Values};
10use futures::future::try_join_all;
11use reblessive::tree::Stk;
12
13impl Value {
14 pub(crate) async fn fetch(
15 &mut self,
16 stk: &mut Stk,
17 ctx: &Context,
18 opt: &Options,
19 path: &[Part],
20 ) -> Result<(), Error> {
21 let mut this = self;
22 let mut iter = path.iter();
23 let mut prev = path;
24
25 while let Some(p) = iter.next() {
32 match p {
33 Part::Graph(g) => match this {
34 Value::Object(o) => {
35 let Some(v) = o.rid() else {
36 return Ok(());
37 };
38
39 let mut v = Value::Thing(v);
40 return stk.run(|stk| v.fetch(stk, ctx, opt, iter.as_slice())).await;
41 }
42 Value::Thing(x) => {
43 let stm = SelectStatement {
44 expr: g.expr.clone().unwrap_or(Fields::all()),
45 what: Values(vec![Value::from(Edges {
46 from: x.clone(),
47 dir: g.dir.clone(),
48 what: g.what.clone(),
49 })]),
50 cond: g.cond.clone(),
51 limit: g.limit.clone(),
52 order: g.order.clone(),
53 split: g.split.clone(),
54 group: g.group.clone(),
55 start: g.start.clone(),
56 ..SelectStatement::default()
57 };
58 *this = stm
59 .compute(stk, ctx, opt, None)
60 .await?
61 .all()
62 .get(stk, ctx, opt, None, path.next())
63 .await?
64 .flatten()
65 .ok()?;
66 return Ok(());
67 }
68 Value::Array(x) => {
69 stk.scope(|scope| {
71 let futs =
72 x.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, prev)));
73 try_join_all(futs)
74 })
75 .await?;
76 return Ok(());
77 }
78 _ => return Ok(()),
80 },
81 Part::Field(f) => match this {
82 Value::Object(o) => {
83 let Some(x) = o.get_mut(f.0.as_str()) else {
84 return Ok(());
85 };
86 this = x;
87 }
88 Value::Array(x) => {
89 stk.scope(|scope| {
91 let futs =
92 x.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, prev)));
93 try_join_all(futs)
94 })
95 .await?;
96 return Ok(());
97 }
98 _ => break,
99 },
100 Part::Index(i) => match this {
101 Value::Object(v) => {
102 let Some(x) = v.get_mut(&i.to_string()) else {
103 return Ok(());
104 };
105 this = x;
106 }
107 Value::Array(v) => {
108 let Some(x) = v.get_mut(i.to_usize()) else {
109 return Ok(());
110 };
111 this = x;
112 }
113 _ => break,
114 },
115 Part::Value(v) => {
116 let v = v.compute(stk, ctx, opt, None).await?;
117 match this {
118 Value::Object(obj) => {
119 let Some(x) = obj.get_mut(v.coerce_to_string()?.as_str()) else {
120 return Ok(());
121 };
122 this = x;
123 }
124 Value::Array(array) => {
125 if let Value::Range(x) = v {
126 let Some(range) = x.slice(array) else {
127 return Ok(());
128 };
129 let mut range = Value::Array(range.to_vec().into());
130 return stk
131 .run(|stk| range.fetch(stk, ctx, opt, iter.as_slice()))
132 .await;
133 }
134 let Some(x) = array.get_mut(v.coerce_to_u64()? as usize) else {
135 return Ok(());
136 };
137 this = x;
138 }
139 _ => return Ok(()),
140 }
141 }
142 Part::Destructure(p) => match this {
143 Value::Array(x) => {
144 stk.scope(|scope| {
146 let futs =
147 x.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, prev)));
148 try_join_all(futs)
149 })
150 .await?;
151 }
152 Value::Object(_) => {
153 for p in p.iter() {
154 let mut destructure_path = p.path();
155 destructure_path.extend_from_slice(path);
156 stk.run(|stk| this.fetch(stk, ctx, opt, &destructure_path)).await?;
157 }
158 return Ok(());
159 }
160 _ => return Ok(()),
161 },
162 Part::All => match this {
163 Value::Object(x) => {
164 let next_path = iter.as_slice();
165 if next_path.is_empty() {
168 break;
169 }
170
171 stk.scope(|scope| {
172 let futs = x
173 .iter_mut()
174 .map(|(_, v)| scope.run(|stk| v.fetch(stk, ctx, opt, next_path)));
175 try_join_all(futs)
176 })
177 .await?;
178 return Ok(());
179 }
180 Value::Array(x) => {
181 let next_path = iter.as_slice();
182 if next_path.is_empty() {
185 break;
186 }
187
188 stk.scope(|scope| {
189 let futs = x
190 .iter_mut()
191 .map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, next_path)));
192 try_join_all(futs)
193 })
194 .await?;
195 return Ok(());
196 }
197 _ => break,
198 },
199 Part::First => match this {
200 Value::Array(x) => {
201 let Some(x) = x.first_mut() else {
202 return Ok(());
203 };
204 this = x;
205 }
206 _ => return Ok(()),
207 },
208 Part::Last => match this {
209 Value::Array(x) => {
210 let Some(x) = x.last_mut() else {
211 return Ok(());
212 };
213 this = x;
214 }
215 _ => return Ok(()),
216 },
217 Part::Where(w) => match this {
218 Value::Array(x) => {
219 for v in x.iter_mut() {
220 let doc = v.clone().into();
221 if w.compute(stk, ctx, opt, Some(&doc)).await?.is_truthy() {
222 stk.run(|stk| v.fetch(stk, ctx, opt, iter.as_slice())).await?;
223 }
224 }
225 }
226 _ => return Ok(()),
227 },
228 _ => break,
229 }
230 prev = iter.as_slice();
231 }
232
233 match this {
235 Value::Array(v) => {
236 stk.scope(|scope| {
237 let futs = v.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, path)));
238 try_join_all(futs)
239 })
240 .await?;
241 Ok(())
242 }
243 Value::Thing(v) => {
244 let val = v.clone();
246 let stm = SelectStatement {
248 expr: Fields(vec![Field::All], false),
249 what: Values(vec![Value::from(val)]),
250 ..SelectStatement::default()
251 };
252 *this = stm.compute(stk, ctx, opt, None).await?.first();
253 Ok(())
254 }
255 _ => Ok(()),
256 }
257 }
258}