From 14020cd25fc58bdd0eaeed73905422c2e3d66e9f Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Mon, 15 Sep 2025 09:32:45 -0400 Subject: [PATCH] Got update working. --- src/message.rs | 205 ++++++++++++++++++++++++------------------------- 1 file changed, 101 insertions(+), 104 deletions(-) diff --git a/src/message.rs b/src/message.rs index dfb1bbb..34e98fd 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1392,42 +1392,8 @@ impl DocDef { Ok(()) } - fn create_indexes(&self) -> HashMap { - let mut output = HashMap::new(); - for (key, value) in self.indexes.iter() { - output.insert(key.clone(), value.create_index()); - } - output - } - - fn set_unique(&mut self, field_name: &str) -> Result<(), MTTError> { - let setting = match self.get_field_mut(field_name) { - Ok(data) => data, - Err(err) => return Err(err), - }; - setting.set_unique(); - Ok(()) - } - - fn use_unique_value(&mut self, field_name: &str, field: Field) -> Result<(), MTTError> { - let setting = match self.get_field_mut(field_name) { - Ok(data) => data, - Err(err) => return Err(err), - }; - match setting.validate(Some(field.clone())) { - Ok(data) => setting.use_unique_value(field), - Err(err) => return Err(err), - } - Ok(()) - } - - fn remove_unique_value(&mut self, field_name: &str, field: &Field) -> Result<(), MTTError> { - let setting = match self.get_field_mut(field_name) { - Ok(data) => data, - Err(err) => return Err(err), - }; - setting.remove_unique_value(field); - Ok(()) + fn create_indexes(&self) -> Indexes { + Indexes::new(&self.indexes) } fn iter(&self) -> impl Iterator { @@ -1539,50 +1505,6 @@ mod docdefs { }, } } - - #[test] - fn does_set_unique_error_on_bad_field_name() { - let mut docdef = DocDef::new(); - let field_name = "bad"; - match docdef.set_unique(field_name) { - Ok(data) => unreachable!("got {:?}, should be an error", data), - Err(err) => match err { - MTTError::DocumentFieldNotFound(data) => assert_eq!(data, field_name), - _ => unreachable!("got {:?}: should have been field not found", err), - }, - } - } - - #[test] - fn does_set_unique_value_error_on_bad_field_name() { - let mut docdef = DocDef::new(); - let field_name = "wrong"; - match docdef.use_unique_value(field_name, "".into()) { - Ok(data) => unreachable!("got {:?}, should be an error", data), - Err(err) => match err { - MTTError::DocumentFieldNotFound(data) => assert_eq!(data, field_name), - _ => unreachable!("got {:?}: should have been field not found", err), - }, - } - } - - #[test] - fn does_set_unique_value_error_on_bad_field_type() { - let mut docdef = DocDef::new(); - let field_name = "unique"; - docdef.add_field(field_name.to_string(), FieldType::Uuid); - docdef.set_unique(field_name).unwrap(); - match docdef.use_unique_value(field_name, "".into()) { - Ok(data) => unreachable!("got {:?}, should be an error", data), - Err(err) => match err { - MTTError::DocumentFieldWrongDataType(expected, got) => { - assert_eq!(expected, FieldType::Uuid); - assert_eq!(got, FieldType::StaticString); - } - _ => unreachable!("got {:?}: should have been field not found", err), - }, - } - } } #[derive(Clone, Debug)] @@ -1916,6 +1838,47 @@ impl Index { } } +struct Indexes { + data: HashMap, +} + +impl Indexes { + fn new(settings: &HashMap) -> Self { + let mut output = HashMap::new(); + for (key, value) in settings.iter() { + output.insert(key.clone(), value.create_index()); + } + Self { data: output } + } + + fn add_to_index(&mut self, field_name: &str, field: Field, oid: Oid) { + let index = match self.data.get_mut(field_name) { + Some(data) => data, + None => return, + }; + index.add(field, oid); + } + + fn remove_from_index(&mut self, field_name: &str, field: &Field, oid: &Oid) { + let index = match self.data.get_mut(field_name) { + Some(data) => data, + None => return, + }; + index.remove(field, oid); + } + + fn validate(&self, field_name: &str, value: &Field) -> Result<(), MTTError> { + match self.data.get(field_name) { + Some(index) => match index.validate(value) { + Ok(_) => {} + Err(err) => return Err(err), + }, + None => {} + } + Ok(()) + } +} + #[cfg(test)] mod indexes { use super::*; @@ -2054,7 +2017,7 @@ mod indexes { struct DocumentFile { docdef: DocDef, docs: HashMap, - indexes: HashMap, + indexes: Indexes, queue: Queue, rx: Receiver, } @@ -2141,6 +2104,18 @@ impl DocumentFile { self.docs.iter() } + fn validate(&self, field_name: &str, value: Option) -> Result { + let output = match self.docdef.validate(field_name, value) { + Ok(data) => data, + Err(err) => return Err(err), + }; + match self.indexes.validate(field_name, &output) { + Ok(_) => {} + Err(err) => return Err(err), + } + Ok(output) + } + fn add_field_to_error(key: String, err: MTTError) -> MTTError { match err { MTTError::DocumentFieldMissing(_) => MTTError::DocumentFieldMissing(key), @@ -2149,19 +2124,29 @@ impl DocumentFile { } } + fn add_to_index(&mut self, field_name: &str, field: Field, oid: Oid) { + self.indexes.add_to_index(field_name, field, oid) + } + + fn remove_from_index(&mut self, field_name: &str, field: &Field, oid: &Oid) { + self.indexes.remove_from_index(field_name, field, oid); + } + fn add_document(&mut self, addition: &Addition) -> MsgAction { let mut holder = Document::new(); let doc = addition.get_document(); for (key, value) in doc.iter() { - match self.docdef.validate(key, Some(value.clone())) { - Ok(data) => holder.add_field(key.clone(), value.clone()), + match self.validate(key, Some(value.clone())) { + Ok(data) => { + holder.add_field(key.clone(), value.clone()); + } Err(err) => return Self::add_field_to_error(key.to_string(), err).into(), } } for (key, value) in self.docdef.iter() { match holder.get_field(key) { Some(_) => {} - None => match value.validate(None) { + None => match self.validate(key, None) { Ok(data) => holder.add_field(key.clone(), data.clone()), Err(err) => return Self::add_field_to_error(key.to_string(), err).into(), }, @@ -2171,9 +2156,9 @@ impl DocumentFile { while self.docs.contains_key(&oid) { oid = Oid::new(); } - self.docs.insert(oid, holder.clone()); + self.docs.insert(oid.clone(), holder.clone()); for (key, value) in holder.iter() { - self.docdef.use_unique_value(key, value.clone()); + self.add_to_index(key, value.clone(), oid.clone()); } let mut reply = Reply::new(); reply.add(holder); @@ -2183,10 +2168,7 @@ impl DocumentFile { fn run_query(&self, query: &Query) -> Result, MTTError> { let mut reply = Reply::new(); for specifier in query.iter() { - match self - .docdef - .validate(&specifier.field_name, Some(specifier.value.clone())) - { + match self.validate(&specifier.field_name, Some(specifier.value.clone())) { Ok(_) => {} Err(err) => match err { MTTError::FieldDuplicate(_, _) => {} @@ -2228,20 +2210,35 @@ impl DocumentFile { Ok(result) => result, Err(err) => return err.into(), }; - let mut reply = Reply::new(); + let mut holder: HashMap = HashMap::new(); for oid in oids.iter() { - let doc = self.docs.get_mut(oid).unwrap(); + let doc = self.docs.get(oid).unwrap(); + let old_new = [doc.clone(), doc.clone()]; + holder.insert(oid.clone(), old_new); + } + let mut index_holder = self.docdef.create_indexes(); + for (oid, docs) in holder.iter_mut() { + let mut updated = Document::new(); for (key, value) in update.get_values().iter() { - match self.docdef.validate(key, Some(value.clone())) { - Ok(field) => { - self.docdef - .remove_unique_value(key, doc.get_field(key).unwrap()); - doc.add_field(key.clone(), field.clone()); - } + match self.validate(key, Some(value.clone())) { + Ok(field) => match index_holder.validate(key, &field) { + Ok(_) => { + index_holder.add_to_index(key, field.clone(), oid.clone()); + docs[1].add_field(key.clone(), field.clone()); + } + Err(err) => return Self::add_field_to_error(key.to_string(), err).into(), + }, Err(err) => return err.into(), } } - reply.add(doc.clone()); + } + let mut reply = Reply::new(); + for (oid, docs) in holder.iter() { + self.docs.insert(oid.clone(), docs[1].clone()); + reply.add(docs[1].clone()); + for (key, value) in docs[0].iter() { + self.remove_from_index(key, value, oid); + } } reply.into() } @@ -3041,7 +3038,7 @@ mod document_files { #[test] fn can_field_be_marked_unique() { let (mut docdef, doc_name) = create_docdef([FieldType::Uuid].to_vec()); - docdef.set_unique("field0"); + docdef.add_index("field0".to_string(), IndexType::Unique); let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes()); let field0 = Uuid::new_v4(); let mut addition = Addition::new(); @@ -3069,7 +3066,7 @@ mod document_files { #[test] fn unique_value_remains_available_if_failure_occurs() { let (mut docdef, doc_name) = create_docdef([FieldType::Uuid, FieldType::Uuid].to_vec()); - docdef.set_unique("field0"); + docdef.add_index("field0".to_string(), IndexType::Unique); let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes()); let field0 = Uuid::new_v4(); let mut bad_addition = Addition::new(); @@ -3094,7 +3091,7 @@ mod document_files { #[test] fn updating_unique_removes_old_entry() { let (mut docdef, doc_name) = create_docdef([FieldType::Uuid].to_vec()); - docdef.set_unique("field0"); + docdef.add_index("field0".to_string(), IndexType::Unique); let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes()); let old = Uuid::new_v4(); let mut new = Uuid::new_v4(); @@ -3151,7 +3148,7 @@ mod document_files { } } - //#[test] + #[test] fn unique_available_after_bad_change() { let mut ids: Vec = Vec::new(); while ids.len() < 3 { @@ -3162,7 +3159,7 @@ mod document_files { } let (mut docdef, doc_name) = create_docdef([FieldType::Uuid, FieldType::StaticString].to_vec()); - docdef.set_unique("field0"); + docdef.add_index("field0".to_string(), IndexType::Unique); let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes()); let field1 = "fred"; for index in 0..2 {