surrealdb_sql/statements/
info.rs

1use crate::ctx::Context;
2use crate::dbs::{Options, Transaction};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::iam::Action;
6use crate::iam::ResourceKind;
7use crate::{Base, Ident, Object, Value};
8use derive::Store;
9use revision::revisioned;
10use serde::{Deserialize, Serialize};
11use std::fmt;
12
13#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
14#[revisioned(revision = 1)]
15pub enum InfoStatement {
16	Root,
17	Ns,
18	Db,
19	Sc(Ident),
20	Tb(Ident),
21	User(Ident, Option<Base>),
22}
23
24impl InfoStatement {
25	/// Process this type returning a computed simple Value
26	pub(crate) async fn compute(
27		&self,
28		_ctx: &Context<'_>,
29		opt: &Options,
30		txn: &Transaction,
31		_doc: Option<&CursorDoc<'_>>,
32	) -> Result<Value, Error> {
33		// Allowed to run?
34		match self {
35			InfoStatement::Root => {
36				// Allowed to run?
37				opt.is_allowed(Action::View, ResourceKind::Any, &Base::Root)?;
38				// Claim transaction
39				let mut run = txn.lock().await;
40				// Create the result set
41				let mut res = Object::default();
42				// Process the namespaces
43				let mut tmp = Object::default();
44				for v in run.all_ns().await?.iter() {
45					tmp.insert(v.name.to_string(), v.to_string().into());
46				}
47				res.insert("namespaces".to_owned(), tmp.into());
48				// Process the users
49				let mut tmp = Object::default();
50				for v in run.all_root_users().await?.iter() {
51					tmp.insert(v.name.to_string(), v.to_string().into());
52				}
53				res.insert("users".to_owned(), tmp.into());
54				// Ok all good
55				Value::from(res).ok()
56			}
57			InfoStatement::Ns => {
58				// Allowed to run?
59				opt.is_allowed(Action::View, ResourceKind::Any, &Base::Ns)?;
60				// Claim transaction
61				let mut run = txn.lock().await;
62				// Create the result set
63				let mut res = Object::default();
64				// Process the databases
65				let mut tmp = Object::default();
66				for v in run.all_db(opt.ns()).await?.iter() {
67					tmp.insert(v.name.to_string(), v.to_string().into());
68				}
69				res.insert("databases".to_owned(), tmp.into());
70				// Process the users
71				let mut tmp = Object::default();
72				for v in run.all_ns_users(opt.ns()).await?.iter() {
73					tmp.insert(v.name.to_string(), v.to_string().into());
74				}
75				res.insert("users".to_owned(), tmp.into());
76				// Process the tokens
77				let mut tmp = Object::default();
78				for v in run.all_ns_tokens(opt.ns()).await?.iter() {
79					tmp.insert(v.name.to_string(), v.to_string().into());
80				}
81				res.insert("tokens".to_owned(), tmp.into());
82				// Ok all good
83				Value::from(res).ok()
84			}
85			InfoStatement::Db => {
86				// Allowed to run?
87				opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
88				// Claim transaction
89				let mut run = txn.lock().await;
90				// Create the result set
91				let mut res = Object::default();
92				// Process the users
93				let mut tmp = Object::default();
94				for v in run.all_db_users(opt.ns(), opt.db()).await?.iter() {
95					tmp.insert(v.name.to_string(), v.to_string().into());
96				}
97				res.insert("users".to_owned(), tmp.into());
98				// Process the tokens
99				let mut tmp = Object::default();
100				for v in run.all_db_tokens(opt.ns(), opt.db()).await?.iter() {
101					tmp.insert(v.name.to_string(), v.to_string().into());
102				}
103				res.insert("tokens".to_owned(), tmp.into());
104				// Process the functions
105				let mut tmp = Object::default();
106				for v in run.all_db_functions(opt.ns(), opt.db()).await?.iter() {
107					tmp.insert(v.name.to_string(), v.to_string().into());
108				}
109				res.insert("functions".to_owned(), tmp.into());
110				// Process the models
111				let mut tmp = Object::default();
112				for v in run.all_db_models(opt.ns(), opt.db()).await?.iter() {
113					tmp.insert(format!("{}<{}>", v.name, v.version), v.to_string().into());
114				}
115				res.insert("models".to_owned(), tmp.into());
116				// Process the params
117				let mut tmp = Object::default();
118				for v in run.all_db_params(opt.ns(), opt.db()).await?.iter() {
119					tmp.insert(v.name.to_string(), v.to_string().into());
120				}
121				res.insert("params".to_owned(), tmp.into());
122				// Process the scopes
123				let mut tmp = Object::default();
124				for v in run.all_sc(opt.ns(), opt.db()).await?.iter() {
125					tmp.insert(v.name.to_string(), v.to_string().into());
126				}
127				res.insert("scopes".to_owned(), tmp.into());
128				// Process the tables
129				let mut tmp = Object::default();
130				for v in run.all_tb(opt.ns(), opt.db()).await?.iter() {
131					tmp.insert(v.name.to_string(), v.to_string().into());
132				}
133				res.insert("tables".to_owned(), tmp.into());
134				// Process the analyzers
135				let mut tmp = Object::default();
136				for v in run.all_db_analyzers(opt.ns(), opt.db()).await?.iter() {
137					tmp.insert(v.name.to_string(), v.to_string().into());
138				}
139				res.insert("analyzers".to_owned(), tmp.into());
140				// Ok all good
141				Value::from(res).ok()
142			}
143			InfoStatement::Sc(sc) => {
144				// Allowed to run?
145				opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
146				// Claim transaction
147				let mut run = txn.lock().await;
148				// Create the result set
149				let mut res = Object::default();
150				// Process the tokens
151				let mut tmp = Object::default();
152				for v in run.all_sc_tokens(opt.ns(), opt.db(), sc).await?.iter() {
153					tmp.insert(v.name.to_string(), v.to_string().into());
154				}
155				res.insert("tokens".to_owned(), tmp.into());
156				// Ok all good
157				Value::from(res).ok()
158			}
159			InfoStatement::Tb(tb) => {
160				// Allowed to run?
161				opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
162				// Claim transaction
163				let mut run = txn.lock().await;
164				// Create the result set
165				let mut res = Object::default();
166				// Process the events
167				let mut tmp = Object::default();
168				for v in run.all_tb_events(opt.ns(), opt.db(), tb).await?.iter() {
169					tmp.insert(v.name.to_string(), v.to_string().into());
170				}
171				res.insert("events".to_owned(), tmp.into());
172				// Process the fields
173				let mut tmp = Object::default();
174				for v in run.all_tb_fields(opt.ns(), opt.db(), tb).await?.iter() {
175					tmp.insert(v.name.to_string(), v.to_string().into());
176				}
177				res.insert("fields".to_owned(), tmp.into());
178				// Process the tables
179				let mut tmp = Object::default();
180				for v in run.all_tb_views(opt.ns(), opt.db(), tb).await?.iter() {
181					tmp.insert(v.name.to_string(), v.to_string().into());
182				}
183				res.insert("tables".to_owned(), tmp.into());
184				// Process the indexes
185				let mut tmp = Object::default();
186				for v in run.all_tb_indexes(opt.ns(), opt.db(), tb).await?.iter() {
187					tmp.insert(v.name.to_string(), v.to_string().into());
188				}
189				res.insert("indexes".to_owned(), tmp.into());
190				// Process the live queries
191				let mut tmp = Object::default();
192				for v in run.all_tb_lives(opt.ns(), opt.db(), tb).await?.iter() {
193					tmp.insert(v.id.to_raw(), v.to_string().into());
194				}
195				res.insert("lives".to_owned(), tmp.into());
196				// Ok all good
197				Value::from(res).ok()
198			}
199			InfoStatement::User(user, base) => {
200				let base = base.clone().unwrap_or(opt.selected_base()?);
201				// Allowed to run?
202				opt.is_allowed(Action::View, ResourceKind::Actor, &base)?;
203
204				// Claim transaction
205				let mut run = txn.lock().await;
206				// Process the user
207				let res = match base {
208					Base::Root => run.get_root_user(user).await?,
209					Base::Ns => run.get_ns_user(opt.ns(), user).await?,
210					Base::Db => run.get_db_user(opt.ns(), opt.db(), user).await?,
211					_ => return Err(Error::InvalidLevel(base.to_string())),
212				};
213				// Ok all good
214				Value::from(res.to_string()).ok()
215			}
216		}
217	}
218}
219
220impl fmt::Display for InfoStatement {
221	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222		match self {
223			Self::Root => f.write_str("INFO FOR ROOT"),
224			Self::Ns => f.write_str("INFO FOR NAMESPACE"),
225			Self::Db => f.write_str("INFO FOR DATABASE"),
226			Self::Sc(ref s) => write!(f, "INFO FOR SCOPE {s}"),
227			Self::Tb(ref t) => write!(f, "INFO FOR TABLE {t}"),
228			Self::User(ref u, ref b) => match b {
229				Some(ref b) => write!(f, "INFO FOR USER {u} ON {b}"),
230				None => write!(f, "INFO FOR USER {u}"),
231			},
232		}
233	}
234}