From df4671761c1ece03925ec7672b74d75dc7510b2e Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Fri, 7 Nov 2025 12:08:08 -0500 Subject: [PATCH] Adjusted query to also accept a list of oids. --- src/message.rs | 286 ++++++++++++++++++++----------------------------- 1 file changed, 114 insertions(+), 172 deletions(-) diff --git a/src/message.rs b/src/message.rs index 15217c9..b354568 100644 --- a/src/message.rs +++ b/src/message.rs @@ -46,7 +46,7 @@ enum Action { Create, Delete, Error, - On, + OnAction, Query, Records, Register, @@ -62,7 +62,7 @@ impl From for Action { MsgAction::Create(_) => Action::Create, MsgAction::Delete(_) => Action::Delete, MsgAction::Error(_) => Action::Error, - MsgAction::On(_) => Action::On, + MsgAction::OnAction(_) => Action::OnAction, MsgAction::Query(_) => Action::Query, MsgAction::Records(_) => Action::Records, MsgAction::Register(_) => Action::Register, @@ -127,8 +127,8 @@ enum MsgAction { // Alter // Remove Error(MTTError), - On(On), - Query(Query), + OnAction(OnAction), + Query(QueryType), Records(RecordIter), Register(Register), Reply(Reply), @@ -163,7 +163,7 @@ impl From for MsgAction { impl From for MsgAction { fn from(value: Query) -> Self { - MsgAction::Query(value) + MsgAction::Query(QueryType::Query(value)) } } @@ -329,7 +329,7 @@ mod messages { #[test] fn can_the_document_be_an_id() { let document = Uuid::new_v4(); - let msg = Message::new(document.clone(), MsgAction::Query(Query::new())); + let msg = Message::new(document.clone(), Query::new()); match msg.get_document_id() { NameType::ID(data) => assert_eq!(data, &document), _ => unreachable!("should have been an id"), @@ -354,7 +354,7 @@ mod messages { #[test] fn Can_make_reply_message() { let name = Name::english("testing"); - let msg = Message::new(name.clone(), MsgAction::Query(Query::new())); + let msg = Message::new(name.clone(), Query::new()); let responce = Reply::new(); let reply = msg.response(responce); assert_eq!(reply.get_message_id(), msg.get_message_id()); @@ -371,7 +371,7 @@ mod messages { #[test] fn Can_make_error_message() { let name = Name::english("testing"); - let msg = Message::new(name.clone(), MsgAction::Query(Query::new())); + let msg = Message::new(name.clone(), Query::new()); let err_msg = Uuid::new_v4().to_string(); let result = msg.response(MTTError::DocumentNotFound(err_msg.clone())); @@ -392,7 +392,7 @@ mod messages { #[test] fn can_make_a_response_message() { let doc_id = Uuid::new_v4(); - let msg = Message::new(doc_id.clone(), MsgAction::Query(Query::new())); + let msg = Message::new(doc_id.clone(), Query::new()); let data = Uuid::new_v4().to_string(); let result1 = msg.response(MTTError::DocumentNotFound(data.clone())); let result2 = msg.response(Reply::new()); @@ -2418,12 +2418,12 @@ enum OnType { } #[derive(Clone, Debug)] -struct On { +struct OnAction { on_type: OnType, oids: HashSet, } -impl On { +impl OnAction { fn new(on_type: OnType, oids: HashSet) -> Self { Self { on_type: on_type, @@ -2453,7 +2453,7 @@ mod ons { while oids.len() < count { oids.insert(Oid::new()); } - let result = On::new(on_type.clone(), oids.clone()); + let result = OnAction::new(on_type.clone(), oids.clone()); assert_eq!(result.get_type(), on_type); assert_eq!(result.get_oids(), &oids); } @@ -3205,6 +3205,24 @@ impl Operation { } } +#[derive(Clone, Debug)] +enum QueryType { + Query(Query), + Oids(HashSet), +} + +impl From for QueryType { + fn from(value: Query) -> Self { + QueryType::Query(value) + } +} + +impl From> for QueryType { + fn from(value: HashSet) -> Self { + QueryType::Oids(value) + } +} + #[derive(Clone, Debug)] struct Query { data: HashMap, @@ -3710,12 +3728,6 @@ impl Document { self.data.iter() } - /* - fn iter(&self) -> DocIter { - DocIter::new(self) - } - */ - fn is_empty(&self) -> bool { self.data.is_empty() } @@ -3779,47 +3791,45 @@ mod documents { #[derive(Clone, Debug)] struct Delete { - query: Query, + query: QueryType, } impl Delete { - fn new() -> Self { + fn new(query: QT) -> Self + where + QT: Into, + { Self { - query: Query::new(), + query: query.into(), } } - fn get_query(&self) -> &Query { + fn get_query(&self) -> &QueryType { &self.query } - - fn get_query_mut(&mut self) -> &mut Query { - &mut self.query - } } #[derive(Clone, Debug)] struct Update { - query: Query, + query: QueryType, values: Document, } impl Update { - fn new() -> Self { + fn new(query: QT) -> Self + where + QT: Into, + { Self { - query: Query::new(), + query: query.into(), values: Document::new(), } } - fn get_query(&self) -> &Query { + fn get_query(&self) -> &QueryType { &self.query } - fn get_query_mut(&mut self) -> &mut Query { - &mut self.query - } - fn get_values(&self) -> &Document { &self.values } @@ -4348,49 +4358,6 @@ impl DocumentFile { records.insert(holder); } records.into() - - /* - for (field_id, value) in addition.iter() { - let id = match self.docdef.get_field_id(field_id) { - Ok(fid) => fid, - Err(err) => return MsgAction::Error(err), - }; - } - - let doc = addition.get_document(); - for (field, value) in doc.iter() { - match self.validate(field, &value) { - Ok((id, data)) => { - holder.insert(id, data); - } - Err(err) => return MsgAction::Error(err), - } - } - let requested: HashSet = holder.keys().cloned().collect(); - let all_fields = self.docdef.field_ids(); - for field in all_fields.difference(&requested).cloned() { - match self.validate(field, &Field::None) { - Ok((id, data)) => { - holder.insert(id, data); - } - Err(err) => return MsgAction::Error(err), - } - } - let mut records = RecordIter::with_names(self.docdef.get_field_names().clone()); - if !holder.is_empty() { - let mut oid = Oid::new(); - while self.docs.contains_key(&oid) { - oid = Oid::new(); - } - self.docs.insert(oid.clone(), holder.clone()); - for (field_id, oids) in self.indexes.iter_mut() { - let value = holder.get(field_id).unwrap(); - oids.internal_add(value, oid.clone()); - } - records.insert(holder); - } - records.into() - */ } fn delete(&mut self, delete: &Delete) -> MsgAction { @@ -4410,7 +4377,11 @@ impl DocumentFile { records.into() } - fn run_query(&self, query: &Query) -> Result, MTTError> { + fn run_query(&self, query_type: &QueryType) -> Result, MTTError> { + let query = match query_type { + QueryType::Query(qry) => qry, + QueryType::Oids(oids) => return Ok(oids.clone()), + }; let indexed_ids = self.indexes.index_ids(); let mut indexed: HashMap = HashMap::new(); let mut unindexed: HashMap = HashMap::new(); @@ -4451,7 +4422,7 @@ impl DocumentFile { Ok(oids) } - fn query(&self, query: &Query) -> MsgAction { + fn query(&self, query: &QueryType) -> MsgAction { let oids = match self.run_query(query) { Ok(data) => data, Err(err) => return err.into(), @@ -4508,51 +4479,6 @@ impl DocumentFile { output.insert(new_rec.clone()); } output.into() - - /* - let mut changes: HashMap = HashMap::new(); - for (key, value) in update.get_values().iter() { - let (id, field) = match self.validate(key, &value) { - Ok(data) => data, - Err(err) => return err.into(), - }; - changes.insert(id, field); - } - let oids = match self.run_query(update.get_query()) { - Ok(result) => result, - Err(err) => return err.into(), - }; - let mut holder: HashMap = HashMap::new(); - for oid in oids.iter() { - holder.insert(oid.clone(), self.docs.get(oid).unwrap().clone()); - } - let mut removes: Vec<(Uuid, Field, Oid)> = Vec::new(); - let mut indexes = self.docdef.create_indexes(); - for (oid, rec) in holder.iter_mut() { - for (field_id, value) in changes.iter() { - removes.push(( - field_id.clone(), - rec.get(field_id).unwrap().clone(), - oid.clone(), - )); - match indexes.add_to_index(&field_id, value.clone(), oid.clone()) { - Ok(_) => {} - Err(err) => return err.into(), - } - rec.insert(field_id.clone(), value.clone()); - } - } - let mut output = RecordIter::with_names(self.docdef.get_field_names().clone()); - for (field_id, value, oid) in removes.iter() { - self.indexes.remove_from_index(field_id, value, oid); - } - self.indexes.append(&indexes); - for (oid, record) in holder.iter() { - self.docs.insert(oid.clone(), record.clone()); - output.insert(record.clone()); - } - output.into() - */ } } @@ -4704,10 +4630,10 @@ mod document_files { let queue = test_doc.get_queue(); let msg_actions = [ MsgAction::Addition(Addition::new()), - MsgAction::Delete(Delete::new()), - MsgAction::Query(Query::new()), + MsgAction::Delete(Delete::new(Query::new())), + MsgAction::Query(Query::new().into()), MsgAction::Show, - MsgAction::Update(Update::new()), + MsgAction::Update(Update::new(Query::new())), ]; for msg_action in msg_actions.iter() { let msg = Message::new(name.clone(), msg_action.clone()); @@ -4753,10 +4679,10 @@ mod document_files { let msg_actions = [ MsgAction::Addition(Addition::new()), MsgAction::Create(DocDef::new(name.clone())), - MsgAction::Delete(Delete::new()), - MsgAction::Query(Query::new()), + MsgAction::Delete(Delete::new(Query::new())), + MsgAction::Query(Query::new().into()), MsgAction::Show, - MsgAction::Update(Update::new()), + MsgAction::Update(Update::new(Query::new())), ]; let mut msgs: HashMap = HashMap::new(); for msg_action in msg_actions.iter() { @@ -5306,10 +5232,13 @@ mod document_files { for id in ids.iter() { doc.populate([id.clone().into()].to_vec()); } - let mut update = Update::new(); let mut calc = Calculation::new(Operand::Equal); - calc.add_value(id); - update.get_query_mut().add(Name::english("field0"), calc); + calc.add_value(CalcValue::Existing(FieldType::Uuid)) + .unwrap(); + calc.add_value(Uuid::nil()).unwrap(); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update .get_values_mut() .add_field(Name::english("field0"), Uuid::nil()); @@ -5331,12 +5260,13 @@ mod document_files { let new = "new"; let id = Uuid::new_v4(); doc.populate([id.into(), old.into()].to_vec()); - let mut update = Update::new(); let mut calc = Calculation::new(Operand::Equal); calc.add_value(CalcValue::Existing(FieldType::Uuid)) .unwrap(); calc.add_value(id.clone()).unwrap(); - update.get_query_mut().add(Name::english("field0"), calc); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update .get_values_mut() .add_field(Name::english("field1"), new); @@ -5368,16 +5298,18 @@ mod document_files { let old = "old"; let new = "new"; let count = 5; + let field_count = count.clone().try_into().unwrap(); let picked = 3; - for i in 0..count { + for i in 0..field_count { doc.populate([i.into(), old.into()].to_vec()); } - let mut update = Update::new(); let mut calc = Calculation::new(Operand::Equal); - calc.add_value(picked.clone()).unwrap(); calc.add_value(CalcValue::Existing(FieldType::Integer)) .unwrap(); - update.get_query_mut().add(Name::english("field0"), calc); + calc.add_value(picked.clone()).unwrap(); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update .get_values_mut() .add_field(Name::english("field1"), new); @@ -5403,7 +5335,7 @@ mod document_files { let action = result.get_action(); match action { MsgAction::Records(docs) => { - assert_eq!(docs.len(), 5, "should have one entry"); + assert_eq!(docs.len(), count, "should have one entry"); for doc in docs.clone() { if doc.get(Name::english("field0")).unwrap() == picked.into() { assert_eq!(doc.get(Name::english("field1")).unwrap(), new.into()); @@ -5428,12 +5360,13 @@ mod document_files { for i in 0..count { doc.populate([picked.into(), old.into()].to_vec()); } - let mut update = Update::new(); let mut calc = Calculation::new(Operand::Equal); - calc.add_value(picked.clone()).unwrap(); calc.add_value(CalcValue::Existing(FieldType::Integer)) .unwrap(); - update.get_query_mut().add(Name::english("field0"), calc); + calc.add_value(picked.clone()).unwrap(); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update .get_values_mut() .add_field(Name::english("field1"), new); @@ -5443,7 +5376,7 @@ mod document_files { let action = result.get_action(); match action { MsgAction::Records(docs) => { - assert_eq!(docs.len(), 5, "should have one entry"); + assert_eq!(docs.len(), count, "should have one entry"); for doc in docs.clone() { assert_eq!(doc.get(Name::english("field0")).unwrap(), picked.into()); assert_eq!(doc.get(Name::english("field1")).unwrap(), new.into()); @@ -5465,10 +5398,7 @@ mod document_files { let new = "new"; let bad_name = Name::english("wrong"); doc.populate([id.into(), old.into()].to_vec()); - let mut update = Update::new(); - let mut calc = Calculation::new(Operand::Equal); - calc.add_value(id.clone()); - update.get_query_mut().add(Name::english("field0"), calc); + let mut update = Update::new(Query::new()); update.get_values_mut().add_field(bad_name.clone(), new); doc.send(update).unwrap(); let result = doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); @@ -5490,11 +5420,14 @@ mod document_files { let old = "old"; let new = Uuid::nil(); doc.populate([id.into(), old.into()].to_vec()); - let mut update = Update::new(); + let mut calc = Calculation::new(Operand::Equal); - calc.add_value(id.clone()); - calc.add_value(CalcValue::Existing(FieldType::Uuid)); - update.get_query_mut().add(Name::english("field0"), calc); + calc.add_value(CalcValue::Existing(FieldType::Uuid)) + .unwrap(); + calc.add_value(id.clone()).unwrap(); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update .get_values_mut() .add_field(Name::english("field1"), new); @@ -5524,11 +5457,14 @@ mod document_files { let old = 3; let new = 5; test_doc.populate([old.into()].to_vec()); - let mut update = Update::new(); + let mut calc = Calculation::new(Operand::Equal); - calc.add_value(old); - calc.add_value(CalcValue::Existing(FieldType::Integer)); - update.get_query_mut().add(fname.clone(), calc); + calc.add_value(CalcValue::Existing(FieldType::Integer)) + .unwrap(); + calc.add_value(old.clone()).unwrap(); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update.get_values_mut().add_field(&fname, new); test_doc.send(update).unwrap(); test_doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); @@ -5606,11 +5542,14 @@ mod document_files { let fold: Field = old.into(); let fnew: Field = new.into(); doc.populate([old.into()].to_vec()); - let mut update = Update::new(); + let mut calc = Calculation::new(Operand::Equal); - calc.add_value(old); - calc.add_value(CalcValue::Existing(FieldType::StaticString)); - update.get_query_mut().add(fname.clone(), calc); + calc.add_value(CalcValue::Existing(FieldType::StaticString)) + .unwrap(); + calc.add_value(old.clone()).unwrap(); + let mut query = Query::new(); + query.add(Name::english("field0"), calc); + let mut update = Update::new(query); update.get_values_mut().add_field(fname.clone(), new); doc.send(update).unwrap(); doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); @@ -5661,12 +5600,14 @@ mod document_files { for id in ids.iter() { doc.populate([id.clone().into(), data.into()].to_vec()); } - let mut update = Update::new(); + let mut calc = Calculation::new(Operand::Equal); - calc.add_value(data).unwrap(); calc.add_value(CalcValue::Existing(FieldType::StaticString)) .unwrap(); - update.get_query_mut().add(&f1name, calc); + calc.add_value(data).unwrap(); + let mut query = Query::new(); + query.add(&f1name, calc); + let mut update = Update::new(query); update.get_values_mut().add_field(&f0name, holder.clone()); doc.send(update).unwrap(); let result = doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); @@ -5674,7 +5615,7 @@ mod document_files { match action { MsgAction::Error(err) => match err { MTTError::FieldDuplicate => {} - _ => unreachable!("got {:?}: should have gotten an missing field", err), + _ => unreachable!("got {:?}: should have gotten field duplicate", err), }, _ => unreachable!("got {:?}: should have gotten an error", action), } @@ -5741,8 +5682,7 @@ mod document_files { calc.add_value(CalcValue::Existing(FieldType::Integer)); let mut query = Query::new(); query.add(&fname, calc); - let mut delete = Delete::new(); - *delete.get_query_mut() = query.clone(); + let mut delete = Delete::new(query.clone()); doc.send(delete).unwrap(); let result = doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); let action = result.get_action(); @@ -5772,11 +5712,12 @@ mod document_files { let field_name = Name::english("wrong"); let mut doc = TestDocument::new([FieldType::Integer].to_vec()); doc.start(); - let mut delete = Delete::new(); let mut calc = Calculation::new(Operand::Equal); + calc.add_value(CalcValue::Existing(FieldType::Integer)); calc.add_value(1); - let query = delete.get_query_mut(); + let mut query = Query::new(); query.add(field_name.clone(), calc); + let delete = Delete::new(query); doc.send(delete).unwrap(); let result = doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); let action = result.get_action(); @@ -5797,7 +5738,7 @@ mod document_files { doc.get_docdef_mut().add_index(&fname, IndexType::Unique); doc.start(); doc.populate([value.into()].to_vec()); - doc.send(Delete::new()); + doc.send(Delete::new(Query::new())); doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); let mut addition = Addition::new(); addition.add_field(&fname, value.clone()); @@ -5852,7 +5793,7 @@ mod createdocs { MsgAction::Reply(_) => {} _ => unreachable!("got {:?}: should have been a reply.", result1.get_action()), } - let msg2 = Message::new(name, MsgAction::Query(Query::new())); + let msg2 = Message::new(name, Query::new()); queue.send(msg2.clone()).unwrap(); let result2 = rx.recv_timeout(TIMEOUT).unwrap(); assert_eq!(result2.get_message_id(), msg2.get_message_id()); @@ -5925,6 +5866,7 @@ impl Clock { #[cfg(test)] mod clocks { use super::*; + use chrono::TimeDelta; static TIMEOUT: Duration = Duration::from_millis(1500); @@ -5946,8 +5888,8 @@ mod clocks { holder.push(rx.recv_timeout(TIMEOUT).unwrap()); } let end = Utc::now(); - assert!((end - start) > chrono::TimeDelta::seconds(1)); - assert!((end - start) < chrono::TimeDelta::seconds(2)); + assert!((end - start) > TimeDelta::seconds(1)); + assert!((end - start) < TimeDelta::seconds(2)); for msg in holder.iter() { let name_id = msg.get_document_id(); match name_id {