use nodedb_types::DatabaseId;
use serde_json::{Map, Value as JsonValue};
use crate::control::security::identity::AuthenticatedIdentity;
use crate::control::server::response_shape::types::{DdlColType, ShapedRows};
use crate::control::state::SharedState;
use super::super::super::result::{DdlError, DdlResult};
use super::support::ddl_err;
pub fn handle_show_storage(
state: &SharedState,
identity: &AuthenticatedIdentity,
parts: &[&str],
) -> Result<Vec<DdlResult>, DdlError> {
let collection = parts
.get(3)
.ok_or_else(|| ddl_err("42601", "syntax: SHOW STORAGE FOR <collection>"))?
.to_lowercase();
let tenant_id = identity.tenant_id.as_u64();
if state
.credentials
.catalog()
.get_collection(DatabaseId::DEFAULT, tenant_id, &collection)
.ok()
.flatten()
.is_none()
{
return Err(ddl_err(
"42P01",
format!("collection \"{collection}\" does not exist"),
));
}
let stats = state
.credentials
.catalog()
.load_column_stats(tenant_id, &collection)
.ok()
.unwrap_or_default();
let columns = vec![
"collection".to_string(),
"columns".to_string(),
"row_count".to_string(),
"last_analyzed".to_string(),
];
let column_types = vec![DdlColType::Text; 4];
let row_count = stats.first().map(|s| s.row_count).unwrap_or(0);
let last_analyzed = stats
.first()
.map(|s| {
if s.analyzed_at > 0 {
format!("{}ms ago", now_ms().saturating_sub(s.analyzed_at))
} else {
"never".to_string()
}
})
.unwrap_or_else(|| "never".to_string());
let mut row = Map::new();
row.insert(
"collection".to_string(),
JsonValue::String(collection.clone()),
);
row.insert(
"columns".to_string(),
JsonValue::String(stats.len().to_string()),
);
row.insert(
"row_count".to_string(),
JsonValue::String(row_count.to_string()),
);
row.insert(
"last_analyzed".to_string(),
JsonValue::String(last_analyzed),
);
Ok(vec![DdlResult::Rows(ShapedRows {
columns,
column_types,
rows: vec![row],
notice: None,
})])
}
pub fn handle_show_compaction_status(
_state: &SharedState,
_identity: &AuthenticatedIdentity,
) -> Result<Vec<DdlResult>, DdlError> {
let columns = vec![
"status".to_string(),
"pending_jobs".to_string(),
"compaction_debt".to_string(),
];
let column_types = vec![DdlColType::Text; 3];
let mut row = Map::new();
row.insert("status".to_string(), JsonValue::String("idle".to_string()));
row.insert(
"pending_jobs".to_string(),
JsonValue::String("0".to_string()),
);
row.insert(
"compaction_debt".to_string(),
JsonValue::String("0".to_string()),
);
Ok(vec![DdlResult::Rows(ShapedRows {
columns,
column_types,
rows: vec![row],
notice: None,
})])
}
fn now_ms() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}