surrealdb_core/sql/statements/
create.rs1use crate::ctx::{Context, MutableContext};
2use crate::dbs::{Iterator, Options, Statement};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::idx::planner::RecordStrategy;
6use crate::sql::{Data, Output, Timeout, Value, Values, Version};
7
8use reblessive::tree::Stk;
9use revision::revisioned;
10use serde::{Deserialize, Serialize};
11use std::fmt;
12
13#[revisioned(revision = 3)]
14#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
15#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
16#[non_exhaustive]
17pub struct CreateStatement {
18 #[revision(start = 2)]
20 pub only: bool,
21 pub what: Values,
23 pub data: Option<Data>,
25 pub output: Option<Output>,
27 pub timeout: Option<Timeout>,
29 pub parallel: bool,
31 #[revision(start = 3)]
33 pub version: Option<Version>,
34}
35
36impl CreateStatement {
37 pub(crate) fn writeable(&self) -> bool {
39 true
40 }
41 pub(crate) async fn compute(
43 &self,
44 stk: &mut Stk,
45 ctx: &Context,
46 opt: &Options,
47 doc: Option<&CursorDoc>,
48 ) -> Result<Value, Error> {
49 opt.valid_for_db()?;
51 let mut i = Iterator::new();
53 let stm = Statement::from(self);
55 let version = match &self.version {
57 Some(v) => Some(v.compute(stk, ctx, opt, doc).await?),
58 _ => None,
59 };
60 let opt = &opt.new_with_futures(false).with_version(version);
62 let ctx = match self.timeout.as_ref() {
64 Some(timeout) => {
65 let mut ctx = MutableContext::new(ctx);
66 ctx.add_timeout(*timeout.0)?;
67 ctx.freeze()
68 }
69 None => ctx.clone(),
70 };
71 for w in self.what.0.iter() {
73 let v = w.compute(stk, &ctx, opt, doc).await?;
74 i.prepare(&stm, v).map_err(|e| match e {
75 Error::InvalidStatementTarget {
76 value: v,
77 } => Error::CreateStatement {
78 value: v,
79 },
80 e => e,
81 })?;
82 }
83 let res = i.output(stk, &ctx, opt, &stm, RecordStrategy::KeysAndValues).await?;
85 if ctx.is_timedout() {
87 return Err(Error::QueryTimedout);
88 }
89 match res {
91 Value::Array(mut a) if self.only => match a.len() {
93 1 => Ok(a.remove(0)),
95 _ => Err(Error::SingleOnlyOutput),
97 },
98 v => Ok(v),
100 }
101 }
102}
103
104impl fmt::Display for CreateStatement {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 write!(f, "CREATE")?;
107 if self.only {
108 f.write_str(" ONLY")?
109 }
110 write!(f, " {}", self.what)?;
111 if let Some(ref v) = self.data {
112 write!(f, " {v}")?
113 }
114 if let Some(ref v) = self.output {
115 write!(f, " {v}")?
116 }
117 if let Some(ref v) = self.version {
118 write!(f, " {v}")?
119 }
120 if let Some(ref v) = self.timeout {
121 write!(f, " {v}")?
122 }
123 if self.parallel {
124 f.write_str(" PARALLEL")?
125 }
126 Ok(())
127 }
128}