use crate::control::server::response_shape::types::{DdlColType, ShapedRows};
use crate::control::state::SharedState;
use crate::types::TenantId;
use super::super::super::result::{DdlError, DdlResult};
pub(super) fn ddl_err(sqlstate: &str, message: impl Into<String>) -> DdlError {
DdlError {
sqlstate: sqlstate.to_string(),
message: message.into(),
}
}
pub(super) fn status(command: &str) -> Vec<DdlResult> {
vec![DdlResult::Status {
command: command.to_string(),
rows_affected: None,
}]
}
pub(super) fn text_rows(
columns: Vec<String>,
rows: Vec<serde_json::Map<String, serde_json::Value>>,
) -> Vec<DdlResult> {
let column_types = vec![DdlColType::Text; columns.len()];
vec![DdlResult::Rows(ShapedRows {
columns,
column_types,
rows,
notice: None,
})]
}
pub(super) fn resolve_tenant_ref(
state: &SharedState,
token: &str,
) -> Result<Option<TenantId>, DdlError> {
if let Ok(id) = token.parse::<u64>() {
return Ok(Some(TenantId::new(id)));
}
let name = token.trim_matches('\'');
if name.is_empty() {
return Err(ddl_err(
"42601",
"TENANT reference must be a numeric id or a tenant name",
));
}
let catalog = state.credentials.catalog();
Ok(catalog
.find_tenant_by_name(name)
.map_err(|e| ddl_err("XX000", format!("catalog read: {e}")))?
.map(|stored| TenantId::new(stored.tenant_id)))
}
pub(super) fn tenant_exists(state: &SharedState, tenant_id: TenantId) -> Result<bool, DdlError> {
let catalog = state.credentials.catalog();
let present = catalog
.load_all_tenants()
.map_err(|e| ddl_err("XX000", format!("catalog read: {e}")))?
.iter()
.any(|t| t.tenant_id == tenant_id.as_u64());
Ok(present)
}