solidb/storage/collection/
schema.rs1use super::*;
2use crate::error::{DbError, DbResult};
3use crate::storage::schema::CollectionSchema;
4use seahash::SeaHasher;
5use std::hash::Hasher;
6
7impl Collection {
8 fn compute_schema_hash(schema: &CollectionSchema) -> u64 {
12 let serialized = serde_json::to_vec(schema).unwrap_or_default();
13 let mut hasher = SeaHasher::new();
14 hasher.write(&serialized);
15 hasher.finish()
16 }
17
18 pub fn get_cached_schema_validator(&self) -> Result<Option<SchemaValidator>, DbError> {
20 if let Some(schema) = self.get_json_schema() {
21 let schema_hash = Self::compute_schema_hash(&schema);
22
23 let mut cached_hash = self.schema_hash.write().unwrap();
24 let mut cached_validator = self.schema_validator.write().unwrap();
25
26 if let Some(ref current_hash) = *cached_hash {
27 if *current_hash == schema_hash {
28 if let Some(ref validator) = *cached_validator {
29 return Ok(Some(validator.clone()));
30 }
31 }
32 }
33
34 let validator = SchemaValidator::new(schema).map_err(|e| {
35 DbError::InvalidDocument(format!("Schema compilation error: {}", e))
36 })?;
37
38 *cached_hash = Some(schema_hash);
39 *cached_validator = Some(validator.clone());
40
41 Ok(Some(validator))
42 } else {
43 Ok(None)
44 }
45 }
46
47 fn invalidate_schema_cache(&self) {
49 let mut cached_hash = self.schema_hash.write().unwrap();
50 let mut cached_validator = self.schema_validator.write().unwrap();
51 *cached_hash = None;
52 *cached_validator = None;
53 }
54
55 pub fn set_json_schema(&self, schema: CollectionSchema) -> DbResult<()> {
58 self.invalidate_schema_cache();
59
60 if schema.is_enabled() {
62 jsonschema::validator_for(&schema.schema)
63 .map_err(|e| DbError::InvalidDocument(format!("Invalid JSON Schema: {}", e)))?;
64 }
65
66 let db = &self.db;
67 let cf = db
68 .cf_handle(&self.name)
69 .expect("Column family should exist");
70
71 let schema_bytes = serde_json::to_vec(&schema)?;
72 db.put_cf(cf, SCHEMA_KEY.as_bytes(), &schema_bytes)
73 .map_err(|e| DbError::InternalError(format!("Failed to set schema: {}", e)))?;
74
75 Ok(())
76 }
77
78 pub fn get_json_schema(&self) -> Option<CollectionSchema> {
80 let db = &self.db;
81 let cf = db.cf_handle(&self.name)?;
82
83 db.get_cf(cf, SCHEMA_KEY.as_bytes())
84 .ok()
85 .flatten()
86 .and_then(|bytes| serde_json::from_slice(&bytes).ok())
87 }
88
89 pub fn remove_json_schema(&self) -> DbResult<()> {
91 self.invalidate_schema_cache();
92
93 let db = &self.db;
94 let cf = db
95 .cf_handle(&self.name)
96 .expect("Column family should exist");
97
98 db.delete_cf(cf, SCHEMA_KEY.as_bytes())
99 .map_err(|e| DbError::InternalError(format!("Failed to remove schema: {}", e)))?;
100
101 Ok(())
102 }
103}