Skip to main content

surrealdb_expr/expr/statements/
info.rs

1use std::sync::Arc;
2
3use crate::expr::{Base, Expr};
4use crate::val::{Object, Value};
5
6#[derive(Clone, Debug, Eq, PartialEq, Hash)]
7pub enum InfoStatement {
8	/// Root information
9	Root(bool, Option<Expr>),
10	/// Namespace information
11	Ns(bool, Option<Expr>),
12	/// Database information
13	Db(bool, Option<Expr>),
14	/// Table information
15	Tb(Expr, bool, Option<Expr>),
16
17	User(Expr, Option<Base>, bool),
18	/// Index information
19	Index(Expr, Expr, bool),
20}
21impl InfoStatement {
22	/// Whether evaluating this statement does only reads.
23	///
24	/// `INFO` reads catalog metadata, but its subject and `VERSION` clause are
25	/// expressions the statement evaluates first, so a write reaches the
26	/// transaction through them.
27	pub fn read_only(&self) -> bool {
28		match self {
29			InfoStatement::Root(_, version)
30			| InfoStatement::Ns(_, version)
31			| InfoStatement::Db(_, version) => version.as_ref().is_none_or(|version| version.read_only()),
32			InfoStatement::Tb(table, _, version) => {
33				table.read_only() && version.as_ref().is_none_or(|version| version.read_only())
34			}
35			InfoStatement::User(user, _, _) => user.read_only(),
36			InfoStatement::Index(index, table, _) => index.read_only() && table.read_only(),
37		}
38	}
39}
40
41pub trait InfoStructure {
42	fn structure(self) -> Value;
43}
44
45impl InfoStructure for surrealdb_cnf::DynamicConfiguration {
46	/// Expose the dynamic configuration as a value for the `INFO` statement.
47	fn structure(self) -> Value {
48		let object = map! {
49			"QUERY_TIMEOUT" => match self.get_query_timeout() {
50				None => Value::None,
51				Some(d) => d.into(),
52			}
53		};
54		Value::Object(Object::from(object))
55	}
56}
57
58pub fn process<T>(a: &Arc<[T]>) -> Value
59where
60	T: InfoStructure + Clone,
61{
62	Value::Array(a.iter().cloned().map(InfoStructure::structure).collect())
63}