This commit is contained in:
parent
841f935c8d
commit
5bb7f1b108
181
src/message.rs
181
src/message.rs
@ -1417,37 +1417,8 @@ impl Query {
|
||||
self.specifiers.push(spec);
|
||||
}
|
||||
|
||||
fn run(&self, docs: &DocumentFile) -> Result<Reply, MTTError> {
|
||||
let mut reply = Reply::new();
|
||||
let docdef = docs.get_docdef();
|
||||
for specifier in self.specifiers.iter() {
|
||||
match docdef.get_field(&specifier.field_name) {
|
||||
Ok(spec) => {
|
||||
let value_type: FieldType = (&specifier.value).into();
|
||||
let wanted_type = spec.get_type();
|
||||
if &value_type != wanted_type {
|
||||
return Err(MTTError::DocumentFieldWrongDataType(
|
||||
wanted_type.clone(),
|
||||
value_type.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
}
|
||||
for doc in docs.get_documents() {
|
||||
let mut output = true;
|
||||
for specifier in self.specifiers.iter() {
|
||||
let value = doc.get_field(&specifier.field_name).unwrap();
|
||||
if value != &specifier.value {
|
||||
output = false;
|
||||
}
|
||||
}
|
||||
if output {
|
||||
reply.add(doc.clone());
|
||||
}
|
||||
}
|
||||
Ok(reply)
|
||||
fn iter(&self) -> impl Iterator<Item = &Specifier> {
|
||||
self.specifiers.iter()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1594,18 +1565,39 @@ impl Update {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_query(&self) -> &Query {
|
||||
&self.query
|
||||
}
|
||||
|
||||
fn get_query_mut(&mut self) -> &mut Query {
|
||||
&mut self.query
|
||||
}
|
||||
|
||||
fn get_values(&self) -> &Document {
|
||||
&self.values
|
||||
}
|
||||
|
||||
fn get_values_mut(&mut self) -> &mut Document {
|
||||
&mut self.values
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
struct Oid {
|
||||
oid: Uuid,
|
||||
}
|
||||
|
||||
impl Oid {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
oid: Uuid::new_v4(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DocumentFile {
|
||||
docdef: DocDef,
|
||||
docs: Vec<Document>,
|
||||
docs: HashMap<Oid, Document>,
|
||||
queue: Queue,
|
||||
rx: Receiver<Message>,
|
||||
}
|
||||
@ -1614,7 +1606,7 @@ impl DocumentFile {
|
||||
fn new(queue: Queue, rx: Receiver<Message>, docdef: DocDef) -> Self {
|
||||
Self {
|
||||
docdef: docdef,
|
||||
docs: Vec::new(),
|
||||
docs: HashMap::new(),
|
||||
queue: queue,
|
||||
rx: rx,
|
||||
}
|
||||
@ -1676,6 +1668,7 @@ impl DocumentFile {
|
||||
let result = match msg.get_action() {
|
||||
MsgAction::Addition(data) => self.add_document(data),
|
||||
MsgAction::Query(query) => self.query(query),
|
||||
MsgAction::Update(update) => self.update(update),
|
||||
_ => Reply::new().into(),
|
||||
};
|
||||
self.queue.send(msg.response(result)).unwrap();
|
||||
@ -1686,7 +1679,7 @@ impl DocumentFile {
|
||||
&self.docdef
|
||||
}
|
||||
|
||||
fn get_documents<'a>(&self) -> impl Iterator<Item = &Document> {
|
||||
fn get_documents<'a>(&self) -> impl Iterator<Item = (&Oid, &Document)> {
|
||||
self.docs.iter()
|
||||
}
|
||||
|
||||
@ -1723,18 +1716,77 @@ impl DocumentFile {
|
||||
},
|
||||
}
|
||||
}
|
||||
self.docs.push(holder.clone());
|
||||
let mut oid = Oid::new();
|
||||
while self.docs.contains_key(&oid) {
|
||||
oid = Oid::new();
|
||||
}
|
||||
self.docs.insert(oid, holder.clone());
|
||||
let mut reply = Reply::new();
|
||||
reply.add(holder);
|
||||
reply.into()
|
||||
}
|
||||
|
||||
fn run_query(&self, query: &Query) -> Result<Vec<Oid>, MTTError> {
|
||||
let mut reply = Reply::new();
|
||||
for specifier in query.iter() {
|
||||
match self.docdef.get_field(&specifier.field_name) {
|
||||
Ok(spec) => {
|
||||
let value_type: FieldType = (&specifier.value).into();
|
||||
let wanted_type = spec.get_type();
|
||||
if &value_type != wanted_type {
|
||||
return Err(MTTError::DocumentFieldWrongDataType(
|
||||
wanted_type.clone(),
|
||||
value_type.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
}
|
||||
let mut result = Vec::new();
|
||||
for (oid, doc) in self.get_documents() {
|
||||
let mut output = true;
|
||||
for specifier in query.iter() {
|
||||
let value = doc.get_field(&specifier.field_name).unwrap();
|
||||
if value != &specifier.value {
|
||||
output = false;
|
||||
}
|
||||
}
|
||||
if output {
|
||||
result.push(oid.clone());
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn query(&self, query: &Query) -> MsgAction {
|
||||
match query.run(self) {
|
||||
Ok(reply) => reply.into(),
|
||||
match self.run_query(query) {
|
||||
Ok(result) => {
|
||||
let mut reply = Reply::new();
|
||||
for oid in result.iter() {
|
||||
reply.add(self.docs.get(oid).unwrap().clone());
|
||||
}
|
||||
reply.into()
|
||||
}
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, update: &Update) -> MsgAction {
|
||||
let oids = match self.run_query(update.get_query()) {
|
||||
Ok(result) => result,
|
||||
Err(err) => return err.into(),
|
||||
};
|
||||
let mut reply = Reply::new();
|
||||
for oid in oids.iter() {
|
||||
let doc = self.docs.get_mut(oid).unwrap();
|
||||
for (key, value) in update.get_values().iter() {
|
||||
doc.add_field(key.clone(), value.clone());
|
||||
}
|
||||
reply.add(doc.clone());
|
||||
}
|
||||
reply.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -2303,6 +2355,61 @@ mod document_files {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn changes_information_requested() {
|
||||
let (mut docdef, doc_name) =
|
||||
create_docdef([FieldType::Uuid, FieldType::StaticString].to_vec());
|
||||
let (mut queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes());
|
||||
let id = Uuid::new_v4();
|
||||
let old = "old";
|
||||
let new = "new";
|
||||
let mut addition = Addition::new();
|
||||
addition.add_field("field0".to_string(), id.clone());
|
||||
addition.add_field("field1".to_string(), old);
|
||||
let msg = Message::new(doc_name.clone(), addition);
|
||||
queue.send(msg).unwrap();
|
||||
rx.recv_timeout(TIMEOUT).unwrap();
|
||||
let mut update = Update::new();
|
||||
update
|
||||
.get_query_mut()
|
||||
.add_specifier("field0".to_string(), Operand::Equal, id.clone());
|
||||
update.get_values_mut().add_field("field1".to_string(), new);
|
||||
let msg = Message::new(doc_name.clone(), update);
|
||||
queue.send(msg).unwrap();
|
||||
let result = rx.recv_timeout(TIMEOUT).unwrap();
|
||||
let action = result.get_action();
|
||||
match action {
|
||||
MsgAction::Reply(docs) => {
|
||||
assert_eq!(docs.len(), 1);
|
||||
let expected_id: Field = id.into();
|
||||
let output: Field = new.into();
|
||||
for doc in docs.iter() {
|
||||
assert_eq!(doc.get_field("field0").unwrap(), &expected_id);
|
||||
assert_eq!(doc.get_field("field1").unwrap(), &output);
|
||||
}
|
||||
}
|
||||
_ => unreachable!("got {:?}: should have gotten a reply", action),
|
||||
}
|
||||
let mut query = Query::new();
|
||||
query.add_specifier("field0".to_string(), Operand::Equal, id.clone());
|
||||
let msg = Message::new(doc_name, query);
|
||||
queue.send(msg).unwrap();
|
||||
let result = rx.recv_timeout(TIMEOUT).unwrap();
|
||||
let action = result.get_action();
|
||||
match action {
|
||||
MsgAction::Reply(docs) => {
|
||||
assert_eq!(docs.len(), 1);
|
||||
let expected_id: Field = id.into();
|
||||
let output: Field = new.into();
|
||||
for doc in docs.iter() {
|
||||
assert_eq!(doc.get_field("field0").unwrap(), &expected_id);
|
||||
assert_eq!(doc.get_field("field1").unwrap(), &output);
|
||||
}
|
||||
}
|
||||
_ => unreachable!("got {:?}: should have gotten a reply", action),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user