Skip to main content

surrealdb_sql/statements/alter/
user.rs

1use common::fmt::{EscapeKwFreeIdent, QuoteStr, SqlDuration};
2use surrealdb_types::{SqlFormat, ToSql, write_sql};
3
4use super::AlterKind;
5use crate::statements::define::user::PassType;
6use crate::{Base, CoverStmts, Expr, Literal};
7
8#[derive(Clone, Debug, Eq, PartialEq)]
9#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
10/// AST node for `ALTER USER`.
11pub struct AlterUserStatement {
12	pub name: Expr,
13	pub base: Base,
14	pub if_exists: bool,
15	pub pass_type: Option<PassType>,
16	/// Explicit SCRAM verifier string (`PASSSCRAM`). Mostly for symmetry with
17	/// `DEFINE USER`; import always emits `DEFINE`.
18	// A SCRAM verifier must be a valid `SCRAM-SHA-256$...` string, which
19	// arbitrary bytes won't satisfy; leave it unset for fuzzing.
20	#[cfg_attr(feature = "arbitrary", arbitrary(default))]
21	pub scram: Option<String>,
22	pub roles: AlterKind<Vec<String>>,
23	pub token_duration: AlterKind<std::time::Duration>,
24	pub session_duration: AlterKind<std::time::Duration>,
25	pub comment: AlterKind<String>,
26}
27
28impl Default for AlterUserStatement {
29	fn default() -> Self {
30		Self {
31			name: Expr::Literal(Literal::None),
32			base: Base::Root,
33			if_exists: false,
34			pass_type: None,
35			scram: None,
36			roles: AlterKind::None,
37			token_duration: AlterKind::None,
38			session_duration: AlterKind::None,
39			comment: AlterKind::None,
40		}
41	}
42}
43
44impl ToSql for AlterUserStatement {
45	fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
46		write_sql!(f, fmt, "ALTER USER");
47		if self.if_exists {
48			write_sql!(f, fmt, " IF EXISTS");
49		}
50		write_sql!(f, fmt, " {} ON {}", CoverStmts(&self.name), &self.base);
51
52		if let Some(ref pt) = self.pass_type {
53			match pt {
54				PassType::Password(p) => write_sql!(f, fmt, " PASSWORD {}", QuoteStr(p)),
55				PassType::Hash(h) => write_sql!(f, fmt, " PASSHASH {}", QuoteStr(h)),
56				PassType::Unset => {}
57			}
58		}
59
60		if let Some(ref x) = self.scram {
61			write_sql!(f, fmt, " PASSSCRAM {}", QuoteStr(x));
62		}
63
64		if let AlterKind::Set(ref roles) = self.roles {
65			write_sql!(f, fmt, " ROLES");
66			for (i, r) in roles.iter().enumerate() {
67				if i > 0 {
68					f.push(',');
69				}
70				write_sql!(f, fmt, " {}", EscapeKwFreeIdent(r));
71			}
72		}
73
74		match self.token_duration {
75			AlterKind::Set(d) => write_sql!(f, fmt, " DURATION FOR TOKEN {}", SqlDuration(d)),
76			AlterKind::Drop => f.push_str(" DURATION FOR TOKEN NONE"),
77			AlterKind::None => {}
78		}
79
80		match self.session_duration {
81			AlterKind::Set(d) => write_sql!(f, fmt, " DURATION FOR SESSION {}", SqlDuration(d)),
82			AlterKind::Drop => f.push_str(" DURATION FOR SESSION NONE"),
83			AlterKind::None => {}
84		}
85
86		match self.comment {
87			AlterKind::Set(ref v) => write_sql!(f, fmt, " COMMENT {}", QuoteStr(v)),
88			AlterKind::Drop => f.push_str(" DROP COMMENT"),
89			AlterKind::None => {}
90		}
91	}
92}