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, Strand, Value};
8
9use revision::revisioned;
10use serde::{Deserialize, Serialize};
11use std::fmt::{self, Display};
12
13#[revisioned(revision = 3)]
14#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, 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 #[revision(start = 3)]
24 pub overwrite: bool,
25}
26
27impl DefineNamespaceStatement {
28 pub(crate) async fn compute(
30 &self,
31 ctx: &Context,
32 opt: &Options,
33 _doc: Option<&CursorDoc>,
34 ) -> Result<Value, Error> {
35 opt.is_allowed(Action::Edit, ResourceKind::Namespace, &Base::Root)?;
37 let txn = ctx.tx();
39 if txn.get_ns(&self.name).await.is_ok() {
41 if self.if_not_exists {
42 return Ok(Value::None);
43 } else if !self.overwrite {
44 return Err(Error::NsAlreadyExists {
45 name: self.name.to_string(),
46 });
47 }
48 }
49 let key = crate::key::root::ns::new(&self.name);
51 txn.set(
52 key,
53 revision::to_vec(&DefineNamespaceStatement {
54 id: if self.id.is_none() {
55 Some(txn.lock().await.get_next_ns_id().await?)
56 } else {
57 None
58 },
59 if_not_exists: false,
61 overwrite: false,
62 ..self.clone()
63 })?,
64 None,
65 )
66 .await?;
67 txn.clear();
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 if self.overwrite {
81 write!(f, " OVERWRITE")?
82 }
83 write!(f, " {}", self.name)?;
84 if let Some(ref v) = self.comment {
85 write!(f, " COMMENT {v}")?
86 }
87 Ok(())
88 }
89}
90
91impl InfoStructure for DefineNamespaceStatement {
92 fn structure(self) -> Value {
93 Value::from(map! {
94 "name".to_string() => self.name.structure(),
95 "comment".to_string(), if let Some(v) = self.comment => v.into(),
96 })
97 }
98}