feat(storage): add offline data validation and strengthen storage/index integrity checks
This commit is contained in:
@@ -153,6 +153,55 @@ impl IndexEngine {
|
||||
self.indexes.contains_key(name)
|
||||
}
|
||||
|
||||
/// Check unique constraints for a document without modifying the index.
|
||||
/// Returns Ok(()) if no conflict, Err(DuplicateKey) if a unique constraint
|
||||
/// would be violated. This is a read-only check (immutable &self).
|
||||
pub fn check_unique_constraints(&self, doc: &Document) -> Result<(), IndexError> {
|
||||
for idx in self.indexes.values() {
|
||||
if idx.unique {
|
||||
let key_bytes = Self::extract_key_bytes(doc, &idx.key, idx.sparse);
|
||||
if let Some(ref kb) = key_bytes {
|
||||
if let Some(existing_ids) = idx.hash.get(kb) {
|
||||
if !existing_ids.is_empty() {
|
||||
return Err(IndexError::DuplicateKey {
|
||||
index: idx.name.clone(),
|
||||
key: format!("{:?}", kb),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check unique constraints for an update, excluding the document being updated.
|
||||
/// Returns Ok(()) if no conflict. This is a read-only check (immutable &self).
|
||||
pub fn check_unique_constraints_for_update(
|
||||
&self,
|
||||
old_doc: &Document,
|
||||
new_doc: &Document,
|
||||
) -> Result<(), IndexError> {
|
||||
let doc_id = Self::extract_id(old_doc);
|
||||
for idx in self.indexes.values() {
|
||||
if idx.unique {
|
||||
let new_key_bytes = Self::extract_key_bytes(new_doc, &idx.key, idx.sparse);
|
||||
if let Some(ref kb) = new_key_bytes {
|
||||
if let Some(existing_ids) = idx.hash.get(kb) {
|
||||
let has_conflict = existing_ids.iter().any(|id| *id != doc_id);
|
||||
if has_conflict {
|
||||
return Err(IndexError::DuplicateKey {
|
||||
index: idx.name.clone(),
|
||||
key: format!("{:?}", kb),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Notify the engine that a document has been inserted.
|
||||
/// Checks unique constraints and updates all index structures.
|
||||
pub fn on_insert(&mut self, doc: &Document) -> Result<(), IndexError> {
|
||||
|
||||
Reference in New Issue
Block a user