use crate::Expr;
use crate::identifier::Identifier;
use crate::types::AnySurrealType;
use indexmap::IndexMap;
use vantage_expressions::Expressive;
use super::{SurrealUpdate, UpdateMode};
impl SurrealUpdate {
pub fn preview(&self) -> String {
self.expr().preview()
}
fn fields_as_object(&self) -> AnySurrealType {
let map: Vec<(ciborium::Value, ciborium::Value)> = self
.fields
.iter()
.map(|(k, v)| (ciborium::Value::Text(k.clone()), v.value().clone()))
.collect();
AnySurrealType::from_cbor(&ciborium::Value::Map(map))
.unwrap_or_else(|| AnySurrealType::new(IndexMap::<String, AnySurrealType>::new()))
}
fn render_where(&self) -> Option<Expr> {
if self.conditions.is_empty() {
return None;
}
Some(
self.conditions
.iter()
.cloned()
.reduce(|a, b| crate::surreal_expr!("{} AND {}", (a), (b)))
.unwrap(),
)
}
fn append_where(&self, base: Expr) -> Expr {
match self.render_where() {
Some(cond) => crate::surreal_expr!("{} WHERE {}", (base), (cond)),
None => base,
}
}
}
impl Expressive<AnySurrealType> for SurrealUpdate {
fn expr(&self) -> Expr {
let raw = match self.mode {
UpdateMode::Set => {
if self.fields.is_empty() {
crate::surreal_expr!("UPDATE {}", (self.target))
} else {
let placeholders: Vec<String> = self
.fields
.keys()
.map(|k| format!("{} = {{}}", Identifier::new(k).expr().preview()))
.collect();
let template = format!("UPDATE {{}} SET {}", placeholders.join(", "));
let mut params: Vec<vantage_expressions::ExpressiveEnum<AnySurrealType>> =
vec![vantage_expressions::ExpressiveEnum::Nested(
self.target.clone(),
)];
for value in self.fields.values() {
params.push(vantage_expressions::ExpressiveEnum::Scalar(value.clone()));
}
vantage_expressions::Expression::new(template, params)
}
}
UpdateMode::Content => {
let obj = self.fields_as_object();
crate::surreal_expr!("UPDATE {} CONTENT {}", (self.target), obj)
}
UpdateMode::Merge => {
let obj = self.fields_as_object();
crate::surreal_expr!("UPDATE {} MERGE {}", (self.target), obj)
}
};
self.append_where(raw)
}
}
impl From<SurrealUpdate> for Expr {
fn from(update: SurrealUpdate) -> Self {
update.expr()
}
}