use super::system::AppState;
use crate::error::DbError;
use axum::{
extract::{Path, State},
http::StatusCode,
response::Json,
};
use serde::{Deserialize, Serialize};
fn default_validation_mode() -> String {
"off".to_string()
}
#[derive(Debug, Deserialize)]
pub struct SetSchemaRequest {
pub schema: serde_json::Value,
#[serde(rename = "validationMode", default = "default_validation_mode")]
pub validation_mode: String,
}
#[derive(Debug, Serialize)]
pub struct SchemaResponse {
pub schema: Option<serde_json::Value>,
#[serde(rename = "validationMode")]
pub validation_mode: String,
pub collection: String,
}
pub async fn set_collection_schema(
State(state): State<AppState>,
Path((db_name, coll_name)): Path<(String, String)>,
Json(req): Json<SetSchemaRequest>,
) -> Result<Json<SchemaResponse>, DbError> {
let database = state.storage.get_database(&db_name)?;
let collection = database.get_collection(&coll_name)?;
let validation_mode = match req.validation_mode.to_lowercase().as_str() {
"strict" => crate::storage::schema::SchemaValidationMode::Strict,
"lenient" => crate::storage::schema::SchemaValidationMode::Lenient,
_ => crate::storage::schema::SchemaValidationMode::Off,
};
let schema_clone = req.schema.clone();
collection.set_json_schema(crate::storage::schema::CollectionSchema::new(
"default".to_string(),
req.schema,
validation_mode,
))?;
Ok(Json(SchemaResponse {
schema: Some(schema_clone),
validation_mode: req.validation_mode.clone(),
collection: coll_name,
}))
}
pub async fn get_collection_schema(
State(state): State<AppState>,
Path((db_name, coll_name)): Path<(String, String)>,
) -> Result<Json<SchemaResponse>, DbError> {
let database = state.storage.get_database(&db_name)?;
let collection = database.get_collection(&coll_name)?;
let schema = collection.get_json_schema();
let (schema_value, validation_mode) = if let Some(s) = schema {
let mode_str = match s.validation_mode {
crate::storage::schema::SchemaValidationMode::Strict => "strict".to_string(),
crate::storage::schema::SchemaValidationMode::Lenient => "lenient".to_string(),
crate::storage::schema::SchemaValidationMode::Off => "off".to_string(),
};
(Some(s.schema.clone()), mode_str)
} else {
(None, "off".to_string())
};
Ok(Json(SchemaResponse {
schema: schema_value,
validation_mode,
collection: coll_name,
}))
}
pub async fn delete_collection_schema(
State(state): State<AppState>,
Path((db_name, coll_name)): Path<(String, String)>,
) -> Result<StatusCode, DbError> {
let database = state.storage.get_database(&db_name)?;
let collection = database.get_collection(&coll_name)?;
collection.remove_json_schema()?;
Ok(StatusCode::NO_CONTENT)
}