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 #[cfg(not(target_family = "wasm"))]
37 ctx.get_index_stores()
38 .table_removed(ctx.get_index_builder(), &txn, ns, db, &self.name)
39 .await?;
40 #[cfg(target_family = "wasm")]
41 ctx.get_index_stores().table_removed(&txn, ns, db, &self.name).await?;
42 let tb = txn.get_tb(ns, db, &self.name).await?;
44 let fts = txn.all_tb_views(ns, db, &self.name).await?;
46 let key = crate::key::database::tb::new(ns, db, &self.name);
48 match self.expunge {
49 true => txn.clr(key).await?,
50 false => txn.del(key).await?,
51 };
52 let key = crate::key::table::all::new(ns, db, &self.name);
54 match self.expunge {
55 true => txn.clrp(key).await?,
56 false => txn.delp(key).await?,
57 };
58 for ft in fts.iter() {
60 let key = crate::key::database::tb::new(ns, db, &ft.name);
62 let tb = txn.get_tb(ns, db, &ft.name).await?;
63 txn.set(
64 key,
65 revision::to_vec(&DefineTableStatement {
66 view: None,
67 ..tb.as_ref().clone()
68 })?,
69 None,
70 )
71 .await?;
72 if let Some(cache) = ctx.get_cache() {
74 cache.clear_tb(ns, db, &ft.name);
75 }
76 }
77 if let Some(view) = &tb.view {
79 for ft in view.what.0.iter() {
81 let key = crate::key::table::ft::new(ns, db, ft, &self.name);
83 txn.del(key).await?;
84 let key = crate::key::database::tb::new(ns, db, ft);
86 let tb = txn.get_tb(ns, db, ft).await?;
87 txn.set(
88 key,
89 revision::to_vec(&DefineTableStatement {
90 cache_tables_ts: Uuid::now_v7(),
91 ..tb.as_ref().clone()
92 })?,
93 None,
94 )
95 .await?;
96 }
97 }
98 if let Some(cache) = ctx.get_cache() {
100 cache.clear_tb(ns, db, &self.name);
101 }
102 txn.clear();
104 Ok(Value::None)
106 }
107 .await;
108 match future {
109 Err(Error::TbNotFound {
110 ..
111 }) if self.if_exists => Ok(Value::None),
112 v => v,
113 }
114 }
115}
116
117impl Display for RemoveTableStatement {
118 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
119 write!(f, "REMOVE TABLE")?;
120 if self.if_exists {
121 write!(f, " IF EXISTS")?
122 }
123 write!(f, " {}", self.name)?;
124 Ok(())
125 }
126}