surrealdb/api/opt/
query.rs

1use crate::api::{err::Error, opt::from_value, Response as QueryResponse, Result};
2use crate::sql::{self, statements::*, Array, Object, Statement, Statements, Value};
3use crate::syn;
4use serde::de::DeserializeOwned;
5use std::mem;
6
7/// A trait for converting inputs into SQL statements
8pub trait IntoQuery {
9	/// Converts an input into SQL statements
10	fn into_query(self) -> Result<Vec<Statement>>;
11}
12
13impl IntoQuery for sql::Query {
14	fn into_query(self) -> Result<Vec<Statement>> {
15		let sql::Query(Statements(statements)) = self;
16		Ok(statements)
17	}
18}
19
20impl IntoQuery for Statements {
21	fn into_query(self) -> Result<Vec<Statement>> {
22		let Statements(statements) = self;
23		Ok(statements)
24	}
25}
26
27impl IntoQuery for Vec<Statement> {
28	fn into_query(self) -> Result<Vec<Statement>> {
29		Ok(self)
30	}
31}
32
33impl IntoQuery for Statement {
34	fn into_query(self) -> Result<Vec<Statement>> {
35		Ok(vec![self])
36	}
37}
38
39impl IntoQuery for UseStatement {
40	fn into_query(self) -> Result<Vec<Statement>> {
41		Ok(vec![Statement::Use(self)])
42	}
43}
44
45impl IntoQuery for SetStatement {
46	fn into_query(self) -> Result<Vec<Statement>> {
47		Ok(vec![Statement::Set(self)])
48	}
49}
50
51impl IntoQuery for InfoStatement {
52	fn into_query(self) -> Result<Vec<Statement>> {
53		Ok(vec![Statement::Info(self)])
54	}
55}
56
57impl IntoQuery for LiveStatement {
58	fn into_query(self) -> Result<Vec<Statement>> {
59		Ok(vec![Statement::Live(self)])
60	}
61}
62
63impl IntoQuery for KillStatement {
64	fn into_query(self) -> Result<Vec<Statement>> {
65		Ok(vec![Statement::Kill(self)])
66	}
67}
68
69impl IntoQuery for BeginStatement {
70	fn into_query(self) -> Result<Vec<Statement>> {
71		Ok(vec![Statement::Begin(self)])
72	}
73}
74
75impl IntoQuery for CancelStatement {
76	fn into_query(self) -> Result<Vec<Statement>> {
77		Ok(vec![Statement::Cancel(self)])
78	}
79}
80
81impl IntoQuery for CommitStatement {
82	fn into_query(self) -> Result<Vec<Statement>> {
83		Ok(vec![Statement::Commit(self)])
84	}
85}
86
87impl IntoQuery for OutputStatement {
88	fn into_query(self) -> Result<Vec<Statement>> {
89		Ok(vec![Statement::Output(self)])
90	}
91}
92
93impl IntoQuery for IfelseStatement {
94	fn into_query(self) -> Result<Vec<Statement>> {
95		Ok(vec![Statement::Ifelse(self)])
96	}
97}
98
99impl IntoQuery for SelectStatement {
100	fn into_query(self) -> Result<Vec<Statement>> {
101		Ok(vec![Statement::Select(self)])
102	}
103}
104
105impl IntoQuery for CreateStatement {
106	fn into_query(self) -> Result<Vec<Statement>> {
107		Ok(vec![Statement::Create(self)])
108	}
109}
110
111impl IntoQuery for UpdateStatement {
112	fn into_query(self) -> Result<Vec<Statement>> {
113		Ok(vec![Statement::Update(self)])
114	}
115}
116
117impl IntoQuery for RelateStatement {
118	fn into_query(self) -> Result<Vec<Statement>> {
119		Ok(vec![Statement::Relate(self)])
120	}
121}
122
123impl IntoQuery for DeleteStatement {
124	fn into_query(self) -> Result<Vec<Statement>> {
125		Ok(vec![Statement::Delete(self)])
126	}
127}
128
129impl IntoQuery for InsertStatement {
130	fn into_query(self) -> Result<Vec<Statement>> {
131		Ok(vec![Statement::Insert(self)])
132	}
133}
134
135impl IntoQuery for DefineStatement {
136	fn into_query(self) -> Result<Vec<Statement>> {
137		Ok(vec![Statement::Define(self)])
138	}
139}
140
141impl IntoQuery for RemoveStatement {
142	fn into_query(self) -> Result<Vec<Statement>> {
143		Ok(vec![Statement::Remove(self)])
144	}
145}
146
147impl IntoQuery for OptionStatement {
148	fn into_query(self) -> Result<Vec<Statement>> {
149		Ok(vec![Statement::Option(self)])
150	}
151}
152
153impl IntoQuery for &str {
154	fn into_query(self) -> Result<Vec<Statement>> {
155		syn::parse(self)?.into_query()
156	}
157}
158
159impl IntoQuery for &String {
160	fn into_query(self) -> Result<Vec<Statement>> {
161		syn::parse(self)?.into_query()
162	}
163}
164
165impl IntoQuery for String {
166	fn into_query(self) -> Result<Vec<Statement>> {
167		syn::parse(&self)?.into_query()
168	}
169}
170
171/// Represents a way to take a single query result from a list of responses
172pub trait QueryResult<Response>
173where
174	Response: DeserializeOwned,
175{
176	/// Extracts and deserializes a query result from a query response
177	fn query_result(self, response: &mut QueryResponse) -> Result<Response>;
178}
179
180impl QueryResult<Value> for usize {
181	fn query_result(self, QueryResponse(map): &mut QueryResponse) -> Result<Value> {
182		match map.remove(&self) {
183			Some(result) => Ok(result?),
184			None => Ok(Value::None),
185		}
186	}
187}
188
189impl<T> QueryResult<Option<T>> for usize
190where
191	T: DeserializeOwned,
192{
193	fn query_result(self, QueryResponse(map): &mut QueryResponse) -> Result<Option<T>> {
194		let value = match map.get_mut(&self) {
195			Some(result) => match result {
196				Ok(val) => val,
197				Err(error) => {
198					let error = mem::replace(error, Error::ConnectionUninitialised.into());
199					map.remove(&self);
200					return Err(error);
201				}
202			},
203			None => {
204				return Ok(None);
205			}
206		};
207		let result = match value {
208			Value::Array(Array(vec)) => match &mut vec[..] {
209				[] => Ok(None),
210				[value] => {
211					let value = mem::take(value);
212					from_value(value).map_err(Into::into)
213				}
214				_ => Err(Error::LossyTake(QueryResponse(mem::take(map))).into()),
215			},
216			_ => {
217				let value = mem::take(value);
218				from_value(value).map_err(Into::into)
219			}
220		};
221		map.remove(&self);
222		result
223	}
224}
225
226impl QueryResult<Value> for (usize, &str) {
227	fn query_result(self, QueryResponse(map): &mut QueryResponse) -> Result<Value> {
228		let (index, key) = self;
229		let response = match map.get_mut(&index) {
230			Some(result) => match result {
231				Ok(val) => val,
232				Err(error) => {
233					let error = mem::replace(error, Error::ConnectionUninitialised.into());
234					map.remove(&index);
235					return Err(error);
236				}
237			},
238			None => {
239				return Ok(Value::None);
240			}
241		};
242
243		let response = match response {
244			Value::Object(Object(object)) => object.remove(key).unwrap_or_default(),
245			_ => Value::None,
246		};
247
248		Ok(response)
249	}
250}
251
252impl<T> QueryResult<Option<T>> for (usize, &str)
253where
254	T: DeserializeOwned,
255{
256	fn query_result(self, QueryResponse(map): &mut QueryResponse) -> Result<Option<T>> {
257		let (index, key) = self;
258		let value = match map.get_mut(&index) {
259			Some(result) => match result {
260				Ok(val) => val,
261				Err(error) => {
262					let error = mem::replace(error, Error::ConnectionUninitialised.into());
263					map.remove(&index);
264					return Err(error);
265				}
266			},
267			None => {
268				return Ok(None);
269			}
270		};
271		let value = match value {
272			Value::Array(Array(vec)) => match &mut vec[..] {
273				[] => {
274					map.remove(&index);
275					return Ok(None);
276				}
277				[value] => value,
278				_ => {
279					return Err(Error::LossyTake(QueryResponse(mem::take(map))).into());
280				}
281			},
282			value => value,
283		};
284		match value {
285			Value::None | Value::Null => {
286				map.remove(&index);
287				Ok(None)
288			}
289			Value::Object(Object(object)) => {
290				if object.is_empty() {
291					map.remove(&index);
292					return Ok(None);
293				}
294				let Some(value) = object.remove(key) else {
295					return Ok(None);
296				};
297				from_value(value).map_err(Into::into)
298			}
299			_ => Ok(None),
300		}
301	}
302}
303
304impl<T> QueryResult<Vec<T>> for usize
305where
306	T: DeserializeOwned,
307{
308	fn query_result(self, QueryResponse(map): &mut QueryResponse) -> Result<Vec<T>> {
309		let vec = match map.remove(&self) {
310			Some(result) => match result? {
311				Value::Array(Array(vec)) => vec,
312				vec => vec![vec],
313			},
314			None => {
315				return Ok(vec![]);
316			}
317		};
318		from_value(vec.into()).map_err(Into::into)
319	}
320}
321
322impl<T> QueryResult<Vec<T>> for (usize, &str)
323where
324	T: DeserializeOwned,
325{
326	fn query_result(self, QueryResponse(map): &mut QueryResponse) -> Result<Vec<T>> {
327		let (index, key) = self;
328		let mut response = match map.get_mut(&index) {
329			Some(result) => match result {
330				Ok(val) => match val {
331					Value::Array(Array(vec)) => mem::take(vec),
332					val => {
333						let val = mem::take(val);
334						vec![val]
335					}
336				},
337				Err(error) => {
338					let error = mem::replace(error, Error::ConnectionUninitialised.into());
339					map.remove(&index);
340					return Err(error);
341				}
342			},
343			None => {
344				return Ok(vec![]);
345			}
346		};
347		let mut vec = Vec::with_capacity(response.len());
348		for value in response.iter_mut() {
349			if let Value::Object(Object(object)) = value {
350				if let Some(value) = object.remove(key) {
351					vec.push(value);
352				}
353			}
354		}
355		from_value(vec.into()).map_err(Into::into)
356	}
357}
358
359impl QueryResult<Value> for &str {
360	fn query_result(self, response: &mut QueryResponse) -> Result<Value> {
361		(0, self).query_result(response)
362	}
363}
364
365impl<T> QueryResult<Option<T>> for &str
366where
367	T: DeserializeOwned,
368{
369	fn query_result(self, response: &mut QueryResponse) -> Result<Option<T>> {
370		(0, self).query_result(response)
371	}
372}
373
374impl<T> QueryResult<Vec<T>> for &str
375where
376	T: DeserializeOwned,
377{
378	fn query_result(self, response: &mut QueryResponse) -> Result<Vec<T>> {
379		(0, self).query_result(response)
380	}
381}