surrealdb_core/sql/statements/
kill.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use crate::ctx::Context;
use crate::dbs::Options;
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::kvs::Live;
use crate::sql::statements::define::DefineTableStatement;
use crate::sql::Value;
use derive::Store;
use reblessive::tree::Stk;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;

#[revisioned(revision = 1)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[non_exhaustive]
pub struct KillStatement {
	// Uuid of Live Query
	// or Param resolving to Uuid of Live Query
	pub id: Value,
}

impl KillStatement {
	/// Process this type returning a computed simple Value
	pub(crate) async fn compute(
		&self,
		stk: &mut Stk,
		ctx: &Context,
		opt: &Options,
		_doc: Option<&CursorDoc>,
	) -> Result<Value, Error> {
		// Is realtime enabled?
		opt.realtime()?;
		// Valid options?
		opt.valid_for_db()?;
		// Resolve live query id
		let lid = match self.id.compute(stk, ctx, opt, None).await?.convert_to_uuid() {
			Err(_) => {
				return Err(Error::KillStatement {
					value: self.id.to_string(),
				})
			}
			Ok(id) => id,
		};
		// Get the Node ID
		let nid = opt.id()?;
		// Get the LIVE ID
		let lid = lid.0;
		// Get the transaction
		let txn = ctx.tx();
		// Fetch the live query key
		let key = crate::key::node::lq::new(nid, lid);
		// Fetch the live query key if it exists
		match txn.get(key, None).await? {
			Some(val) => {
				// Decode the data for this live query
				let val: Live = val.into();
				// Delete the node live query
				let key = crate::key::node::lq::new(nid, lid);
				txn.del(key).await?;
				// Delete the table live query
				let key = crate::key::table::lq::new(&val.ns, &val.db, &val.tb, lid);
				txn.del(key).await?;
				// Refresh the table cache for lives
				let key = crate::key::database::tb::new(&val.ns, &val.db, &val.tb);
				let tb = txn.get_tb(&val.ns, &val.db, &val.tb).await?;
				txn.set(
					key,
					DefineTableStatement {
						cache_lives_ts: uuid::Uuid::now_v7(),
						..tb.as_ref().clone()
					},
					None,
				)
				.await?;
				// Clear the cache
				txn.clear();
			}
			None => {
				return Err(Error::KillStatement {
					value: self.id.to_string(),
				});
			}
		}
		// Return the query id
		Ok(Value::None)
	}
}

impl fmt::Display for KillStatement {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "KILL {}", self.id)
	}
}