surrealdb/sql/statements/
create.rs

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