surrealdb_sql/statements/
update.rs

1use crate::ctx::Context;
2use crate::dbs::{Iterator, Options, Statement, Transaction};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::{Cond, Data, Output, Timeout, Value, Values};
6use derive::Store;
7use revision::revisioned;
8use serde::{Deserialize, Serialize};
9use std::fmt;
10
11#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
12#[revisioned(revision = 2)]
13pub struct UpdateStatement {
14	#[revision(start = 2)]
15	pub only: bool,
16	pub what: Values,
17	pub data: Option<Data>,
18	pub cond: Option<Cond>,
19	pub output: Option<Output>,
20	pub timeout: Option<Timeout>,
21	pub parallel: bool,
22}
23
24impl UpdateStatement {
25	/// Check if we require a writeable transaction
26	pub(crate) fn writeable(&self) -> bool {
27		true
28	}
29	/// Process this type returning a computed simple Value
30	pub(crate) async fn compute(
31		&self,
32		ctx: &Context<'_>,
33		opt: &Options,
34		txn: &Transaction,
35		doc: Option<&CursorDoc<'_>>,
36	) -> Result<Value, Error> {
37		// Valid options?
38		opt.valid_for_db()?;
39		// Create a new iterator
40		let mut i = Iterator::new();
41		// Assign the statement
42		let stm = Statement::from(self);
43		// Ensure futures are stored
44		let opt = &opt.new_with_futures(false).with_projections(false);
45		// Loop over the update targets
46		for w in self.what.0.iter() {
47			let v = w.compute(ctx, opt, txn, doc).await?;
48			i.prepare(ctx, opt, txn, &stm, v).await.map_err(|e| match e {
49				Error::InvalidStatementTarget {
50					value: v,
51				} => Error::UpdateStatement {
52					value: v,
53				},
54				e => e,
55			})?;
56		}
57		// Output the results
58		match i.output(ctx, opt, txn, &stm).await? {
59			// This is a single record result
60			Value::Array(mut a) if self.only => match a.len() {
61				// There was exactly one result
62				1 => Ok(a.remove(0)),
63				// There were no results
64				_ => Err(Error::SingleOnlyOutput),
65			},
66			// This is standard query result
67			v => Ok(v),
68		}
69	}
70}
71
72impl fmt::Display for UpdateStatement {
73	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74		write!(f, "UPDATE")?;
75		if self.only {
76			f.write_str(" ONLY")?
77		}
78		write!(f, " {}", self.what)?;
79		if let Some(ref v) = self.data {
80			write!(f, " {v}")?
81		}
82		if let Some(ref v) = self.cond {
83			write!(f, " {v}")?
84		}
85		if let Some(ref v) = self.output {
86			write!(f, " {v}")?
87		}
88		if let Some(ref v) = self.timeout {
89			write!(f, " {v}")?
90		}
91		if self.parallel {
92			f.write_str(" PARALLEL")?
93		}
94		Ok(())
95	}
96}