94 lines
3.2 KiB
Rust
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),
|
|
})
|
|
}
|