use anyhow::{Context, Result, anyhow}; use std::fs; use std::path::PathBuf; use crate::db; use crate::config; use clap::Command; use clap::error::ErrorKind; use log::{debug, warn}; use rusqlite::Connection; pub fn mode_delete( cmd: &mut Command, _settings: &config::Settings, _config: &config::Settings, ids: &mut Vec, tags: &mut Vec, conn: &mut Connection, data_path: PathBuf, ) -> Result<()> { if ids.is_empty() { cmd.error( ErrorKind::InvalidValue, "No ID given, you must supply atleast one ID when using --delete", ) .exit(); } else if !tags.is_empty() { cmd.error( ErrorKind::InvalidValue, "Tags given but not supported, you must supply atleast one ID when using --delete", ) .exit(); } for item_id in ids.iter() { if let Some(item) = db::get_item(conn, *item_id)? { debug!("MAIN: Found item {:?}", item); db::delete_item(conn, item)?; // Validate that item ID is positive to prevent path traversal issues if *item_id <= 0 { return Err(anyhow!("Invalid item ID: {}", item_id)); } let mut item_path = data_path.clone(); item_path.push(item_id.to_string()); fs::remove_file(&item_path) .context(anyhow!("Unable to remove item file {:?}", item_path))?; } else { warn!("Unable to find item {item_id} in database"); } } Ok(()) }