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);
|
self.specifiers.push(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, docs: &DocumentFile) -> Result<Reply, MTTError> {
|
fn iter(&self) -> impl Iterator<Item = &Specifier> {
|
||||||
let mut reply = Reply::new();
|
self.specifiers.iter()
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1594,18 +1565,39 @@ impl Update {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_query(&self) -> &Query {
|
||||||
|
&self.query
|
||||||
|
}
|
||||||
|
|
||||||
fn get_query_mut(&mut self) -> &mut Query {
|
fn get_query_mut(&mut self) -> &mut Query {
|
||||||
&mut self.query
|
&mut self.query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_values(&self) -> &Document {
|
||||||
|
&self.values
|
||||||
|
}
|
||||||
|
|
||||||
fn get_values_mut(&mut self) -> &mut Document {
|
fn get_values_mut(&mut self) -> &mut Document {
|
||||||
&mut self.values
|
&mut self.values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||||
|
struct Oid {
|
||||||
|
oid: Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Oid {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
oid: Uuid::new_v4(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct DocumentFile {
|
struct DocumentFile {
|
||||||
docdef: DocDef,
|
docdef: DocDef,
|
||||||
docs: Vec<Document>,
|
docs: HashMap<Oid, Document>,
|
||||||
queue: Queue,
|
queue: Queue,
|
||||||
rx: Receiver<Message>,
|
rx: Receiver<Message>,
|
||||||
}
|
}
|
||||||
@ -1614,7 +1606,7 @@ impl DocumentFile {
|
|||||||
fn new(queue: Queue, rx: Receiver<Message>, docdef: DocDef) -> Self {
|
fn new(queue: Queue, rx: Receiver<Message>, docdef: DocDef) -> Self {
|
||||||
Self {
|
Self {
|
||||||
docdef: docdef,
|
docdef: docdef,
|
||||||
docs: Vec::new(),
|
docs: HashMap::new(),
|
||||||
queue: queue,
|
queue: queue,
|
||||||
rx: rx,
|
rx: rx,
|
||||||
}
|
}
|
||||||
@ -1676,6 +1668,7 @@ impl DocumentFile {
|
|||||||
let result = match msg.get_action() {
|
let result = match msg.get_action() {
|
||||||
MsgAction::Addition(data) => self.add_document(data),
|
MsgAction::Addition(data) => self.add_document(data),
|
||||||
MsgAction::Query(query) => self.query(query),
|
MsgAction::Query(query) => self.query(query),
|
||||||
|
MsgAction::Update(update) => self.update(update),
|
||||||
_ => Reply::new().into(),
|
_ => Reply::new().into(),
|
||||||
};
|
};
|
||||||
self.queue.send(msg.response(result)).unwrap();
|
self.queue.send(msg.response(result)).unwrap();
|
||||||
@ -1686,7 +1679,7 @@ impl DocumentFile {
|
|||||||
&self.docdef
|
&self.docdef
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_documents<'a>(&self) -> impl Iterator<Item = &Document> {
|
fn get_documents<'a>(&self) -> impl Iterator<Item = (&Oid, &Document)> {
|
||||||
self.docs.iter()
|
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();
|
let mut reply = Reply::new();
|
||||||
reply.add(holder);
|
reply.add(holder);
|
||||||
reply.into()
|
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 {
|
fn query(&self, query: &Query) -> MsgAction {
|
||||||
match query.run(self) {
|
match self.run_query(query) {
|
||||||
Ok(reply) => reply.into(),
|
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(),
|
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)]
|
#[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)]
|
#[cfg(test)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user