use axum::{
extract::{Path, Query, State},
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use chrono::{DateTime, Utc};
use kyma_core::catalog::{Catalog, CleanupResult};
use kyma_core::errors::{CatalogError, Error as KymaError};
use serde::Deserialize;
use std::sync::Arc;
#[derive(Clone)]
pub struct CleanupState {
pub catalog: Arc<dyn Catalog>,
}
#[derive(Debug, Deserialize)]
pub struct CleanupQuery {
pub before: DateTime<Utc>,
}
pub async fn cleanup_table(
State(state): State<CleanupState>,
Path((db, table)): Path<(String, String)>,
Query(q): Query<CleanupQuery>,
) -> Result<Json<CleanupResult>, ApiError> {
let result = state
.catalog
.cleanup_soft_deleted_extents(&db, &table, q.before)
.await?;
Ok(Json(result))
}
#[derive(Debug)]
pub enum ApiError {
Catalog(KymaError),
}
impl From<KymaError> for ApiError {
fn from(e: KymaError) -> Self {
ApiError::Catalog(e)
}
}
impl IntoResponse for ApiError {
fn into_response(self) -> Response {
match self {
ApiError::Catalog(KymaError::Catalog(CatalogError::TableNotFound {
database,
name,
})) => (
StatusCode::NOT_FOUND,
Json(serde_json::json!({
"error": format!("table '{database}'.'{name}' not found")
})),
)
.into_response(),
ApiError::Catalog(e) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(serde_json::json!({ "error": e.to_string() })),
)
.into_response(),
}
}
}