surrealdb_core/sql/statements/
sleep.rs

1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::iam::{Action, ResourceKind};
6use crate::sql::{Base, Duration, Value};
7
8use revision::revisioned;
9use serde::{Deserialize, Serialize};
10use std::fmt;
11
12#[revisioned(revision = 1)]
13#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
14#[non_exhaustive]
15pub struct SleepStatement {
16	pub(crate) duration: Duration,
17}
18
19impl SleepStatement {
20	/// Process this type returning a computed simple Value
21	pub(crate) async fn compute(
22		&self,
23		ctx: &Context,
24		opt: &Options,
25		_doc: Option<&CursorDoc>,
26	) -> Result<Value, Error> {
27		// Allowed to run?
28		opt.is_allowed(Action::Edit, ResourceKind::Table, &Base::Root)?;
29		// Calculate the sleep duration
30		let dur = match (ctx.timeout(), self.duration.0) {
31			(Some(t), d) if t < d => t,
32			(_, d) => d,
33		};
34		// Sleep for the specified time
35		#[cfg(target_family = "wasm")]
36		wasmtimer::tokio::sleep(dur).await;
37		#[cfg(not(target_family = "wasm"))]
38		tokio::time::sleep(dur).await;
39		// Ok all good
40		Ok(Value::None)
41	}
42}
43
44impl fmt::Display for SleepStatement {
45	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46		write!(f, "SLEEP {}", self.duration)
47	}
48}
49
50#[cfg(test)]
51mod tests {
52	use super::*;
53	use crate::dbs::test::mock;
54	use std::time::{self, SystemTime};
55
56	#[tokio::test]
57	async fn test_sleep_compute() {
58		let time = SystemTime::now();
59		let (ctx, opt) = mock().await;
60		let stm = SleepStatement {
61			duration: Duration(time::Duration::from_micros(500)),
62		};
63		let value = stm.compute(&ctx, &opt, None).await.unwrap();
64		assert!(time.elapsed().unwrap() >= time::Duration::from_micros(500));
65		assert_eq!(value, Value::None);
66	}
67}