surrealdb_core/sql/statements/remove/
user.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 = 2)]
12#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
13#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
14#[non_exhaustive]
15pub struct RemoveUserStatement {
16	pub name: Ident,
17	pub base: Base,
18	#[revision(start = 2)]
19	pub if_exists: bool,
20}
21
22impl RemoveUserStatement {
23	/// Process this type returning a computed simple Value
24	pub(crate) async fn compute(&self, ctx: &Context, opt: &Options) -> Result<Value, Error> {
25		let future = async {
26			// Allowed to run?
27			opt.is_allowed(Action::Edit, ResourceKind::Actor, &self.base)?;
28			// Check the statement type
29			match self.base {
30				Base::Root => {
31					// Get the transaction
32					let txn = ctx.tx();
33					// Get the definition
34					let us = txn.get_root_user(&self.name).await?;
35					// Process the statement
36					let key = crate::key::root::us::new(&us.name);
37					txn.del(key).await?;
38					// Clear the cache
39					txn.clear();
40					// Ok all good
41					Ok(Value::None)
42				}
43				Base::Ns => {
44					// Get the transaction
45					let txn = ctx.tx();
46					// Get the definition
47					let us = txn.get_ns_user(opt.ns()?, &self.name).await?;
48					// Delete the definition
49					let key = crate::key::namespace::us::new(opt.ns()?, &us.name);
50					txn.del(key).await?;
51					// Clear the cache
52					txn.clear();
53					// Ok all good
54					Ok(Value::None)
55				}
56				Base::Db => {
57					// Get the transaction
58					let txn = ctx.tx();
59					// Get the definition
60					let (ns, db) = opt.ns_db()?;
61					let us = txn.get_db_user(ns, db, &self.name).await?;
62					// Delete the definition
63					let key = crate::key::database::us::new(ns, db, &us.name);
64					txn.del(key).await?;
65					// Clear the cache
66					txn.clear();
67					// Ok all good
68					Ok(Value::None)
69				}
70				_ => Err(Error::InvalidLevel(self.base.to_string())),
71			}
72		}
73		.await;
74		match future {
75			Err(e) if self.if_exists => match e {
76				Error::UserRootNotFound {
77					..
78				} => Ok(Value::None),
79				Error::UserNsNotFound {
80					..
81				} => Ok(Value::None),
82				Error::UserDbNotFound {
83					..
84				} => Ok(Value::None),
85				e => Err(e),
86			},
87			v => v,
88		}
89	}
90}
91
92impl Display for RemoveUserStatement {
93	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
94		write!(f, "REMOVE USER")?;
95		if self.if_exists {
96			write!(f, " IF EXISTS")?
97		}
98		write!(f, " {} ON {}", self.name, self.base)?;
99		Ok(())
100	}
101}