diff --git a/src/message.rs b/src/message.rs index 9e3cf95..641f341 100644 --- a/src/message.rs +++ b/src/message.rs @@ -47,7 +47,7 @@ enum Action { Create, Delete, Error, - OnAction, + OnQuery, Query, Records, Register, @@ -127,8 +127,8 @@ enum MsgAction { // Alter // Remove Error(MTTError), - Query(QueryType), - Records(RecordIter), + Query(Query), + Records(Records), Register(Register), Reply(Reply), Show, @@ -162,12 +162,12 @@ impl From for MsgAction { impl From for MsgAction { fn from(value: Query) -> Self { - MsgAction::Query(QueryType::Query(value)) + MsgAction::Query(value) } } -impl From for MsgAction { - fn from(value: RecordIter) -> Self { +impl From for MsgAction { + fn from(value: Records) -> Self { MsgAction::Records(value) } } @@ -3508,6 +3508,144 @@ impl InternalRecord { } } +#[derive(Clone, Debug)] +struct InternalRecords { + data: HashMap, +} + +impl InternalRecords { + fn new() -> Self { + Self { + data: HashMap::new(), + } + } + + fn insert(&mut self, oid: Oid, record: InternalRecord) -> Option { + self.data.insert(oid, record) + } + + fn get(&self, oid: &Oid) -> Option<&InternalRecord> { + self.data.get(oid) + } + + fn remove(&mut self, oid: &Oid) -> Option { + self.data.remove(oid) + } + + fn iter(&self) -> impl Iterator { + self.data.iter() + } + + fn keys(&self) -> impl Iterator { + self.data.keys() + } + + fn values(&self) -> impl Iterator { + self.data.values() + } + + fn contains_key(&self, oid: &Oid) -> bool { + self.data.contains_key(oid) + } + + fn is_empty(&self) -> bool { + self.data.is_empty() + } + + fn len(&self) -> usize { + self.data.len() + } +} + +#[derive(Clone, Debug)] +struct Record { + names: Names, + data: InternalRecord, +} + +impl Record { + fn with_data(names: Names, rec: InternalRecord) -> Self { + Self { + names: names, + data: rec, + } + } + + fn get(&self, field_id: NT) -> Result + where + NT: Into, + { + let id = match self.names.get_id(field_id) { + Ok(data) => data, + Err(err) => return Err(err), + }; + match self.data.get(&id) { + Some(data) => Ok(data.clone()), + None => Err(MTTError::FieldMissingData), + } + } +} + +#[derive(Clone, Debug)] +struct Records { + names: Names, + data: InternalRecords, +} + +impl Records { + fn new(names: Names) -> Self { + Self { + names: names, + data: InternalRecords::new(), + } + } + + fn with_data(names: Names, records: InternalRecords) -> Self { + Self { + names: names, + data: records, + } + } + + fn insert(&mut self, oid: Oid, record: InternalRecord) -> Option { + self.data.insert(oid, record) + } + + fn len(&self) -> usize { + self.data.len() + } + + fn iter(&self) -> impl Iterator { + RecordIter::new(self) + } +} + +struct RecordIter { + names: Names, + recs: Vec, +} + +impl RecordIter { + fn new(records: &Records) -> Self { + Self { + names: records.names.clone(), + recs: records.data.values().cloned().collect(), + } + } +} + +impl Iterator for RecordIter { + type Item = Record; + + fn next(&mut self) -> Option { + match self.recs.pop() { + Some(rec) => Some(Record::with_data(self.names.clone(), rec.clone())), + None => None, + } + } +} + +/* #[derive(Clone, Debug)] struct Record { names: Names, @@ -3777,6 +3915,7 @@ mod records { } } } +*/ #[derive(Clone, Debug)] struct Document { @@ -3883,42 +4022,36 @@ mod documents { #[derive(Clone, Debug)] struct Delete { - query: QueryType, + query: Query, } impl Delete { - fn new(query: QT) -> Self - where - QT: Into, - { + fn new(query: Query) -> Self { Self { query: query.into(), } } - fn get_query(&self) -> &QueryType { + fn get_query(&self) -> &Query { &self.query } } #[derive(Clone, Debug)] struct Update { - query: QueryType, + query: Query, values: Document, } impl Update { - fn new(query: QT) -> Self - where - QT: Into, - { + fn new(query: Query) -> Self { Self { query: query.into(), values: Document::new(), } } - fn get_query(&self) -> &QueryType { + fn get_query(&self) -> &Query { &self.query } @@ -4275,7 +4408,7 @@ mod indexes { struct DocumentFile { docdef: DocDef, - docs: HashMap, + docs: InternalRecords, indexes: Indexes, queue: Queue, rx: Receiver, @@ -4285,7 +4418,7 @@ impl DocumentFile { fn new(queue: Queue, rx: Receiver, docdef: DocDef) -> Self { Self { docdef: docdef.clone(), - docs: HashMap::new(), + docs: InternalRecords::new(), indexes: docdef.create_indexes(), queue: queue, rx: rx, @@ -4438,7 +4571,7 @@ impl DocumentFile { }; holder.insert(field_id.clone(), corrected.clone()); } - let mut records = RecordIter::with_names(self.docdef.get_field_names().clone()); + let mut records = Records::new(self.docdef.get_field_names().clone()); if !holder.is_empty() { let mut oid = Oid::new(); while self.docs.contains_key(&oid) { @@ -4449,12 +4582,25 @@ impl DocumentFile { oids.internal_add(value, oid.clone()); } self.docs.insert(oid.clone(), holder.clone()); - records.insert(holder); + records.insert(oid, holder); } records.into() } fn delete(&mut self, delete: &Delete) -> MsgAction { + let records = match self.run_query(delete.get_query()) { + Ok(data) => data, + Err(err) => return err.into(), + }; + for (oid, record) in records.iter() { + for (field_id, index) in self.indexes.iter_mut() { + index.remove(record.get(field_id).unwrap(), oid); + } + self.docs.remove(oid); + } + Records::with_data(self.docdef.get_field_names().clone(), records).into() + + /* let oids = match self.run_query(delete.get_query()) { Ok(data) => data, Err(err) => return err.into(), @@ -4469,13 +4615,10 @@ impl DocumentFile { self.docs.remove(oid); } records.into() + */ } - 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()), - }; + fn run_query(&self, query: &Query) -> Result { let indexed_ids = self.indexes.index_ids(); let mut indexed: HashMap = HashMap::new(); let mut unindexed: HashMap = HashMap::new(); @@ -4498,6 +4641,34 @@ impl DocumentFile { }; oids = oids.intersection(&holder).cloned().collect(); } + let mut records = InternalRecords::new(); + for oid in oids.iter() { + records.insert(oid.clone(), self.docs.get(oid).unwrap().clone()); + } + let holder = oids.clone(); + for (oid, record) in records.iter() { + for (field_id, calc) in unindexed.iter() { + match calc.calculate(record.get(field_id).unwrap()) { + Field::Boolean(data) => { + if !data { + oids.remove(oid); + break; + } + } + _ => { + oids.remove(oid); + break; + } + } + } + } + let removals = holder.difference(&oids); + for oid in removals { + records.remove(oid); + } + Ok(records) + + /* for (field_id, calc) in unindexed.iter() { for oid in oids.clone().iter() { let doc = self.docs.get(oid).unwrap(); @@ -4513,22 +4684,72 @@ impl DocumentFile { } } } - Ok(oids) + let output = InternalRecords::new(); + for oid in oids.iter() { + output.insert(oid.clone(), self.docs.get(oid).unwrap().clone()); + } + Ok(output) + */ } - fn query(&self, query: &QueryType) -> MsgAction { - let oids = match self.run_query(query) { + fn query(&self, query: &Query) -> MsgAction { + let records = match self.run_query(query) { Ok(data) => data, Err(err) => return err.into(), }; + Records::with_data(self.docdef.get_field_names().clone(), records).into() + + /* let mut records = RecordIter::with_names(self.docdef.get_field_names().clone()); for oid in oids.iter() { records.insert(self.docs.get(oid).unwrap().clone()); } records.into() + */ } fn update(&mut self, update: &Update) -> MsgAction { + let original = match self.run_query(update.get_query()) { + Ok(result) => result, + Err(err) => return err.into(), + }; + let mut changes: HashMap = HashMap::new(); + for (key, value) in update.get_values().iter() { + let field_id = match self.docdef.get_field_id(key) { + Ok(data) => data, + Err(err) => return err.into(), + }; + changes.insert(field_id, value); + } + let mut indexes = self.docdef.create_indexes(); + let mut updates = InternalRecords::new(); + for (oid, record) in original.iter() { + let mut holder = record.clone(); + for (field_id, value) in changes.iter() { + let field = value.get(holder.get(field_id).unwrap()); + let correction = match self.validate(field_id, &field) { + Ok(data) => data, + Err(err) => return err.into(), + }; + holder.insert(field_id.clone(), correction.clone()); + match indexes.add_to_index(&field_id, correction, oid.clone()) { + Ok(_) => {} + Err(err) => return err.into(), + } + } + updates.insert(oid.clone(), holder); + } + for (oid, new_rec) in updates.iter() { + let old_rec = original.get(oid).unwrap(); + for (field_id, index) in self.indexes.iter_mut() { + index.remove(old_rec.get(field_id).unwrap(), oid); + index.add(new_rec.get(field_id).unwrap().clone(), oid.clone()); + } + self.docs.insert(oid.clone(), new_rec.clone()); + } + Records::with_data(self.docdef.get_field_names().clone(), updates).into() + + /* let oids = match self.run_query(update.get_query()) { Ok(result) => result, Err(err) => return err.into(), @@ -4542,8 +4763,8 @@ impl DocumentFile { changes.insert(field_id, value); } let mut indexes = self.docdef.create_indexes(); - let mut old: HashMap = HashMap::new(); - let mut changed: HashMap = HashMap::new(); + let mut old = InternalRecords::new(); + let mut changed = InternalRecords::new(); for oid in oids.iter() { let mut holder = self.docs.get(oid).unwrap().clone(); old.insert(oid.clone(), holder.clone()); @@ -4573,6 +4794,7 @@ impl DocumentFile { output.insert(new_rec.clone()); } output.into() + */ } } @@ -4593,7 +4815,6 @@ mod document_files { struct TestDocument { docdef: DocDef, queue: Queue, - routes: Vec, sender_id: Uuid, rx: Receiver, } @@ -4616,7 +4837,6 @@ mod document_files { Self { docdef: docdef, queue: queue, - routes: standard_paths(), sender_id: id, rx: rx, } @@ -4630,10 +4850,6 @@ mod document_files { &mut self.docdef } - fn get_routes_mut(&mut self) -> &mut Vec { - &mut self.routes - } - fn get_queue(&mut self) -> Queue { self.queue.clone() } @@ -4654,13 +4870,13 @@ mod document_files { self.queue.send(msg) } - fn start(&mut self) { + fn start(&mut self, routes: Vec) { let msg = Message::new( self.docdef.get_document_names()[0].clone(), self.docdef.clone(), ); DocumentFile::start(self.queue.clone(), msg); - for route in self.routes.iter() { + for route in routes.iter() { let request = Register::new(self.sender_id.clone(), RegMsg::AddRoute(route.clone())); let add_route = Message::new(NameType::None, request); @@ -4680,7 +4896,13 @@ mod document_files { count += 1; } self.send(add).unwrap(); - self.rx.recv().unwrap(); // eat addition response. + match self.rx.recv_timeout(TIMEOUT) { + Ok(_) => {} // eats the addition response. + Err(err) => match err { + RecvTimeoutError::Timeout => {} + _ => unreachable!("got {}, should have been ok or time out", err), + }, + } } } @@ -4692,7 +4914,6 @@ mod document_files { Self { docdef: value, queue: queue, - routes: standard_paths(), sender_id: id, rx: rx, } @@ -4705,7 +4926,7 @@ mod document_files { let docdef = DocDef::new(name.clone()); let mut test_doc: TestDocument = docdef.into(); let alt = Name::english("alternate"); - test_doc.start(); + test_doc.start(standard_paths()); let docdef = DocDef::new(alt); let msg = Message::new(name.clone(), docdef); test_doc.get_queue().send(msg).unwrap(); @@ -4723,7 +4944,7 @@ mod document_files { let name = Name::english("listen"); let docdef = DocDef::new(name.clone()); let mut test_doc: TestDocument = docdef.into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let msg_actions = [ MsgAction::Addition(Addition::new()), @@ -4767,7 +4988,7 @@ mod document_files { let alt = Name::english("alternate"); let docdef = DocDef::new(name.clone()); let mut test_doc: TestDocument = docdef.into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let reg_msg = Register::new( test_doc.get_sender_id(), @@ -4803,6 +5024,31 @@ mod document_files { } } + #[test] + #[ignore] + fn query_sends_on_query_message() { + let count = 5; + let mut data: HashSet = HashSet::new(); + while data.len() < count { + let field: Field = Uuid::new_v4().into(); + data.insert(field); + } + let mut test_doc = TestDocument::new([FieldType::Uuid].to_vec()); + let doc_name = test_doc.get_docdef().get_document_names()[0].clone(); + let routes = [Path::new( + Include::All, + Include::All, + Include::Some(Action::OnQuery), + )] + .to_vec(); + test_doc.start(routes); + for item in data.iter() { + test_doc.populate([item.clone()].to_vec()); + } + test_doc.send(Query::new()); + let result = test_doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); + } + #[test] fn can_document_be_added() { let doc_name = Name::english("document"); @@ -4811,7 +5057,7 @@ mod document_files { let data = Uuid::new_v4(); docdef.add_field(name.clone(), FieldType::Uuid); let mut test_doc: TestDocument = docdef.clone().into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let mut new_doc = Addition::new(); new_doc.add_field(name.clone(), data.clone()); @@ -4822,7 +5068,7 @@ mod document_files { match result.get_action() { MsgAction::Records(output) => { assert_eq!(output.len(), 1); - for rec in output.clone() { + for rec in output.iter() { let holder = rec.get(&name).unwrap(); match holder { Field::Uuid(field_data) => assert_eq!(field_data, data), @@ -4847,7 +5093,7 @@ mod document_files { let name = Name::english("count"); docdef.add_field(name.clone(), FieldType::Integer); let mut test_doc: TestDocument = docdef.clone().into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let count = 5; for i in 0..count { @@ -4868,7 +5114,7 @@ mod document_files { entry_count, "should have the same number of entries" ); - for record in output.clone() { + for record in output.iter() { let holder = record.get(&name).unwrap(); let data = match holder { Field::Integer(item) => item.clone(), @@ -4891,7 +5137,7 @@ mod document_files { #[test] fn errors_on_wrong_field_name() { let mut test_doc = TestDocument::new(Vec::new()); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let name = Name::english("bad"); let mut addition = Addition::new(); @@ -4915,7 +5161,7 @@ mod document_files { #[test] fn errors_on_wrong_field_type() { let mut test_doc = TestDocument::new([FieldType::Uuid].to_vec()); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let mut addition = Addition::new(); addition.add_field(Name::english("field0"), "string"); @@ -4942,7 +5188,7 @@ mod document_files { #[test] fn errors_on_missing_fields() { let mut test_doc = TestDocument::new([FieldType::Integer, FieldType::Integer].to_vec()); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let mut addition = Addition::new(); addition.add_field(Name::english("field0"), 1); @@ -4963,7 +5209,7 @@ mod document_files { #[test] fn does_query_return_related_entries() { let mut test_doc = TestDocument::new([FieldType::Integer].to_vec()); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let count = 5; let expected = 3; @@ -4991,7 +5237,7 @@ mod document_files { expected, action ); - for doc in data.clone() { + for doc in data.iter() { assert_eq!(doc.get(&Name::english("field0")).unwrap(), expected.into()); } } @@ -5002,7 +5248,7 @@ mod document_files { #[test] fn gets_all_documents_in_query() { let mut test_doc = TestDocument::new([FieldType::Integer].to_vec()); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let data = 1; let count = 5; @@ -5031,7 +5277,7 @@ mod document_files { data, action ); - for doc in docs.clone() { + for doc in docs.iter() { assert_eq!(doc.get(&Name::english("field0")).unwrap(), data.into()); } } @@ -5043,7 +5289,7 @@ mod document_files { fn query_should_work_with_multiple_fields() { let mut doc = TestDocument::new([FieldType::StaticString, FieldType::StaticString].to_vec()); - doc.start(); + doc.start(standard_paths()); let values = [ ["a".into(), "a".into()].to_vec(), ["a".into(), "b".into()].to_vec(), @@ -5070,7 +5316,7 @@ mod document_files { let afield: Field = "a".into(); let bfield: Field = "b".into(); assert_eq!(data.len(), 1, "should return one entry:\n{:?}", action); - for doc in data.clone() { + for doc in data.iter() { assert_eq!(doc.get(&Name::english("field0")).unwrap(), afield); assert_eq!(doc.get(&Name::english("field1")).unwrap(), bfield); } @@ -5086,7 +5332,7 @@ mod document_files { let docdef = doc.get_docdef_mut(); docdef.add_index(&Name::english("field0"), IndexType::Index); docdef.add_index(&Name::english("field1"), IndexType::Index); - doc.start(); + doc.start(standard_paths()); let values = [ ["a".into(), "a".into()].to_vec(), ["a".into(), "b".into()].to_vec(), @@ -5113,7 +5359,7 @@ mod document_files { let afield: Field = "a".into(); let bfield: Field = "b".into(); assert_eq!(data.len(), 1, "should return one entry:\n{:?}", action); - for doc in data.clone() { + for doc in data.iter() { assert_eq!(doc.get(&Name::english("field0")).unwrap(), afield); assert_eq!(doc.get(&Name::english("field1")).unwrap(), bfield); } @@ -5128,7 +5374,7 @@ mod document_files { TestDocument::new([FieldType::StaticString, FieldType::StaticString].to_vec()); let docdef = doc.get_docdef_mut(); docdef.add_index(&Name::english("field0"), IndexType::Index); - doc.start(); + doc.start(standard_paths()); let values = [ ["a".into(), "a".into()].to_vec(), ["a".into(), "b".into()].to_vec(), @@ -5155,7 +5401,7 @@ mod document_files { let afield: Field = "a".into(); let bfield: Field = "b".into(); assert_eq!(data.len(), 1, "should return one entry:\n{:?}", action); - for doc in data.clone() { + for doc in data.iter() { assert_eq!(doc.get(&Name::english("field0")).unwrap(), afield); assert_eq!(doc.get(&Name::english("field1")).unwrap(), bfield); } @@ -5167,7 +5413,7 @@ mod document_files { #[test] fn errors_on_bad_field_name() { let mut doc = TestDocument::new(Vec::new()); - doc.start(); + doc.start(standard_paths()); let doc_name = doc.get_docdef().get_document_names()[0].clone(); let queue = doc.get_queue(); let rx = doc.get_receiver(); @@ -5192,7 +5438,7 @@ mod document_files { #[test] fn errors_on_bad_field_type() { let mut doc = TestDocument::new([FieldType::Uuid].to_vec()); - doc.start(); + doc.start(standard_paths()); doc.populate([Uuid::nil().into()].to_vec()); let mut calc = Calculation::new(Operand::Equal); calc.add_value("notUUID"); @@ -5215,7 +5461,7 @@ mod document_files { let mut doc = TestDocument::new([FieldType::Uuid].to_vec()); doc.get_docdef_mut() .add_index(&Name::english("field0"), IndexType::Index); - doc.start(); + doc.start(standard_paths()); doc.populate([Uuid::nil().into()].to_vec()); let mut calc = Calculation::new(Operand::Equal); calc.add_value("notUUID"); @@ -5241,7 +5487,7 @@ mod document_files { docdef.add_field(field_name.clone(), FieldType::StaticString); docdef.set_default(&field_name, FieldType::StaticString); let mut test_doc: TestDocument = docdef.into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let rx = test_doc.get_receiver(); let new_doc = Addition::new(); @@ -5252,7 +5498,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1); - for doc in docs.clone() { + for doc in docs.iter() { let expected: Field = "".into(); assert_eq!(doc.get(&field_name).unwrap(), expected); } @@ -5269,7 +5515,7 @@ mod document_files { docdef.add_field(field_name.clone(), FieldType::Uuid); docdef.set_default(&field_name, Uuid::nil()); let mut test_doc: TestDocument = docdef.into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let rx = test_doc.get_receiver(); let new_doc = Addition::new(); @@ -5280,7 +5526,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1); - for doc in docs.clone() { + for doc in docs.iter() { let expected: Field = Uuid::nil().into(); assert_eq!(doc.get(&field_name).unwrap(), expected); } @@ -5297,7 +5543,7 @@ mod document_files { docdef.add_field(field_name.clone(), FieldType::Uuid); docdef.set_default(&field_name, FieldType::Uuid); let mut test_doc: TestDocument = docdef.into(); - test_doc.start(); + test_doc.start(standard_paths()); let queue = test_doc.get_queue(); let rx = test_doc.get_receiver(); let mut new_doc = Addition::new(); @@ -5309,7 +5555,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1); - for doc in docs.clone() { + for doc in docs.iter() { let expected: Field = Uuid::nil().into(); assert_eq!(doc.get(&field_name).unwrap(), expected); } @@ -5328,7 +5574,7 @@ mod document_files { let id = ids.iter().last().unwrap().clone(); ids.remove(&id); let mut doc = TestDocument::new([FieldType::Uuid].to_vec()); - doc.start(); + doc.start(standard_paths()); for id in ids.iter() { doc.populate([id.clone().into()].to_vec()); } @@ -5354,7 +5600,7 @@ mod document_files { #[test] fn changes_information_requested() { let mut doc = TestDocument::new([FieldType::Uuid, FieldType::StaticString].to_vec()); - doc.start(); + doc.start(standard_paths()); let doc_name = doc.get_docdef().get_document_names()[0].clone(); let old = "old"; let new = "new"; @@ -5378,7 +5624,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1, "for {:?}, should have one entry", msg); - for doc in docs.clone() { + for doc in docs.iter() { assert_eq!(doc.get(Name::english("field0")).unwrap(), id.into()); assert_eq!(doc.get(Name::english("field1")).unwrap(), new.into()); } @@ -5393,7 +5639,7 @@ mod document_files { #[test] fn changes_only_the_queried() { let mut doc = TestDocument::new([FieldType::Integer, FieldType::StaticString].to_vec()); - doc.start(); + doc.start(standard_paths()); let doc_name = doc.get_docdef().get_document_names()[0].clone(); let old = "old"; let new = "new"; @@ -5421,7 +5667,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1, "should have one entry"); - for doc in docs.clone() { + for doc in docs.iter() { assert_eq!(doc.get(Name::english("field0")).unwrap(), picked.into()); assert_eq!(doc.get(Name::english("field1")).unwrap(), new.into()); } @@ -5436,11 +5682,21 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), count, "should have one entry"); - for doc in docs.clone() { + for doc in docs.iter() { if doc.get(Name::english("field0")).unwrap() == picked.into() { - assert_eq!(doc.get(Name::english("field1")).unwrap(), new.into()); + assert_eq!( + doc.get(Name::english("field1")).unwrap(), + new.into(), + "{:?}", + docs + ); } else { - assert_eq!(doc.get(Name::english("field1")).unwrap(), old.into()); + assert_eq!( + doc.get(Name::english("field1")).unwrap(), + old.into(), + "{:?}", + docs + ); } } } @@ -5451,7 +5707,7 @@ mod document_files { #[test] fn can_handle_multiple_updates() { let mut doc = TestDocument::new([FieldType::Integer, FieldType::StaticString].to_vec()); - doc.start(); + doc.start(standard_paths()); let doc_name = doc.get_docdef().get_document_names()[0].clone(); let old = "old"; let new = "new"; @@ -5477,7 +5733,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), count, "should have one entry"); - for doc in docs.clone() { + for doc in docs.iter() { assert_eq!(doc.get(Name::english("field0")).unwrap(), picked.into()); assert_eq!(doc.get(Name::english("field1")).unwrap(), new.into()); } @@ -5492,7 +5748,7 @@ mod document_files { #[test] fn update_errors_on_bad_field_name() { let mut doc = TestDocument::new([FieldType::Uuid, FieldType::StaticString].to_vec()); - doc.start(); + doc.start(standard_paths()); let id = Uuid::new_v4(); let old = "old"; let new = "new"; @@ -5515,7 +5771,7 @@ mod document_files { #[test] fn update_errors_on_bad_field_type() { let mut doc = TestDocument::new([FieldType::Uuid, FieldType::StaticString].to_vec()); - doc.start(); + doc.start(standard_paths()); let id = Uuid::new_v4(); let old = "old"; let new = Uuid::nil(); @@ -5552,7 +5808,7 @@ mod document_files { test_doc .get_docdef_mut() .add_index(&Name::english("field0"), IndexType::Unique); - test_doc.start(); + test_doc.start(standard_paths()); let fname = Name::english("field0"); let old = 3; let new = 5; @@ -5578,7 +5834,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1, "should have one entry"); - for doc in docs.clone() { + for doc in docs.iter() { assert_eq!(doc.get(&fname).unwrap(), old.into()); } } @@ -5604,7 +5860,7 @@ mod document_files { test_doc .get_docdef_mut() .add_index(&f0name, IndexType::Unique); - test_doc.start(); + test_doc.start(standard_paths()); let f0data = Uuid::new_v4(); let f1bad_data = "NotUuid"; let f1good_data = Uuid::nil(); @@ -5622,7 +5878,7 @@ mod document_files { match action { MsgAction::Records(docs) => { assert_eq!(docs.len(), 1, "should have one entry"); - for doc in docs.clone() { + for doc in docs.iter() { assert_eq!(doc.get(&f0name).unwrap(), f0data.into()); assert_eq!(doc.get(&f1name).unwrap(), f1good_data.into()); } @@ -5636,7 +5892,7 @@ mod document_files { let fname = Name::english("field0"); let mut doc = TestDocument::new([FieldType::StaticString].to_vec()); doc.get_docdef_mut().add_index(&fname, IndexType::Unique); - doc.start(); + doc.start(standard_paths()); let old = "old"; let new = "new"; let fold: Field = old.into(); @@ -5661,7 +5917,7 @@ mod document_files { match action { MsgAction::Records(data) => { assert_eq!(data.len(), 1); - for doc in data.clone() { + for doc in data.iter() { assert_eq!(doc.get(&fname).unwrap(), fold); } } @@ -5687,7 +5943,7 @@ mod document_files { let f1name = Name::english("field1"); let mut doc = TestDocument::new([FieldType::Uuid, FieldType::StaticString].to_vec()); doc.get_docdef_mut().add_index(&f0name, IndexType::Unique); - doc.start(); + doc.start(standard_paths()); let count = 5; let data = "data"; let mut ids: HashSet = HashSet::new(); @@ -5726,7 +5982,7 @@ mod document_files { match action { MsgAction::Records(data) => { assert_eq!(data.len(), ids.len()); - for doc in data.clone() { + for doc in data.iter() { match doc.get(&f0name).unwrap() { Field::Uuid(id) => { assert!(ids.contains(&id)); @@ -5745,7 +6001,7 @@ mod document_files { fn can_calculate_field_values() { let fname = Name::english("field0"); let mut doc = TestDocument::new([FieldType::DateTime].to_vec()); - doc.start(); + doc.start(standard_paths()); let duration = Duration::from_secs(300); let mut calc = Calculation::new(Operand::Add); calc.add_value(FieldType::DateTime).unwrap(); @@ -5760,7 +6016,7 @@ mod document_files { match action { MsgAction::Records(data) => { assert_eq!(data.len(), 1); - for doc in data.clone() { + for doc in data.iter() { match doc.get(&fname).unwrap() { Field::DateTime(datetime) => assert!(datetime > start && datetime < stop), _ => unreachable!("did not get uuid"), @@ -5775,7 +6031,7 @@ mod document_files { fn can_delete() { let fname = Name::english("field0"); let mut doc = TestDocument::new([FieldType::Integer].to_vec()); - doc.start(); + doc.start(standard_paths()); doc.populate([1.into()].to_vec()); let mut calc = Calculation::new(Operand::Equal); calc.add_value(1); @@ -5789,7 +6045,7 @@ mod document_files { match action { MsgAction::Records(data) => { assert_eq!(data.len(), 1); - for doc in data.clone() { + for doc in data.iter() { match doc.get(&fname).unwrap() { Field::Integer(num) => assert_eq!(num, 1), _ => unreachable!("did not get uuid"), @@ -5811,7 +6067,7 @@ mod document_files { fn does_delete_return_query_errors() { let field_name = Name::english("wrong"); let mut doc = TestDocument::new([FieldType::Integer].to_vec()); - doc.start(); + doc.start(standard_paths()); let mut calc = Calculation::new(Operand::Equal); calc.add_value(CalcValue::Existing(FieldType::Integer)); calc.add_value(1); @@ -5836,7 +6092,7 @@ mod document_files { let value = 1; let mut doc = TestDocument::new([FieldType::Integer].to_vec()); doc.get_docdef_mut().add_index(&fname, IndexType::Unique); - doc.start(); + doc.start(standard_paths()); doc.populate([value.into()].to_vec()); doc.send(Delete::new(Query::new())); doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); @@ -5850,6 +6106,29 @@ mod document_files { _ => unreachable!("got {:?}, should have added entry", action), } } + + #[test] + #[ignore] + fn can_query_trigger_reaction() { + let mut doc = TestDocument::new([FieldType::Integer].to_vec()); + doc.start(standard_paths()); + doc.populate([0.into()].to_vec()); + for i in 0..5 { + let expected: Field = i.try_into().unwrap(); + doc.send(Query::new()).unwrap(); + let result = doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); + let action = result.get_action(); + match action { + MsgAction::Records(data) => { + assert_eq!(data.len(), 1); + for rec in data.iter() { + assert_eq!(rec.get(&Name::english("field0")).unwrap(), expected); + } + } + _ => unreachable!("got {:?}, should have added entry", action), + } + } + } } #[cfg(test)] @@ -6005,8 +6284,10 @@ impl Clock { fn listen(&self) { loop { - self.queue - .send(Message::new(Name::english("clock"), RecordIter::new())); + self.queue.send(Message::new( + Name::english("clock"), + Records::new(Names::new()), + )); sleep(Duration::from_secs(1)); } }