surrealdb_core/sql/statements/define/
namespace.rs1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::iam::{Action, ResourceKind};
6use crate::sql::statements::info::InfoStructure;
7use crate::sql::{Base, Ident, Object, Strand, Value};
8use derive::Store;
9use revision::revisioned;
10use serde::{Deserialize, Serialize};
11use std::fmt::{self, Display};
12
13#[revisioned(revision = 2)]
14#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
15#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
16#[non_exhaustive]
17pub struct DefineNamespaceStatement {
18 pub id: Option<u32>,
19 pub name: Ident,
20 pub comment: Option<Strand>,
21 #[revision(start = 2)]
22 pub if_not_exists: bool,
23}
24
25impl DefineNamespaceStatement {
26 pub(crate) async fn compute(
28 &self,
29 ctx: &Context<'_>,
30 opt: &Options,
31 _doc: Option<&CursorDoc<'_>>,
32 ) -> Result<Value, Error> {
33 opt.is_allowed(Action::Edit, ResourceKind::Namespace, &Base::Root)?;
35 let key = crate::key::root::ns::new(&self.name);
37 let mut run = ctx.tx_lock().await;
39 run.clear_cache();
41 if run.get_ns(&self.name).await.is_ok() {
43 if self.if_not_exists {
44 return Ok(Value::None);
45 } else {
46 return Err(Error::NsAlreadyExists {
47 value: self.name.to_string(),
48 });
49 }
50 }
51 if self.id.is_none() {
52 let ns = DefineNamespaceStatement {
54 id: Some(run.get_next_ns_id().await?),
55 if_not_exists: false,
56 ..self.clone()
57 };
58 run.set(key, ns).await?;
59 } else {
60 run.set(
61 key,
62 DefineNamespaceStatement {
63 if_not_exists: false,
64 ..self.clone()
65 },
66 )
67 .await?;
68 }
69 Ok(Value::None)
71 }
72}
73
74impl Display for DefineNamespaceStatement {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 write!(f, "DEFINE NAMESPACE")?;
77 if self.if_not_exists {
78 write!(f, " IF NOT EXISTS")?
79 }
80 write!(f, " {}", self.name)?;
81 if let Some(ref v) = self.comment {
82 write!(f, " COMMENT {v}")?
83 }
84 Ok(())
85 }
86}
87
88impl InfoStructure for DefineNamespaceStatement {
89 fn structure(self) -> Value {
90 let Self {
91 name,
92 comment,
93 ..
94 } = self;
95 let mut acc = Object::default();
96
97 acc.insert("name".to_string(), name.structure());
98
99 if let Some(comment) = comment {
100 acc.insert("comment".to_string(), comment.into());
101 }
102
103 Value::Object(acc)
104 }
105}