Made query selective.
This commit is contained in:
parent
50481c18ad
commit
73b4b866d4
141
src/message.rs
141
src/message.rs
@ -959,7 +959,16 @@ enum FieldType {
|
||||
Uuid,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
impl From<&Field> for FieldType {
|
||||
fn from(value: &Field) -> Self {
|
||||
match value {
|
||||
Field::StaticString(_) => Self::StaticString,
|
||||
Field::Uuid(_) => Self::Uuid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
enum Field {
|
||||
StaticString(String),
|
||||
Uuid(Uuid),
|
||||
@ -967,10 +976,7 @@ enum Field {
|
||||
|
||||
impl Field {
|
||||
fn get_type(&self) -> FieldType {
|
||||
match self {
|
||||
Self::StaticString(_) => FieldType::StaticString,
|
||||
Self::Uuid(_) => FieldType::Uuid,
|
||||
}
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1209,11 +1215,65 @@ mod docdefs {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Query;
|
||||
enum Operand {
|
||||
Equal,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Specifier {
|
||||
field_name: String,
|
||||
operation: Operand,
|
||||
value: Field,
|
||||
}
|
||||
|
||||
impl Specifier {
|
||||
fn new<F>(name: String, op: Operand, value: F) -> Self
|
||||
where
|
||||
F: Into<Field>,
|
||||
{
|
||||
Self {
|
||||
field_name: name,
|
||||
operation: op,
|
||||
value: value.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Query {
|
||||
specifiers: Vec<Specifier>,
|
||||
}
|
||||
|
||||
impl Query {
|
||||
fn new() -> Self {
|
||||
Self {}
|
||||
Self {
|
||||
specifiers: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_specifier<F>(&mut self, name: String, op: Operand, value: F)
|
||||
where
|
||||
F: Into<Field>,
|
||||
{
|
||||
let spec = Specifier::new(name, op, value);
|
||||
self.specifiers.push(spec);
|
||||
}
|
||||
|
||||
fn run(&self, docs: &DocumentFile) -> Reply {
|
||||
let mut reply = Reply::new();
|
||||
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());
|
||||
}
|
||||
}
|
||||
reply
|
||||
}
|
||||
}
|
||||
|
||||
@ -1234,14 +1294,9 @@ impl Reply {
|
||||
fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Reply {
|
||||
type Item = Document;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.data.into_iter()
|
||||
fn iter(&self) -> impl Iterator<Item = &Document> {
|
||||
self.data.iter()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1275,7 +1330,7 @@ mod replies {
|
||||
let mut reply = Reply::new();
|
||||
reply.add(doc1);
|
||||
reply.add(doc2);
|
||||
let mut reply_iter = reply.into_iter();
|
||||
let mut reply_iter = reply.iter();
|
||||
let mut result1 = reply_iter.next().unwrap();
|
||||
match result1.get_field(&fieldname).unwrap() {
|
||||
Field::StaticString(output) => assert_eq!(output, "one"),
|
||||
@ -1432,6 +1487,10 @@ impl DocumentFile {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_documents<'a>(&self) -> impl Iterator<Item = &Document> {
|
||||
self.docs.iter()
|
||||
}
|
||||
|
||||
fn add_document(&mut self, addition: &Addition) -> MsgAction {
|
||||
let mut holder = Document::new();
|
||||
let doc = addition.get_document();
|
||||
@ -1464,11 +1523,7 @@ impl DocumentFile {
|
||||
}
|
||||
|
||||
fn query(&self, query: &Query) -> MsgAction {
|
||||
let mut reply = Reply::new();
|
||||
for doc in self.docs.iter() {
|
||||
reply.add(doc.clone());
|
||||
}
|
||||
reply.into()
|
||||
query.run(self).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1609,7 +1664,7 @@ mod document_files {
|
||||
match result.get_action() {
|
||||
MsgAction::Reply(output) => {
|
||||
assert_eq!(output.len(), 1);
|
||||
let holder = output.clone().into_iter().next().unwrap();
|
||||
let holder = output.iter().next().unwrap();
|
||||
match holder.get_field(name) {
|
||||
Some(field) => match field {
|
||||
Field::Uuid(store) => assert_eq!(store, &data),
|
||||
@ -1630,7 +1685,7 @@ mod document_files {
|
||||
match result.get_action() {
|
||||
MsgAction::Reply(output) => {
|
||||
assert_eq!(output.len(), 1);
|
||||
let holder = output.clone().into_iter().next().unwrap();
|
||||
let holder = output.iter().next().unwrap();
|
||||
match holder.get_field(name) {
|
||||
Some(field) => match field {
|
||||
Field::Uuid(store) => assert_eq!(store, &data),
|
||||
@ -1750,6 +1805,48 @@ mod document_files {
|
||||
_ => unreachable!("got {:?}: should have been an error", result.get_action()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_query_return_related_entries() {
|
||||
let doc_name = "query";
|
||||
let (queue, rx) = test_doc(doc_name, create_docdef(2), standard_routes());
|
||||
let field0 = Uuid::new_v4();
|
||||
let field1 = Uuid::new_v4();
|
||||
for _ in 0..3 {
|
||||
let mut addition = Addition::new();
|
||||
addition.add_field("field0".to_string(), Uuid::new_v4());
|
||||
addition.add_field("field1".to_string(), Uuid::new_v4());
|
||||
let msg = Message::new(doc_name, addition);
|
||||
queue.send(msg).unwrap();
|
||||
rx.recv_timeout(TIMEOUT).unwrap();
|
||||
}
|
||||
let mut addition = Addition::new();
|
||||
addition.add_field("field0".to_string(), field0.clone());
|
||||
addition.add_field("field1".to_string(), field1.clone());
|
||||
let msg = Message::new(doc_name, addition);
|
||||
queue.send(msg).unwrap();
|
||||
rx.recv_timeout(TIMEOUT).unwrap();
|
||||
for _ in 0..3 {
|
||||
let mut addition = Addition::new();
|
||||
addition.add_field("field0".to_string(), Uuid::new_v4());
|
||||
addition.add_field("field1".to_string(), Uuid::new_v4());
|
||||
let msg = Message::new(doc_name, addition);
|
||||
queue.send(msg).unwrap();
|
||||
rx.recv_timeout(TIMEOUT).unwrap();
|
||||
}
|
||||
let mut query = Query::new();
|
||||
query.add_specifier("field0".to_string(), Operand::Equal, field0.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(data) => {
|
||||
assert_eq!(data.len(), 1, "should return one entry");
|
||||
}
|
||||
_ => unreachable!("got {:?}: should have been a reply", action),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user