surrealdb_core/sql/statements/remove/
table.rs1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::err::Error;
4use crate::iam::{Action, ResourceKind};
5use crate::sql::statements::define::DefineTableStatement;
6use crate::sql::{Base, Ident, Value};
7
8use revision::revisioned;
9use serde::{Deserialize, Serialize};
10use std::fmt::{self, Display, Formatter};
11use uuid::Uuid;
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 RemoveTableStatement {
18 pub name: Ident,
19 #[revision(start = 2)]
20 pub if_exists: bool,
21 #[revision(start = 3)]
22 pub expunge: bool,
23}
24
25impl RemoveTableStatement {
26 pub(crate) async fn compute(&self, ctx: &Context, opt: &Options) -> Result<Value, Error> {
28 let future = async {
29 opt.is_allowed(Action::Edit, ResourceKind::Table, &Base::Db)?;
31 let (ns, db) = opt.ns_db()?;
33 let txn = ctx.tx();
35 ctx.get_index_stores()
37 .table_removed(ctx.get_index_builder(), &txn, ns, db, &self.name)
38 .await?;
39 let tb = txn.get_tb(ns, db, &self.name).await?;
41 let fts = txn.all_tb_views(ns, db, &self.name).await?;
43 let key = crate::key::database::tb::new(ns, db, &self.name);
45 match self.expunge {
46 true => txn.clr(key).await?,
47 false => txn.del(key).await?,
48 };
49 let key = crate::key::table::all::new(ns, db, &self.name);
51 match self.expunge {
52 true => txn.clrp(key).await?,
53 false => txn.delp(key).await?,
54 };
55 for ft in fts.iter() {
57 let key = crate::key::database::tb::new(ns, db, &ft.name);
59 let tb = txn.get_tb(ns, db, &ft.name).await?;
60 txn.set(
61 key,
62 revision::to_vec(&DefineTableStatement {
63 view: None,
64 ..tb.as_ref().clone()
65 })?,
66 None,
67 )
68 .await?;
69 if let Some(cache) = ctx.get_cache() {
71 cache.clear_tb(ns, db, &ft.name);
72 }
73 }
74 if let Some(view) = &tb.view {
76 for ft in view.what.0.iter() {
78 let key = crate::key::table::ft::new(ns, db, ft, &self.name);
80 txn.del(key).await?;
81 let key = crate::key::database::tb::new(ns, db, ft);
83 let tb = txn.get_tb(ns, db, ft).await?;
84 txn.set(
85 key,
86 revision::to_vec(&DefineTableStatement {
87 cache_tables_ts: Uuid::now_v7(),
88 ..tb.as_ref().clone()
89 })?,
90 None,
91 )
92 .await?;
93 }
94 }
95 if let Some(cache) = ctx.get_cache() {
97 cache.clear_tb(ns, db, &self.name);
98 }
99 txn.clear();
101 Ok(Value::None)
103 }
104 .await;
105 match future {
106 Err(Error::TbNotFound {
107 ..
108 }) if self.if_exists => Ok(Value::None),
109 v => v,
110 }
111 }
112}
113
114impl Display for RemoveTableStatement {
115 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
116 write!(f, "REMOVE TABLE")?;
117 if self.if_exists {
118 write!(f, " IF EXISTS")?
119 }
120 write!(f, " {}", self.name)?;
121 Ok(())
122 }
123}