Skip to main content

surrealdb_expr/expr/
fetch.rs

1use revision::revisioned;
2
3use crate::expr::Expr;
4use crate::expr::statements::info::InfoStructure;
5use crate::val::Value;
6
7/// A list of fetches to be applied to the result of a query.
8///
9/// Fetches are applied to the result of a query in the order they are specified.
10/// For this reason, the list of fetches is always sorted to ensure that parent fetches are
11/// applied before child fetches.
12///
13/// For example:
14/// `FETCH a.b, a` is sorted to `FETCH a, a.b`.
15/// `FETCH a.b, a.b.c, d, a, b` is sorted to `FETCH a, a.b, a.b.c, b, d`.
16///
17/// This prevents confusing behaviour like `FETCH a.b, a` only returning `a` because `a.b` gets
18/// clobbered by `a`.
19#[revisioned(revision = 1)]
20#[derive(Clone, Debug, Eq, PartialEq, Hash)]
21pub struct Fetchs(Vec<Fetch>);
22
23impl Fetchs {
24	pub fn new(fetches: Vec<Fetch>) -> Self {
25		Self(fetches)
26	}
27
28	/// Whether evaluating every fetch target can be done on a read-only
29	/// transaction.
30	pub fn read_only(&self) -> bool {
31		self.0.iter().all(|x| x.read_only())
32	}
33
34	pub fn len(&self) -> usize {
35		self.0.len()
36	}
37
38	pub fn is_empty(&self) -> bool {
39		self.0.is_empty()
40	}
41
42	pub fn iter(&self) -> impl Iterator<Item = &Fetch> {
43		self.0.iter()
44	}
45
46	pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Fetch> {
47		self.0.iter_mut()
48	}
49}
50
51impl IntoIterator for Fetchs {
52	type Item = Fetch;
53	type IntoIter = std::vec::IntoIter<Self::Item>;
54	fn into_iter(self) -> Self::IntoIter {
55		self.0.into_iter()
56	}
57}
58
59impl surrealdb_types::ToSql for Fetchs {
60	fn fmt_sql(&self, f: &mut String, fmt: surrealdb_types::SqlFormat) {
61		let sql_fetchs: crate::sql::Fetchs = self.clone().into();
62		sql_fetchs.fmt_sql(f, fmt);
63	}
64}
65
66impl InfoStructure for Fetchs {
67	fn structure(self) -> Value {
68		self.into_iter().map(Fetch::structure).collect::<Vec<_>>().into()
69	}
70}
71
72#[revisioned(revision = 1)]
73#[derive(Clone, Debug, Eq, PartialEq, Hash)]
74pub struct Fetch(pub Expr);
75
76impl Fetch {
77	/// Whether evaluating this fetch target can be done on a read-only
78	/// transaction.
79	pub fn read_only(&self) -> bool {
80		self.0.read_only()
81	}
82}
83
84impl surrealdb_types::ToSql for Fetch {
85	fn fmt_sql(&self, f: &mut String, fmt: surrealdb_types::SqlFormat) {
86		let sql_fetch: crate::sql::Fetch = self.clone().into();
87		sql_fetch.fmt_sql(f, fmt);
88	}
89}
90
91impl InfoStructure for Fetch {
92	fn structure(self) -> Value {
93		use surrealdb_types::ToSql;
94		self.to_sql().into()
95	}
96}