use nodedb_sql::ddl_ast::AlterTenantOperation;
use nodedb_types::QuotaRecord;
use crate::control::security::audit::AuditEvent;
use crate::control::security::identity::AuthenticatedIdentity;
use crate::control::state::SharedState;
use crate::types::TenantId;
use super::super::super::result::{DdlError, DdlResult};
use super::super::database::gate::require_tenant_admin;
use super::support::{ddl_err, status};
pub fn handle_alter_tenant_quota(
state: &SharedState,
identity: &AuthenticatedIdentity,
name: &str,
database: &str,
operation: &AlterTenantOperation,
) -> Result<Vec<DdlResult>, DdlError> {
require_tenant_admin(identity, "alter tenant quota")?;
let catalog = state.credentials.catalog();
let db_id = catalog
.get_database_id_by_name(database)
.map_err(|e| ddl_err("XX000", format!("catalog lookup failed: {e}")))?
.ok_or_else(|| ddl_err("3D000", format!("database '{database}' does not exist")))?;
let tenants = catalog
.load_all_tenants()
.map_err(|e| ddl_err("XX000", format!("tenant load failed: {e}")))?;
let tenant_id = tenants
.iter()
.find(|t| t.name == name)
.map(|t| TenantId::new(t.tenant_id))
.ok_or_else(|| ddl_err("42704", format!("tenant '{name}' does not exist")))?;
let AlterTenantOperation::SetQuota(spec) = operation;
let before = catalog
.get_tenant_quota(db_id, tenant_id)
.map_err(|e| ddl_err("XX000", format!("quota read failed: {e}")))?
.unwrap_or(QuotaRecord::DEFAULT);
let mut record = before.clone();
record.merge(spec);
catalog
.put_tenant_quota(db_id, tenant_id, &record)
.map_err(|e| ddl_err("53400", format!("{e}")))?;
state.audit_record(
AuditEvent::AdminAction,
Some(tenant_id),
&identity.username,
&format!(
"ALTER TENANT {name} IN DATABASE {database} SET QUOTA — before: [{}] — after: [{}]",
before.audit_summary(),
record.audit_summary()
),
);
Ok(status("ALTER TENANT"))
}