use dashmap::DashMap;
use serde_json::Value;
use std::sync::Arc;
use crate::engine::types::{DbError, LogEntry};
use crate::engine::storage::StorageBackend;
use tokio::sync::broadcast;
use jsonschema::Validator;
pub fn set_schema(
schemas: &DashMap<String, Arc<(Value, Validator)>>,
storage: &Arc<dyn StorageBackend>,
tx: &broadcast::Sender<String>,
collection: &str,
schema: Value,
) -> Result<(), DbError> {
let validator = jsonschema::validator_for(&schema)
.map_err(|e| DbError::SchemaValidationError(format!("Invalid schema: {}", e)))?;
let tx_id = uuid::Uuid::new_v4().to_string();
storage.write_entry(&LogEntry::new(
"TX_BEGIN".into(),
collection.into(),
tx_id.clone(),
Value::Null,
))?;
storage.write_entry(&LogEntry::new(
"SCHEMA".to_string(),
collection.to_string(),
"".to_string(),
schema.clone(),
))?;
storage.write_entry(&LogEntry::new(
"TX_COMMIT".into(),
collection.into(),
tx_id,
Value::Null,
))?;
schemas.insert(collection.to_string(), Arc::new((schema.clone(), validator)));
let event = serde_json::json!({
"event": "SCHEMA_SET",
"collection": collection,
"schema": schema
});
let _ = tx.send(event.to_string());
Ok(())
}
pub fn validate_document(
schemas: &DashMap<String, Arc<(Value, Validator)>>,
collection: &str,
document: &Value,
) -> Result<(), DbError> {
if let Some(entry) = schemas.get(collection) {
let validator = &entry.1;
if !validator.is_valid(document) {
return Err(DbError::SchemaValidationError("Document does not conform to schema".to_string()));
}
}
Ok(())
}