// src/tables_data/handlers/delete_table_data.rs use tonic::Status; use sqlx::PgPool; use common::proto::multieko2::tables_data::{DeleteTableDataRequest, DeleteTableDataResponse}; use crate::shared::schema_qualifier::qualify_table_name_for_data; // Import schema qualifier pub async fn delete_table_data( db_pool: &PgPool, request: DeleteTableDataRequest, ) -> Result { // Lookup profile let profile = sqlx::query!( "SELECT id FROM profiles WHERE name = $1", request.profile_name ) .fetch_optional(db_pool) .await .map_err(|e| Status::internal(format!("Profile lookup error: {}", e)))?; let profile_id = match profile { Some(p) => p.id, None => return Err(Status::not_found("Profile not found")), }; // Verify table exists in profile let table_exists = sqlx::query!( "SELECT 1 AS exists FROM table_definitions WHERE profile_id = $1 AND table_name = $2", profile_id, request.table_name ) .fetch_optional(db_pool) .await .map_err(|e| Status::internal(format!("Table verification error: {}", e)))?; if table_exists.is_none() { return Err(Status::not_found("Table not found in profile")); } // Qualify table name with schema let qualified_table = qualify_table_name_for_data(&request.table_name)?; // Perform soft delete using qualified table name let query = format!( "UPDATE {} SET deleted = true WHERE id = $1 AND deleted = false", qualified_table ); let result = sqlx::query(&query) .bind(request.record_id) .execute(db_pool) .await; let rows_affected = match result { Ok(result) => result.rows_affected(), Err(e) => { // Handle "relation does not exist" error specifically if let Some(db_err) = e.as_database_error() { if db_err.code() == Some(std::borrow::Cow::Borrowed("42P01")) { return Err(Status::internal(format!( "Table '{}' is defined but does not physically exist in the database as {}", request.table_name, qualified_table ))); } } return Err(Status::internal(format!("Delete operation failed: {}", e))); } }; Ok(DeleteTableDataResponse { success: rows_affected > 0, }) }