dynoxide/actions/
delete_table.rs1use crate::actions::{TableDescription, build_table_description};
2use crate::errors::{DynoxideError, Result};
3use crate::storage::Storage;
4use crate::types::{GlobalSecondaryIndex, LocalSecondaryIndex};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Default, Deserialize)]
9struct DeleteTableRequestRaw {
10 #[serde(rename = "TableName", default)]
11 table_name: Option<String>,
12}
13
14#[derive(Debug, Default)]
15pub struct DeleteTableRequest {
16 pub table_name: String,
17}
18
19impl<'de> serde::Deserialize<'de> for DeleteTableRequest {
20 fn deserialize<D: serde::Deserializer<'de>>(
21 deserializer: D,
22 ) -> std::result::Result<Self, D::Error> {
23 let raw = DeleteTableRequestRaw::deserialize(deserializer)?;
24
25 if raw.table_name.is_none() {
26 return Err(serde::de::Error::custom(
27 "VALIDATION:The parameter 'TableName' is required but was not present in the request",
28 ));
29 }
30 let table_name = raw.table_name.unwrap();
31
32 if table_name.len() < 3 || table_name.len() > 255 {
34 return Err(serde::de::Error::custom(
35 "VALIDATION:TableName must be at least 3 characters long and at most 255 characters long",
36 ));
37 }
38
39 if !table_name
41 .chars()
42 .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-' || c == '.')
43 {
44 return Err(serde::de::Error::custom(format!(
45 "VALIDATION:1 validation error detected: \
46 Value '{}' at 'tableName' failed to satisfy constraint: \
47 Member must satisfy regular expression pattern: [a-zA-Z0-9_.-]+",
48 table_name
49 )));
50 }
51
52 Ok(DeleteTableRequest { table_name })
53 }
54}
55
56#[derive(Debug, Default, Serialize)]
57pub struct DeleteTableResponse {
58 #[serde(rename = "TableDescription")]
59 pub table_description: TableDescription,
60}
61
62pub fn execute(storage: &Storage, request: DeleteTableRequest) -> Result<DeleteTableResponse> {
63 crate::validation::validate_table_name(&request.table_name)?;
65
66 let meta = storage
68 .get_table_metadata(&request.table_name)?
69 .ok_or_else(|| {
70 DynoxideError::ResourceNotFoundException(format!(
71 "Requested resource not found: Table: {} not found",
72 request.table_name
73 ))
74 })?;
75
76 if meta.deletion_protection_enabled {
78 return Err(DynoxideError::ValidationException(format!(
79 "Resource {} can't be deleted because deletion protection is enabled",
80 crate::streams::table_arn(&request.table_name)
81 )));
82 }
83
84 if let Some(ref gsi_json) = meta.gsi_definitions {
86 if let Ok(gsis) = serde_json::from_str::<Vec<GlobalSecondaryIndex>>(gsi_json) {
87 for gsi in &gsis {
88 storage.drop_gsi_table(&request.table_name, &gsi.index_name)?;
89 }
90 }
91 }
92
93 if let Some(ref lsi_json) = meta.lsi_definitions {
95 if let Ok(lsis) = serde_json::from_str::<Vec<LocalSecondaryIndex>>(lsi_json) {
96 for lsi in &lsis {
97 storage.drop_lsi_table(&request.table_name, &lsi.index_name)?;
98 }
99 }
100 }
101
102 storage.drop_data_table(&request.table_name)?;
104
105 storage.delete_table_metadata(&request.table_name)?;
107
108 let mut desc = build_table_description(&meta, Some(0), Some(0));
110 desc.table_status = "DELETING".to_string();
111
112 Ok(DeleteTableResponse {
113 table_description: desc,
114 })
115}