dbmcp_postgres/tools/
drop_table.rs1use dbmcp_server::types::MessageResponse;
4use dbmcp_sql::SqlError;
5
6use super::prelude::*;
7use crate::connection::quote_ident;
8use crate::types::DropTableRequest;
9
10const NAME: &str = "dropTable";
11const TITLE: &str = "Drop Table";
12const DESCRIPTION_PINNED: &str = include_str!("../../assets/tools/drop_table/pinned.md");
13const DESCRIPTION_UNPINNED: &str = include_str!("../../assets/tools/drop_table/unpinned.md");
14
15fn annotations() -> ToolAnnotations {
16 ToolAnnotations::new()
17 .read_only(false)
18 .destructive(true)
19 .idempotent(false)
20 .open_world(false)
21}
22
23pub(crate) struct PinnedDropTableTool;
25
26impl ToolBase for PinnedDropTableTool {
27 type Parameter = DropTableRequest;
28 type Output = MessageResponse;
29 type Error = ErrorData;
30
31 fn name() -> Cow<'static, str> {
32 NAME.into()
33 }
34
35 fn title() -> Option<String> {
36 Some(TITLE.into())
37 }
38
39 fn description() -> Option<Cow<'static, str>> {
40 Some(DESCRIPTION_PINNED.into())
41 }
42
43 fn annotations() -> Option<ToolAnnotations> {
44 Some(annotations())
45 }
46
47 fn input_schema() -> Option<Arc<JsonObject>> {
48 Some(input_schema::<Self::Parameter>(true))
49 }
50
51 fn output_schema() -> Option<Arc<JsonObject>> {
52 Some(output_schema::<Self::Output>())
53 }
54}
55
56impl AsyncTool<PostgresHandler> for PinnedDropTableTool {
57 async fn invoke(handler: &PostgresHandler, params: Self::Parameter) -> Result<Self::Output, Self::Error> {
58 handler.drop_table(None, params.table, params.cascade).await
59 }
60}
61
62pub(crate) struct UnpinnedDropTableTool;
64
65impl ToolBase for UnpinnedDropTableTool {
66 type Parameter = DropTableRequest;
67 type Output = MessageResponse;
68 type Error = ErrorData;
69
70 fn name() -> Cow<'static, str> {
71 NAME.into()
72 }
73
74 fn title() -> Option<String> {
75 Some(TITLE.into())
76 }
77
78 fn description() -> Option<Cow<'static, str>> {
79 Some(DESCRIPTION_UNPINNED.into())
80 }
81
82 fn annotations() -> Option<ToolAnnotations> {
83 Some(annotations())
84 }
85
86 fn input_schema() -> Option<Arc<JsonObject>> {
87 Some(input_schema::<Self::Parameter>(false))
88 }
89
90 fn output_schema() -> Option<Arc<JsonObject>> {
91 Some(output_schema::<Self::Output>())
92 }
93}
94
95impl AsyncTool<PostgresHandler> for UnpinnedDropTableTool {
96 async fn invoke(handler: &PostgresHandler, params: Self::Parameter) -> Result<Self::Output, Self::Error> {
97 handler.drop_table(params.database, params.table, params.cascade).await
98 }
99}
100
101impl PostgresHandler {
102 pub async fn drop_table(
114 &self,
115 database: Option<String>,
116 table: String,
117 cascade: bool,
118 ) -> Result<MessageResponse, ErrorData> {
119 if self.config.read_only {
120 return Err(SqlError::ReadOnlyViolation.into());
121 }
122
123 let database = database.as_deref().map(str::trim).filter(|s| !s.is_empty());
124
125 let mut drop_sql = format!("DROP TABLE {}", quote_ident(&table));
126 if cascade {
127 drop_sql.push_str(" CASCADE");
128 }
129
130 self.connection.execute(drop_sql.as_str(), database).await?;
131
132 Ok(MessageResponse {
133 message: format!("Table '{table}' dropped successfully."),
134 })
135 }
136}