use crate::ctx::Context;
use crate::dbs::Options;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::edges::Edges;
use crate::sql::field::{Field, Fields};
use crate::sql::part::Next;
use crate::sql::part::Part;
use crate::sql::statements::select::SelectStatement;
use crate::sql::value::{Value, Values};
use async_recursion::async_recursion;
use futures::future::try_join_all;
impl Value {
#[cfg_attr(feature = "parallel", async_recursion)]
#[cfg_attr(not(feature = "parallel"), async_recursion(?Send))]
pub async fn fetch(
&mut self,
ctx: &Context<'_>,
opt: &Options,
txn: &Transaction,
path: &[Part],
) -> Result<(), Error> {
match path.first() {
Some(p) => match self {
Value::Object(v) => match p {
Part::Graph(_) => match v.rid() {
Some(v) => Value::Thing(v).fetch(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
Part::Field(f) => match v.get_mut(f as &str) {
Some(v) => v.fetch(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
Part::All => self.fetch(ctx, opt, txn, path.next()).await,
_ => Ok(()),
},
Value::Array(v) => match p {
Part::All => {
let path = path.next();
let futs = v.iter_mut().map(|v| v.fetch(ctx, opt, txn, path));
try_join_all(futs).await?;
Ok(())
}
Part::First => match v.first_mut() {
Some(v) => v.fetch(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
Part::Last => match v.last_mut() {
Some(v) => v.fetch(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
Part::Index(i) => match v.get_mut(i.to_usize()) {
Some(v) => v.fetch(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
Part::Where(w) => {
let path = path.next();
for v in v.iter_mut() {
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
v.fetch(ctx, opt, txn, path).await?;
}
}
Ok(())
}
_ => {
let futs = v.iter_mut().map(|v| v.fetch(ctx, opt, txn, path));
try_join_all(futs).await?;
Ok(())
}
},
Value::Thing(v) => {
let val = v.clone();
match p {
Part::Graph(g) => {
let stm = SelectStatement {
expr: Fields(vec![Field::All]),
what: Values(vec![Value::from(Edges {
from: val,
dir: g.dir.clone(),
what: g.what.clone(),
})]),
cond: g.cond.clone(),
..SelectStatement::default()
};
*self = stm
.compute(ctx, opt, txn, None)
.await?
.all()
.get(ctx, opt, txn, path.next())
.await?
.flatten()
.ok()?;
Ok(())
}
_ => {
let stm = SelectStatement {
expr: Fields(vec![Field::All]),
what: Values(vec![Value::from(val)]),
..SelectStatement::default()
};
*self = stm.compute(ctx, opt, txn, None).await?.first();
Ok(())
}
}
}
_ => Ok(()),
},
None => match self {
Value::Array(v) => {
let futs = v.iter_mut().map(|v| v.fetch(ctx, opt, txn, path));
try_join_all(futs).await?;
Ok(())
}
Value::Thing(v) => {
let val = v.clone();
let stm = SelectStatement {
expr: Fields(vec![Field::All]),
what: Values(vec![Value::from(val)]),
..SelectStatement::default()
};
*self = stm.compute(ctx, opt, txn, None).await?.first();
Ok(())
}
_ => Ok(()),
},
}
}
}