surrealdb_core/sql/
graph.rsuse crate::sql::cond::Cond;
use crate::sql::dir::Dir;
use crate::sql::field::Fields;
use crate::sql::group::Groups;
use crate::sql::idiom::Idiom;
use crate::sql::limit::Limit;
use crate::sql::order::{OldOrders, Order, OrderList, Ordering};
use crate::sql::split::Splits;
use crate::sql::start::Start;
use crate::sql::table::Tables;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter, Write};
#[revisioned(revision = 3)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[non_exhaustive]
pub struct Graph {
pub dir: Dir,
#[revision(end = 3, convert_fn = "convert_old_expr")]
pub old_expr: Fields,
#[revision(start = 3)]
pub expr: Option<Fields>,
pub what: Tables,
pub cond: Option<Cond>,
pub split: Option<Splits>,
pub group: Option<Groups>,
#[revision(end = 2, convert_fn = "convert_old_orders")]
pub old_order: Option<OldOrders>,
#[revision(start = 2)]
pub order: Option<Ordering>,
pub limit: Option<Limit>,
pub start: Option<Start>,
pub alias: Option<Idiom>,
}
impl Graph {
fn convert_old_orders(
&mut self,
_rev: u16,
old_value: Option<OldOrders>,
) -> Result<(), revision::Error> {
let Some(x) = old_value else {
return Ok(());
};
if x.0.iter().any(|x| x.random) {
self.order = Some(Ordering::Random);
return Ok(());
}
let new_ord =
x.0.into_iter()
.map(|x| Order {
value: x.order,
collate: x.collate,
numeric: x.numeric,
direction: x.direction,
})
.collect();
self.order = Some(Ordering::Order(OrderList(new_ord)));
Ok(())
}
fn convert_old_expr(&mut self, _rev: u16, _old_value: Fields) -> Result<(), revision::Error> {
self.expr = None;
Ok(())
}
pub fn to_raw(&self) -> String {
self.to_string()
}
}
impl Display for Graph {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if self.what.0.len() <= 1 && self.cond.is_none() && self.alias.is_none() {
Display::fmt(&self.dir, f)?;
match self.what.len() {
0 => f.write_char('?'),
_ => Display::fmt(&self.what, f),
}
} else {
write!(f, "{}(", self.dir)?;
match self.what.len() {
0 => f.write_char('?'),
_ => Display::fmt(&self.what, f),
}?;
if let Some(ref v) = self.cond {
write!(f, " {v}")?
}
if let Some(ref v) = self.split {
write!(f, " {v}")?
}
if let Some(ref v) = self.group {
write!(f, " {v}")?
}
if let Some(ref v) = self.order {
write!(f, " {v}")?
}
if let Some(ref v) = self.limit {
write!(f, " {v}")?
}
if let Some(ref v) = self.start {
write!(f, " {v}")?
}
if let Some(ref v) = self.alias {
write!(f, " AS {v}")?
}
f.write_char(')')
}
}
}