mixtape_tools/sqlite/database/
close.rs1use crate::prelude::*;
4use crate::sqlite::error::SqliteToolError;
5use crate::sqlite::manager::DATABASE_MANAGER;
6
7#[derive(Debug, Deserialize, JsonSchema)]
9pub struct CloseDatabaseInput {
10 #[serde(default)]
12 pub db_path: Option<String>,
13}
14
15pub struct CloseDatabaseTool;
21
22impl Tool for CloseDatabaseTool {
23 type Input = CloseDatabaseInput;
24
25 fn name(&self) -> &str {
26 "sqlite_close_database"
27 }
28
29 fn description(&self) -> &str {
30 "Close an open SQLite database connection. Specify the database name/path, or omit to close the default database."
31 }
32
33 async fn execute(&self, input: Self::Input) -> Result<ToolResult, ToolError> {
34 let db_name = input.db_path.clone();
35
36 let result = tokio::task::spawn_blocking(move || {
37 let name = match &db_name {
38 Some(n) => n.as_str(),
39 None => {
40 DATABASE_MANAGER
41 .get_default()
42 .ok_or(SqliteToolError::NoDefaultDatabase)?
43 .as_str()
44 .to_string();
45 let default = DATABASE_MANAGER
47 .get_default()
48 .ok_or(SqliteToolError::NoDefaultDatabase)?;
49 return DATABASE_MANAGER.close(&default);
50 }
51 };
52 DATABASE_MANAGER.close(name)
53 })
54 .await
55 .map_err(|e| ToolError::Custom(format!("Task join error: {}", e)))?;
56
57 match result {
58 Ok(()) => {
59 let closed_name = input
60 .db_path
61 .unwrap_or_else(|| "default database".to_string());
62 let response = serde_json::json!({
63 "status": "success",
64 "message": format!("Database closed: {}", closed_name)
65 });
66 Ok(ToolResult::Json(response))
67 }
68 Err(e) => Err(e.into()),
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::sqlite::test_utils::TestDatabase;
77
78 #[tokio::test]
79 async fn test_close_database() {
80 let db = TestDatabase::new().await;
82 let db_key = db.key();
83
84 let close_tool = CloseDatabaseTool;
86 let close_input = CloseDatabaseInput {
87 db_path: Some(db_key.clone()),
88 };
89
90 let result = close_tool.execute(close_input).await;
91 assert!(result.is_ok());
92
93 assert!(!DATABASE_MANAGER.is_open(&db_key));
95
96 std::mem::forget(db);
98 }
99
100 #[test]
101 fn test_tool_metadata() {
102 let tool = CloseDatabaseTool;
103 assert_eq!(tool.name(), "sqlite_close_database");
104 assert!(!tool.description().is_empty());
105 }
106}