Files
komp_ac/server/src/table_definition/handlers/delete_table.rs
2025-06-21 09:57:14 +02:00

94 lines
3.2 KiB
Rust

// src/table_definition/handlers/delete_table.rs
use tonic::Status;
use sqlx::PgPool;
use common::proto::multieko2::table_definition::{DeleteTableRequest, DeleteTableResponse};
pub async fn delete_table(
db_pool: &PgPool,
request: DeleteTableRequest,
) -> Result<DeleteTableResponse, Status> {
let mut transaction = db_pool.begin().await
.map_err(|e| Status::internal(format!("Failed to start transaction: {}", e)))?;
// Step 1: Get schema and validate existence
let schema = sqlx::query!(
"SELECT id, name FROM schemas WHERE name = $1",
request.profile_name
)
.fetch_optional(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Schema lookup failed: {}", e)))?;
let (schema_id, schema_name) = match schema {
Some(s) => (s.id, s.name),
None => return Err(Status::not_found("Profile not found")),
};
// Step 2: Get table definition and validate existence
let table_def = sqlx::query!(
"SELECT id FROM table_definitions
WHERE schema_id = $1 AND table_name = $2",
schema_id,
request.table_name
)
.fetch_optional(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Table lookup failed: {}", e)))?;
let table_def_id = match table_def {
Some(t) => t.id,
None => return Err(Status::not_found("Table not found in profile")),
};
// Step 3: Drop the actual PostgreSQL table with CASCADE (schema-qualified)
let drop_table_sql = format!(r#"DROP TABLE IF EXISTS "{}"."{}" CASCADE"#, schema_name, request.table_name);
sqlx::query(&drop_table_sql)
.execute(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Table drop failed: {}", e)))?;
// Step 4: Delete from table_definitions
sqlx::query!(
"DELETE FROM table_definitions WHERE id = $1",
table_def_id
)
.execute(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Definition deletion failed: {}", e)))?;
// Step 5: Check and clean up schema if empty
let remaining = sqlx::query!(
"SELECT COUNT(*) as count FROM table_definitions WHERE schema_id = $1",
schema_id
)
.fetch_one(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Count query failed: {}", e)))?;
if remaining.count.unwrap_or(1) == 0 {
// Drop the PostgreSQL schema if empty
let drop_schema_sql = format!(r#"DROP SCHEMA IF EXISTS "{}" CASCADE"#, schema_name);
sqlx::query(&drop_schema_sql)
.execute(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Schema drop failed: {}", e)))?;
// Delete the schema record
sqlx::query!(
"DELETE FROM schemas WHERE id = $1",
schema_id
)
.execute(&mut *transaction)
.await
.map_err(|e| Status::internal(format!("Schema cleanup failed: {}", e)))?;
}
transaction.commit().await
.map_err(|e| Status::internal(format!("Transaction commit failed: {}", e)))?;
Ok(DeleteTableResponse {
success: true,
message: format!("Table '{}' and its definition were successfully removed", request.table_name),
})
}