Skip to main content

surrealdb_sql/statements/alter/
access.rs

1use common::fmt::{QuoteStr, SqlDuration};
2use surrealdb_types::{SqlFormat, ToSql, write_sql};
3
4use super::AlterKind;
5use crate::{Base, CoverStmts, Expr, Literal};
6
7#[derive(Clone, Debug, Eq, PartialEq)]
8#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
9/// AST node for `ALTER ACCESS`.
10pub struct AlterAccessStatement {
11	pub name: Expr,
12	pub base: Base,
13	pub if_exists: bool,
14	pub authenticate: AlterKind<Expr>,
15	pub context: AlterKind<Expr>,
16	pub grant_duration: AlterKind<std::time::Duration>,
17	pub token_duration: AlterKind<std::time::Duration>,
18	pub session_duration: AlterKind<std::time::Duration>,
19	pub comment: AlterKind<String>,
20}
21
22impl Default for AlterAccessStatement {
23	fn default() -> Self {
24		Self {
25			name: Expr::Literal(Literal::None),
26			base: Base::Root,
27			if_exists: false,
28			authenticate: AlterKind::None,
29			context: AlterKind::None,
30			grant_duration: AlterKind::None,
31			token_duration: AlterKind::None,
32			session_duration: AlterKind::None,
33			comment: AlterKind::None,
34		}
35	}
36}
37
38impl ToSql for AlterAccessStatement {
39	fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
40		write_sql!(f, fmt, "ALTER ACCESS");
41		if self.if_exists {
42			write_sql!(f, fmt, " IF EXISTS");
43		}
44		write_sql!(f, fmt, " {} ON {}", CoverStmts(&self.name), &self.base);
45
46		match self.authenticate {
47			AlterKind::Set(ref v) => write_sql!(f, fmt, " AUTHENTICATE {}", CoverStmts(v)),
48			AlterKind::Drop => f.push_str(" DROP AUTHENTICATE"),
49			AlterKind::None => {}
50		}
51
52		match self.context {
53			AlterKind::Set(ref v) => write_sql!(f, fmt, " CONTEXT {}", CoverStmts(v)),
54			AlterKind::Drop => f.push_str(" DROP CONTEXT"),
55			AlterKind::None => {}
56		}
57
58		let has_duration = !matches!(
59			(&self.grant_duration, &self.token_duration, &self.session_duration),
60			(AlterKind::None, AlterKind::None, AlterKind::None)
61		);
62		if has_duration {
63			f.push_str(" DURATION");
64			// Each altered clause is separated from the previous one, never
65			// terminated: a trailing comma leaves the parser expecting a
66			// fourth `FOR`.
67			let mut written = false;
68			let mut separate = |f: &mut String| {
69				if std::mem::replace(&mut written, true) {
70					f.push(',');
71				}
72			};
73			match self.grant_duration {
74				AlterKind::Set(d) => {
75					separate(f);
76					write_sql!(f, fmt, " FOR GRANT {}", SqlDuration(d))
77				}
78				AlterKind::Drop => {
79					separate(f);
80					f.push_str(" FOR GRANT NONE")
81				}
82				AlterKind::None => {}
83			}
84			match self.token_duration {
85				AlterKind::Set(d) => {
86					separate(f);
87					write_sql!(f, fmt, " FOR TOKEN {}", SqlDuration(d))
88				}
89				AlterKind::Drop => {
90					separate(f);
91					f.push_str(" FOR TOKEN NONE")
92				}
93				AlterKind::None => {}
94			}
95			match self.session_duration {
96				AlterKind::Set(d) => {
97					separate(f);
98					write_sql!(f, fmt, " FOR SESSION {}", SqlDuration(d))
99				}
100				AlterKind::Drop => {
101					separate(f);
102					f.push_str(" FOR SESSION NONE")
103				}
104				AlterKind::None => {}
105			}
106		}
107
108		match self.comment {
109			AlterKind::Set(ref v) => write_sql!(f, fmt, " COMMENT {}", QuoteStr(v)),
110			AlterKind::Drop => f.push_str(" DROP COMMENT"),
111			AlterKind::None => {}
112		}
113	}
114}