surrealdb_core/sql/
statement.rs

1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::sql::statements::rebuild::RebuildStatement;
6use crate::sql::statements::AccessStatement;
7use crate::sql::{
8	fmt::{Fmt, Pretty},
9	statements::{
10		AlterStatement, AnalyzeStatement, BeginStatement, BreakStatement, CancelStatement,
11		CommitStatement, ContinueStatement, CreateStatement, DefineStatement, DeleteStatement,
12		ForeachStatement, IfelseStatement, InfoStatement, InsertStatement, KillStatement,
13		LiveStatement, OptionStatement, OutputStatement, RelateStatement, RemoveStatement,
14		SelectStatement, SetStatement, ShowStatement, SleepStatement, ThrowStatement,
15		UpdateStatement, UpsertStatement, UseStatement,
16	},
17	value::Value,
18};
19
20use reblessive::tree::Stk;
21use revision::revisioned;
22use serde::{Deserialize, Serialize};
23use std::{
24	fmt::{self, Display, Formatter, Write},
25	ops::Deref,
26};
27
28#[revisioned(revision = 1)]
29#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
30#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
31#[non_exhaustive]
32pub struct Statements(pub Vec<Statement>);
33
34impl Deref for Statements {
35	type Target = Vec<Statement>;
36	fn deref(&self) -> &Self::Target {
37		&self.0
38	}
39}
40
41impl IntoIterator for Statements {
42	type Item = Statement;
43	type IntoIter = std::vec::IntoIter<Self::Item>;
44	fn into_iter(self) -> Self::IntoIter {
45		self.0.into_iter()
46	}
47}
48
49impl Display for Statements {
50	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51		Display::fmt(
52			&Fmt::one_line_separated(self.0.iter().map(|v| Fmt::new(v, |v, f| write!(f, "{v};")))),
53			f,
54		)
55	}
56}
57
58#[revisioned(revision = 5)]
59#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
60#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
61#[non_exhaustive]
62pub enum Statement {
63	Value(Value),
64	Analyze(AnalyzeStatement),
65	Begin(BeginStatement),
66	Break(BreakStatement),
67	Continue(ContinueStatement),
68	Cancel(CancelStatement),
69	Commit(CommitStatement),
70	Create(CreateStatement),
71	Define(DefineStatement),
72	Delete(DeleteStatement),
73	Foreach(ForeachStatement),
74	Ifelse(IfelseStatement),
75	Info(InfoStatement),
76	Insert(InsertStatement),
77	Kill(KillStatement),
78	Live(LiveStatement),
79	Option(OptionStatement),
80	Output(OutputStatement),
81	Relate(RelateStatement),
82	Remove(RemoveStatement),
83	Select(SelectStatement),
84	Set(SetStatement),
85	Show(ShowStatement),
86	Sleep(SleepStatement),
87	Update(UpdateStatement),
88	Throw(ThrowStatement),
89	Use(UseStatement),
90	#[revision(start = 2)]
91	Rebuild(RebuildStatement),
92	#[revision(start = 3)]
93	Upsert(UpsertStatement),
94	#[revision(start = 4)]
95	Alter(AlterStatement),
96	// TODO(gguillemas): Document once bearer access is no longer experimental.
97	#[revision(start = 5)]
98	Access(AccessStatement),
99}
100
101impl Statement {
102	/// Check if we require a writeable transaction
103	pub(crate) fn writeable(&self) -> bool {
104		match self {
105			Self::Value(v) => v.writeable(),
106			Self::Access(_) => true,
107			Self::Alter(_) => true,
108			Self::Analyze(_) => false,
109			Self::Break(_) => false,
110			Self::Continue(_) => false,
111			Self::Create(v) => v.writeable(),
112			Self::Define(_) => true,
113			Self::Delete(v) => v.writeable(),
114			Self::Foreach(v) => v.writeable(),
115			Self::Ifelse(v) => v.writeable(),
116			Self::Info(_) => false,
117			Self::Insert(v) => v.writeable(),
118			Self::Kill(_) => true,
119			Self::Live(_) => true,
120			Self::Output(v) => v.writeable(),
121			Self::Option(_) => false,
122			Self::Rebuild(_) => true,
123			Self::Relate(v) => v.writeable(),
124			Self::Remove(_) => true,
125			Self::Select(v) => v.writeable(),
126			Self::Set(v) => v.writeable(),
127			Self::Show(_) => false,
128			Self::Sleep(_) => false,
129			Self::Throw(_) => false,
130			Self::Upsert(v) => v.writeable(),
131			Self::Update(v) => v.writeable(),
132			Self::Use(_) => false,
133			_ => false,
134		}
135	}
136	/// Process this type returning a computed simple Value
137	pub(crate) async fn compute(
138		&self,
139		stk: &mut Stk,
140		ctx: &Context,
141		opt: &Options,
142		doc: Option<&CursorDoc>,
143	) -> Result<Value, Error> {
144		let stm = match (opt.import, self) {
145			// All exports in SurrealDB 1.x are done with `UPDATE`, but
146			// because `UPDATE` works different in SurrealDB 2.x, we need
147			// to convert these statements into `UPSERT` statements.
148			(true, Self::Update(stm)) => &Statement::Upsert(UpsertStatement {
149				only: stm.only,
150				what: stm.what.to_owned(),
151				data: stm.data.to_owned(),
152				cond: stm.cond.to_owned(),
153				output: stm.output.to_owned(),
154				timeout: stm.timeout.to_owned(),
155				parallel: stm.parallel,
156			}),
157			(_, stm) => stm,
158		};
159
160		match stm {
161			Self::Access(v) => v.compute(stk, ctx, opt, doc).await,
162			Self::Alter(v) => v.compute(stk, ctx, opt, doc).await,
163			Self::Analyze(v) => v.compute(ctx, opt, doc).await,
164			Self::Break(v) => v.compute(ctx, opt, doc).await,
165			Self::Continue(v) => v.compute(ctx, opt, doc).await,
166			Self::Create(v) => v.compute(stk, ctx, opt, doc).await,
167			Self::Delete(v) => v.compute(stk, ctx, opt, doc).await,
168			Self::Define(v) => v.compute(stk, ctx, opt, doc).await,
169			Self::Foreach(v) => v.compute(stk, ctx, opt, doc).await,
170			Self::Ifelse(v) => v.compute(stk, ctx, opt, doc).await,
171			Self::Info(v) => v.compute(stk, ctx, opt, doc).await,
172			Self::Insert(v) => v.compute(stk, ctx, opt, doc).await,
173			Self::Kill(v) => v.compute(stk, ctx, opt, doc).await,
174			Self::Live(v) => v.compute(stk, ctx, opt, doc).await,
175			Self::Output(v) => v.compute(stk, ctx, opt, doc).await,
176			Self::Relate(v) => v.compute(stk, ctx, opt, doc).await,
177			Self::Rebuild(v) => v.compute(stk, ctx, opt, doc).await,
178			Self::Remove(v) => v.compute(ctx, opt, doc).await,
179			Self::Select(v) => v.compute(stk, ctx, opt, doc).await,
180			Self::Set(v) => v.compute(stk, ctx, opt, doc).await,
181			Self::Show(v) => v.compute(ctx, opt, doc).await,
182			Self::Sleep(v) => v.compute(ctx, opt, doc).await,
183			Self::Throw(v) => v.compute(stk, ctx, opt, doc).await,
184			Self::Update(v) => v.compute(stk, ctx, opt, doc).await,
185			Self::Upsert(v) => v.compute(stk, ctx, opt, doc).await,
186			Self::Value(v) => {
187				// Ensure futures are processed
188				let opt = &opt.new_with_futures(true);
189				// Process the output value
190				v.compute_unbordered(stk, ctx, opt, doc).await
191			}
192			_ => Err(fail!("Unexpected statement type encountered: {self:?}")),
193		}
194	}
195}
196
197impl Display for Statement {
198	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
199		match self {
200			Self::Value(v) => write!(Pretty::from(f), "{v}"),
201			Self::Access(v) => write!(Pretty::from(f), "{v}"),
202			Self::Alter(v) => write!(Pretty::from(f), "{v}"),
203			Self::Analyze(v) => write!(Pretty::from(f), "{v}"),
204			Self::Begin(v) => write!(Pretty::from(f), "{v}"),
205			Self::Break(v) => write!(Pretty::from(f), "{v}"),
206			Self::Cancel(v) => write!(Pretty::from(f), "{v}"),
207			Self::Commit(v) => write!(Pretty::from(f), "{v}"),
208			Self::Continue(v) => write!(Pretty::from(f), "{v}"),
209			Self::Create(v) => write!(Pretty::from(f), "{v}"),
210			Self::Define(v) => write!(Pretty::from(f), "{v}"),
211			Self::Delete(v) => write!(Pretty::from(f), "{v}"),
212			Self::Foreach(v) => write!(Pretty::from(f), "{v}"),
213			Self::Insert(v) => write!(Pretty::from(f), "{v}"),
214			Self::Ifelse(v) => write!(Pretty::from(f), "{v}"),
215			Self::Info(v) => write!(Pretty::from(f), "{v}"),
216			Self::Kill(v) => write!(Pretty::from(f), "{v}"),
217			Self::Live(v) => write!(Pretty::from(f), "{v}"),
218			Self::Option(v) => write!(Pretty::from(f), "{v}"),
219			Self::Output(v) => write!(Pretty::from(f), "{v}"),
220			Self::Rebuild(v) => write!(Pretty::from(f), "{v}"),
221			Self::Relate(v) => write!(Pretty::from(f), "{v}"),
222			Self::Remove(v) => write!(Pretty::from(f), "{v}"),
223			Self::Select(v) => write!(Pretty::from(f), "{v}"),
224			Self::Set(v) => write!(Pretty::from(f), "{v}"),
225			Self::Show(v) => write!(Pretty::from(f), "{v}"),
226			Self::Sleep(v) => write!(Pretty::from(f), "{v}"),
227			Self::Throw(v) => write!(Pretty::from(f), "{v}"),
228			Self::Update(v) => write!(Pretty::from(f), "{v}"),
229			Self::Upsert(v) => write!(Pretty::from(f), "{v}"),
230			Self::Use(v) => write!(Pretty::from(f), "{v}"),
231		}
232	}
233}