surrealdb_core/expr/statements/remove/
index.rs

1use std::fmt::{self, Display, Formatter};
2
3use anyhow::Result;
4use revision::revisioned;
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7
8use crate::catalog::TableDefinition;
9use crate::ctx::Context;
10use crate::dbs::Options;
11use crate::err::Error;
12use crate::expr::{Base, Ident, Value};
13use crate::iam::{Action, ResourceKind};
14
15#[revisioned(revision = 1)]
16#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
17pub struct RemoveIndexStatement {
18	pub name: Ident,
19	pub what: Ident,
20	pub if_exists: bool,
21}
22
23impl RemoveIndexStatement {
24	/// Process this type returning a computed simple Value
25	pub(crate) async fn compute(&self, ctx: &Context, opt: &Options) -> Result<Value> {
26		// Allowed to run?
27		opt.is_allowed(Action::Edit, ResourceKind::Index, &Base::Db)?;
28		// Get the NS and DB
29		let (ns, db) = ctx.expect_ns_db_ids(opt).await?;
30		// Get the transaction
31		let txn = ctx.tx();
32		// Clear the index store cache
33		#[cfg(not(target_family = "wasm"))]
34		let err = ctx
35			.get_index_stores()
36			.index_removed(ctx.get_index_builder(), &txn, ns, db, &self.what, &self.name)
37			.await;
38		#[cfg(target_family = "wasm")]
39		let err = ctx.get_index_stores().index_removed(&txn, ns, db, &self.what, &self.name).await;
40
41		if let Err(e) = err {
42			if self.if_exists && matches!(e.downcast_ref(), Some(Error::IxNotFound { .. })) {
43				return Ok(Value::None);
44			}
45			return Err(e);
46		}
47
48		// Delete the definition
49		let key = crate::key::table::ix::new(ns, db, &self.what, &self.name);
50		txn.del(&key).await?;
51		// Remove the index data
52		let key = crate::key::index::all::new(ns, db, &self.what, &self.name);
53		txn.delp(&key).await?;
54		// Refresh the table cache for indexes
55		let key = crate::key::database::tb::new(ns, db, &self.what);
56		let Some(tb) = txn.get_tb(ns, db, &self.what).await? else {
57			return Err(Error::TbNotFound {
58				name: self.what.to_string(),
59			}
60			.into());
61		};
62
63		txn.set(
64			&key,
65			&TableDefinition {
66				cache_indexes_ts: Uuid::now_v7(),
67				..tb.as_ref().clone()
68			},
69			None,
70		)
71		.await?;
72		// Clear the cache
73		if let Some(cache) = ctx.get_cache() {
74			cache.clear_tb(ns, db, &self.what);
75		}
76		// Clear the cache
77		txn.clear_cache();
78		// Ok all good
79		Ok(Value::None)
80	}
81}
82
83impl Display for RemoveIndexStatement {
84	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
85		write!(f, "REMOVE INDEX")?;
86		if self.if_exists {
87			write!(f, " IF EXISTS")?
88		}
89		write!(f, " {} ON {}", self.name, self.what)?;
90		Ok(())
91	}
92}