surrealdb_core/sql/statements/remove/
database.rs

1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::err::Error;
4use crate::iam::{Action, ResourceKind};
5use crate::sql::{Base, Ident, Value};
6
7use revision::revisioned;
8use serde::{Deserialize, Serialize};
9use std::fmt::{self, Display, Formatter};
10
11#[revisioned(revision = 3)]
12#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
13#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
14#[non_exhaustive]
15pub struct RemoveDatabaseStatement {
16	pub name: Ident,
17	#[revision(start = 2)]
18	pub if_exists: bool,
19	#[revision(start = 3)]
20	pub expunge: bool,
21}
22
23impl RemoveDatabaseStatement {
24	/// Process this type returning a computed simple Value
25	pub(crate) async fn compute(&self, ctx: &Context, opt: &Options) -> Result<Value, Error> {
26		let future = async {
27			// Allowed to run?
28			opt.is_allowed(Action::Edit, ResourceKind::Database, &Base::Ns)?;
29			// Get the transaction
30			let txn = ctx.tx();
31			// Remove the index stores
32			#[cfg(not(target_family = "wasm"))]
33			ctx.get_index_stores()
34				.database_removed(ctx.get_index_builder(), &txn, opt.ns()?, &self.name)
35				.await?;
36			#[cfg(target_family = "wasm")]
37			ctx.get_index_stores().database_removed(&txn, opt.ns()?, &self.name).await?;
38			// Get the definition
39			let db = txn.get_db(opt.ns()?, &self.name).await?;
40			// Delete the definition
41			let key = crate::key::namespace::db::new(opt.ns()?, &db.name);
42			match self.expunge {
43				true => txn.clr(key).await?,
44				false => txn.del(key).await?,
45			};
46			// Delete the resource data
47			let key = crate::key::database::all::new(opt.ns()?, &db.name);
48			match self.expunge {
49				true => txn.clrp(key).await?,
50				false => txn.delp(key).await?,
51			};
52			// Clear the cache
53			if let Some(cache) = ctx.get_cache() {
54				cache.clear();
55			}
56			// Clear the cache
57			txn.clear();
58			// Ok all good
59			Ok(Value::None)
60		}
61		.await;
62		match future {
63			Err(Error::DbNotFound {
64				..
65			}) if self.if_exists => Ok(Value::None),
66			v => v,
67		}
68	}
69}
70
71impl Display for RemoveDatabaseStatement {
72	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
73		write!(f, "REMOVE DATABASE")?;
74		if self.if_exists {
75			write!(f, " IF EXISTS")?
76		}
77		write!(f, " {}", self.name)?;
78		Ok(())
79	}
80}