Skip to main content

surql_parser/upstream/sql/statements/
access.rs

1use crate::compat::types::PublicDuration;
2use crate::upstream::fmt::{EscapeIdent, EscapeKwFreeIdent};
3use crate::upstream::sql::{Base, Cond, RecordIdLit};
4use surrealdb_types::{SqlFormat, ToSql, write_sql};
5#[derive(Clone, Debug, PartialEq, Eq)]
6#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
7pub enum AccessStatement {
8	Grant(AccessStatementGrant),
9	Show(AccessStatementShow),
10	Revoke(AccessStatementRevoke),
11	Purge(AccessStatementPurge),
12}
13#[derive(Clone, Debug, PartialEq, Eq)]
14#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
15pub struct AccessStatementGrant {
16	pub ac: String,
17	pub base: Option<Base>,
18	pub subject: Subject,
19}
20#[derive(Clone, Debug, Default, PartialEq, Eq)]
21#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
22pub struct AccessStatementShow {
23	pub ac: String,
24	pub base: Option<Base>,
25	pub gr: Option<String>,
26	pub cond: Option<Cond>,
27}
28#[derive(Clone, Debug, Default, PartialEq, Eq)]
29#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
30pub struct AccessStatementRevoke {
31	pub ac: String,
32	pub base: Option<Base>,
33	pub gr: Option<String>,
34	pub cond: Option<Cond>,
35}
36#[derive(Clone, Debug, Default, PartialEq, Eq)]
37#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
38pub struct AccessStatementPurge {
39	pub ac: String,
40	pub base: Option<Base>,
41	pub kind: PurgeKind,
42	pub grace: PublicDuration,
43}
44#[derive(Clone, Debug, Default, PartialEq, Eq)]
45#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
46pub enum PurgeKind {
47	#[default]
48	Expired,
49	Revoked,
50	Both,
51}
52#[derive(Clone, Debug, PartialEq, Eq)]
53pub enum Subject {
54	Record(RecordIdLit),
55	User(String),
56}
57impl ToSql for AccessStatement {
58	fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
59		match self {
60			Self::Grant(stmt) => {
61				write_sql!(f, fmt, "ACCESS {}", EscapeKwFreeIdent(&stmt.ac));
62				if let Some(ref v) = stmt.base {
63					write_sql!(f, fmt, " ON {v}");
64				}
65				write_sql!(f, fmt, " GRANT");
66				match &stmt.subject {
67					Subject::User(x) => {
68						write_sql!(f, fmt, " FOR USER {}", EscapeIdent(&x))
69					}
70					Subject::Record(x) => write_sql!(f, fmt, " FOR RECORD {}", x),
71				}
72			}
73			Self::Show(stmt) => {
74				write_sql!(f, fmt, "ACCESS {}", EscapeKwFreeIdent(&stmt.ac));
75				if let Some(ref v) = stmt.base {
76					write_sql!(f, fmt, " ON {v}");
77				}
78				write_sql!(f, fmt, " SHOW");
79				match &stmt.gr {
80					Some(v) => write_sql!(f, fmt, " GRANT {}", EscapeKwFreeIdent(v)),
81					None => match &stmt.cond {
82						Some(v) => write_sql!(f, fmt, " {v}"),
83						None => write_sql!(f, fmt, " ALL"),
84					},
85				};
86			}
87			Self::Revoke(stmt) => {
88				write_sql!(f, fmt, "ACCESS {}", EscapeKwFreeIdent(&stmt.ac));
89				if let Some(ref v) = stmt.base {
90					write_sql!(f, fmt, " ON {v}");
91				}
92				write_sql!(f, fmt, " REVOKE");
93				match &stmt.gr {
94					Some(v) => write_sql!(f, fmt, " GRANT {}", EscapeKwFreeIdent(v)),
95					None => match &stmt.cond {
96						Some(v) => write_sql!(f, fmt, " {v}"),
97						None => write_sql!(f, fmt, " ALL"),
98					},
99				};
100			}
101			Self::Purge(stmt) => {
102				write_sql!(f, fmt, "ACCESS {}", EscapeKwFreeIdent(&stmt.ac));
103				if let Some(ref v) = stmt.base {
104					write_sql!(f, fmt, " ON {v}");
105				}
106				f.push_str(" PURGE");
107				match stmt.kind {
108					PurgeKind::Expired => f.push_str(" EXPIRED"),
109					PurgeKind::Revoked => f.push_str(" REVOKED"),
110					PurgeKind::Both => f.push_str(" EXPIRED, REVOKED"),
111				}
112				if !stmt.grace.is_zero() {
113					write_sql!(f, fmt, " FOR {}", stmt.grace);
114				}
115			}
116		}
117	}
118}