diff --git a/lib/src/sparql/dataset.rs b/lib/src/sparql/dataset.rs index 7db04505..e8c9f149 100644 --- a/lib/src/sparql/dataset.rs +++ b/lib/src/sparql/dataset.rs @@ -37,11 +37,11 @@ impl DatasetView { predicate: Option<&EncodedTerm>, object: Option<&EncodedTerm>, graph_name: Option<&EncodedTerm>, - // ) -> impl Iterator> + 'static { - ) -> Vec { + ) -> impl Iterator> + 'static { + // ) -> Vec { self.reader .quads_for_pattern(subject, predicate, object, graph_name) - // .map(|t| t.map_err(Into::into)) + .map(|t| t.map_err(Into::into)) } #[allow(clippy::needless_collect)] @@ -51,104 +51,104 @@ impl DatasetView { predicate: Option<&EncodedTerm>, object: Option<&EncodedTerm>, graph_name: Option<&EncodedTerm>, - // ) -> Box>> { - ) -> Vec { - return Vec::new(); - // if let Some(graph_name) = graph_name { - // if graph_name.is_default_graph() { - // if let Some(default_graph_graphs) = &self.dataset.default { - // if default_graph_graphs.len() == 1 { - // // Single graph optimization - // Box::new( - // self.store_encoded_quads_for_pattern( - // subject, - // predicate, - // object, - // Some(&default_graph_graphs[0]), - // ) - // .map(|quad| { - // let quad = quad?; - // Ok(EncodedQuad::new( - // quad.subject, - // quad.predicate, - // quad.object, - // EncodedTerm::DefaultGraph, - // )) - // }), - // ) - // } else { - // let iters = default_graph_graphs - // .iter() - // .map(|graph_name| { - // self.store_encoded_quads_for_pattern( - // subject, - // predicate, - // object, - // Some(graph_name), - // ) - // }) - // .collect::>(); - // Box::new(iters.into_iter().flatten().map(|quad| { - // let quad = quad?; - // Ok(EncodedQuad::new( - // quad.subject, - // quad.predicate, - // quad.object, - // EncodedTerm::DefaultGraph, - // )) - // })) - // } - // } else { - // Box::new( - // self.store_encoded_quads_for_pattern(subject, predicate, object, None) - // .map(|quad| { - // let quad = quad?; - // Ok(EncodedQuad::new( - // quad.subject, - // quad.predicate, - // quad.object, - // EncodedTerm::DefaultGraph, - // )) - // }), - // ) - // } - // } else if self - // .dataset - // .named - // .as_ref() - // .map_or(true, |d| d.contains(graph_name)) - // { - // Box::new(self.store_encoded_quads_for_pattern( - // subject, - // predicate, - // object, - // Some(graph_name), - // )) - // } else { - // Box::new(empty()) - // } - // } else if let Some(named_graphs) = &self.dataset.named { - // let iters = named_graphs - // .iter() - // .map(|graph_name| { - // self.store_encoded_quads_for_pattern( - // subject, - // predicate, - // object, - // Some(graph_name), - // ) - // }) - // .collect::>(); - // Box::new(iters.into_iter().flatten()) - // } else { - // Box::new( - // self.store_encoded_quads_for_pattern(subject, predicate, object, None) - // .filter(|quad| match quad { - // Err(_) => true, - // Ok(quad) => !quad.graph_name.is_default_graph(), - // }), - // ) - // } + ) -> Box>> { + // ) -> Vec { + // return Vec::new(); + if let Some(graph_name) = graph_name { + if graph_name.is_default_graph() { + if let Some(default_graph_graphs) = &self.dataset.default { + if default_graph_graphs.len() == 1 { + // Single graph optimization + Box::new( + self.store_encoded_quads_for_pattern( + subject, + predicate, + object, + Some(&default_graph_graphs[0]), + ) + .map(|quad| { + let quad = quad?; + Ok(EncodedQuad::new( + quad.subject, + quad.predicate, + quad.object, + EncodedTerm::DefaultGraph, + )) + }), + ) + } else { + let iters = default_graph_graphs + .iter() + .map(|graph_name| { + self.store_encoded_quads_for_pattern( + subject, + predicate, + object, + Some(graph_name), + ) + }) + .collect::>(); + Box::new(iters.into_iter().flatten().map(|quad| { + let quad = quad?; + Ok(EncodedQuad::new( + quad.subject, + quad.predicate, + quad.object, + EncodedTerm::DefaultGraph, + )) + })) + } + } else { + Box::new( + self.store_encoded_quads_for_pattern(subject, predicate, object, None) + .map(|quad| { + let quad = quad?; + Ok(EncodedQuad::new( + quad.subject, + quad.predicate, + quad.object, + EncodedTerm::DefaultGraph, + )) + }), + ) + } + } else if self + .dataset + .named + .as_ref() + .map_or(true, |d| d.contains(graph_name)) + { + Box::new(self.store_encoded_quads_for_pattern( + subject, + predicate, + object, + Some(graph_name), + )) + } else { + Box::new(empty()) + } + } else if let Some(named_graphs) = &self.dataset.named { + let iters = named_graphs + .iter() + .map(|graph_name| { + self.store_encoded_quads_for_pattern( + subject, + predicate, + object, + Some(graph_name), + ) + }) + .collect::>(); + Box::new(iters.into_iter().flatten()) + } else { + Box::new( + self.store_encoded_quads_for_pattern(subject, predicate, object, None) + .filter(|quad| match quad { + Err(_) => true, + Ok(quad) => !quad.graph_name.is_default_graph(), + }), + ) + } } pub fn encode_term<'a>(&self, term: impl Into>) -> EncodedTerm { diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index 53bee962..8a49643d 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -214,14 +214,16 @@ impl SimpleEvaluator { let predicate = predicate.clone(); let object = object.clone(); let graph_name = graph_name.clone(); - Box::new(iter.into_iter().filter_map(move |quad| { - let mut new_tuple = from.clone(); - // put_pattern_value(&subject, quad.subject, &mut new_tuple)?; - // TODO - // put_pattern_value(&predicate, quad.predicate, &mut new_tuple)?; - // put_pattern_value(&object, quad.object, &mut new_tuple)?; - // put_pattern_value(&graph_name, quad.graph_name, &mut new_tuple)?; - Some(Ok(new_tuple)) + Box::new(iter.filter_map(move |quad| match quad { + Ok(quad) => { + let mut new_tuple = from.clone(); + put_pattern_value(&subject, quad.subject, &mut new_tuple)?; + put_pattern_value(&predicate, quad.predicate, &mut new_tuple)?; + put_pattern_value(&object, quad.object, &mut new_tuple)?; + put_pattern_value(&graph_name, quad.graph_name, &mut new_tuple)?; + Some(Ok(new_tuple)) + } + Err(error) => Some(Err(error)), })) }) } @@ -3154,9 +3156,8 @@ impl PathEvaluator { Some(end), Some(graph_name), ) - .into_iter() .next() - // .transpose()? + .transpose()? .is_some(), PlanPropertyPath::Reverse(p) => self.eval_closed_in_graph(p, end, start, graph_name)?, PlanPropertyPath::Sequence(a, b) => self @@ -3202,16 +3203,15 @@ impl PathEvaluator { PlanPropertyPath::NegatedPropertySet(ps) => self .dataset .encoded_quads_for_pattern(Some(start), None, Some(end), Some(graph_name)) - .into_iter() - .find_map(move |t| { - // Ok(t) => { - // if ps.iter().any(|p| p.encoded == t.predicate) { - // None - // } else { - Some(Ok(())) - // } - // } - // Err(e) => Some(Err(e)), + .find_map(move |t| match t { + Ok(t) => { + if ps.iter().any(|p| p.encoded == t.predicate) { + None + } else { + Some(Ok(())) + } + } + Err(e) => Some(Err(e)), }) .transpose()? .is_some(), @@ -3223,100 +3223,97 @@ impl PathEvaluator { path: &PlanPropertyPath, start: &EncodedTerm, end: &EncodedTerm, - // ) -> Box>> { - ) -> Vec { - return Vec::new(); - // match path { - // PlanPropertyPath::Path(p) => Box::new( - // self.dataset - // .encoded_quads_for_pattern(Some(start), Some(&p.encoded), Some(end), None) - // .into_iter() - // .map(|t| Ok(t.graph_name)), - // ), - // PlanPropertyPath::Reverse(p) => self.eval_closed_in_unknown_graph(p, end, start), - // PlanPropertyPath::Sequence(a, b) => { - // let eval = self.clone(); - // let b = Rc::clone(b); - // let end = end.clone(); - // Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok( - // move |(middle, graph_name)| { - // eval.eval_closed_in_graph(&b, &middle, &end, &graph_name) - // .map(|is_found| is_found.then(|| graph_name)) - // .transpose() - // }, - // )) - // } - // PlanPropertyPath::Alternative(a, b) => Box::new(hash_deduplicate( - // self.eval_closed_in_unknown_graph(a, start, end) - // .chain(self.eval_closed_in_unknown_graph(b, start, end)), - // )), - // PlanPropertyPath::ZeroOrMore(p) => { - // let eval = self.clone(); - // let start2 = start.clone(); - // let end = end.clone(); - // let p = Rc::clone(p); - // self.run_if_term_is_a_dataset_node(start, move |graph_name| { - // look_in_transitive_closure( - // Some(Ok(start2.clone())), - // |e| eval.eval_from_in_graph(&p, &e, &graph_name), - // &end, - // ) - // .map(|is_found| is_found.then(|| graph_name)) - // .transpose() - // }) - // } - // PlanPropertyPath::OneOrMore(p) => { - // let eval = self.clone(); - // let end = end.clone(); - // let p = Rc::clone(p); - // Box::new( - // self.eval_from_in_unknown_graph(&p, start) - // .filter_map(move |r| { - // r.and_then(|(start, graph_name)| { - // look_in_transitive_closure( - // Some(Ok(start)), - // |e| eval.eval_from_in_graph(&p, &e, &graph_name), - // &end, - // ) - // .map(|is_found| is_found.then(|| graph_name)) - // }) - // .transpose() - // }), - // ) - // } - // PlanPropertyPath::ZeroOrOne(p) => { - // if start == end { - // self.run_if_term_is_a_dataset_node(start, |graph_name| Some(Ok(graph_name))) - // } else { - // let eval = self.clone(); - // let start2 = start.clone(); - // let end = end.clone(); - // let p = Rc::clone(p); - // self.run_if_term_is_a_dataset_node(start, move |graph_name| { - // eval.eval_closed_in_graph(&p, &start2, &end, &graph_name) - // .map(|is_found| is_found.then(|| graph_name)) - // .transpose() - // }) - // } - // } - // PlanPropertyPath::NegatedPropertySet(ps) => { - // let ps = Rc::clone(ps); - // Box::new( - // self.dataset - // .encoded_quads_for_pattern(Some(start), None, Some(end), None) - // .filter_map(move |t| match t { - // Ok(t) => { - // if ps.iter().any(|p| p.encoded == t.predicate) { - // None - // } else { - // Some(Ok(t.graph_name)) - // } - // } - // Err(e) => Some(Err(e)), - // }), - // ) - // } - // } + ) -> Box>> { + match path { + PlanPropertyPath::Path(p) => Box::new( + self.dataset + .encoded_quads_for_pattern(Some(start), Some(&p.encoded), Some(end), None) + .map(|t| Ok(t?.graph_name)), + ), + PlanPropertyPath::Reverse(p) => self.eval_closed_in_unknown_graph(p, end, start), + PlanPropertyPath::Sequence(a, b) => { + let eval = self.clone(); + let b = Rc::clone(b); + let end = end.clone(); + Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok( + move |(middle, graph_name)| { + eval.eval_closed_in_graph(&b, &middle, &end, &graph_name) + .map(|is_found| is_found.then(|| graph_name)) + .transpose() + }, + )) + } + PlanPropertyPath::Alternative(a, b) => Box::new(hash_deduplicate( + self.eval_closed_in_unknown_graph(a, start, end) + .chain(self.eval_closed_in_unknown_graph(b, start, end)), + )), + PlanPropertyPath::ZeroOrMore(p) => { + let eval = self.clone(); + let start2 = start.clone(); + let end = end.clone(); + let p = Rc::clone(p); + self.run_if_term_is_a_dataset_node(start, move |graph_name| { + look_in_transitive_closure( + Some(Ok(start2.clone())), + |e| eval.eval_from_in_graph(&p, &e, &graph_name), + &end, + ) + .map(|is_found| is_found.then(|| graph_name)) + .transpose() + }) + } + PlanPropertyPath::OneOrMore(p) => { + let eval = self.clone(); + let end = end.clone(); + let p = Rc::clone(p); + Box::new( + self.eval_from_in_unknown_graph(&p, start) + .filter_map(move |r| { + r.and_then(|(start, graph_name)| { + look_in_transitive_closure( + Some(Ok(start)), + |e| eval.eval_from_in_graph(&p, &e, &graph_name), + &end, + ) + .map(|is_found| is_found.then(|| graph_name)) + }) + .transpose() + }), + ) + } + PlanPropertyPath::ZeroOrOne(p) => { + if start == end { + self.run_if_term_is_a_dataset_node(start, |graph_name| Some(Ok(graph_name))) + } else { + let eval = self.clone(); + let start2 = start.clone(); + let end = end.clone(); + let p = Rc::clone(p); + self.run_if_term_is_a_dataset_node(start, move |graph_name| { + eval.eval_closed_in_graph(&p, &start2, &end, &graph_name) + .map(|is_found| is_found.then(|| graph_name)) + .transpose() + }) + } + } + PlanPropertyPath::NegatedPropertySet(ps) => { + let ps = Rc::clone(ps); + Box::new( + self.dataset + .encoded_quads_for_pattern(Some(start), None, Some(end), None) + .filter_map(move |t| match t { + Ok(t) => { + if ps.iter().any(|p| p.encoded == t.predicate) { + None + } else { + Some(Ok(t.graph_name)) + } + } + Err(e) => Some(Err(e)), + }), + ) + } + } } fn eval_from_in_graph( @@ -3324,170 +3321,167 @@ impl PathEvaluator { path: &PlanPropertyPath, start: &EncodedTerm, graph_name: &EncodedTerm, - // ) -> Box>> { - ) -> Vec { - Vec::new() + ) -> Box>> { + match path { + PlanPropertyPath::Path(p) => Box::new( + self.dataset + .encoded_quads_for_pattern( + Some(start), + Some(&p.encoded), + None, + Some(graph_name), + ) + .map(|t| Ok(t?.object)), + ), + PlanPropertyPath::Reverse(p) => self.eval_to_in_graph(p, start, graph_name), + PlanPropertyPath::Sequence(a, b) => { + let eval = self.clone(); + let b = Rc::clone(b); + let graph_name2 = graph_name.clone(); + Box::new( + self.eval_from_in_graph(a, start, graph_name) + .flat_map_ok(move |middle| { + eval.eval_from_in_graph(&b, &middle, &graph_name2) + }), + ) + } + PlanPropertyPath::Alternative(a, b) => Box::new(hash_deduplicate( + self.eval_from_in_graph(a, start, graph_name) + .chain(self.eval_from_in_graph(b, start, graph_name)), + )), + PlanPropertyPath::ZeroOrMore(p) => { + self.run_if_term_is_a_graph_node(start, graph_name, || { + let eval = self.clone(); + let p = Rc::clone(p); + let graph_name2 = graph_name.clone(); + transitive_closure(Some(Ok(start.clone())), move |e| { + eval.eval_from_in_graph(&p, &e, &graph_name2) + }) + }) + } + PlanPropertyPath::OneOrMore(p) => { + let eval = self.clone(); + let p = Rc::clone(p); + let graph_name2 = graph_name.clone(); + Box::new(transitive_closure( + self.eval_from_in_graph(&p, start, graph_name), + move |e| eval.eval_from_in_graph(&p, &e, &graph_name2), + )) + } + PlanPropertyPath::ZeroOrOne(p) => { + self.run_if_term_is_a_graph_node(start, graph_name, || { + hash_deduplicate( + once(Ok(start.clone())) + .chain(self.eval_from_in_graph(p, start, graph_name)), + ) + }) + } + PlanPropertyPath::NegatedPropertySet(ps) => { + let ps = Rc::clone(ps); + Box::new( + self.dataset + .encoded_quads_for_pattern(Some(start), None, None, Some(graph_name)) + .filter_map(move |t| match t { + Ok(t) => { + if ps.iter().any(|p| p.encoded == t.predicate) { + None + } else { + Some(Ok(t.object)) + } + } + Err(e) => Some(Err(e)), + }), + ) + } + } } - // match path { - // PlanPropertyPath::Path(p) => Box::new( - // self.dataset - // .encoded_quads_for_pattern( - // Some(start), - // Some(&p.encoded), - // None, - // Some(graph_name), - // ) - // .map(|t| Ok(t?.object)), - // ), - // PlanPropertyPath::Reverse(p) => self.eval_to_in_graph(p, start, graph_name), - // PlanPropertyPath::Sequence(a, b) => { - // let eval = self.clone(); - // let b = Rc::clone(b); - // let graph_name2 = graph_name.clone(); - // Box::new( - // self.eval_from_in_graph(a, start, graph_name) - // .flat_map_ok(move |middle| { - // eval.eval_from_in_graph(&b, &middle, &graph_name2) - // }), - // ) - // } - // PlanPropertyPath::Alternative(a, b) => Box::new(hash_deduplicate( - // self.eval_from_in_graph(a, start, graph_name) - // .chain(self.eval_from_in_graph(b, start, graph_name)), - // )), - // PlanPropertyPath::ZeroOrMore(p) => { - // self.run_if_term_is_a_graph_node(start, graph_name, || { - // let eval = self.clone(); - // let p = Rc::clone(p); - // let graph_name2 = graph_name.clone(); - // transitive_closure(Some(Ok(start.clone())), move |e| { - // eval.eval_from_in_graph(&p, &e, &graph_name2) - // }) - // }) - // } - // PlanPropertyPath::OneOrMore(p) => { - // let eval = self.clone(); - // let p = Rc::clone(p); - // let graph_name2 = graph_name.clone(); - // Box::new(transitive_closure( - // self.eval_from_in_graph(&p, start, graph_name), - // move |e| eval.eval_from_in_graph(&p, &e, &graph_name2), - // )) - // } - // PlanPropertyPath::ZeroOrOne(p) => { - // self.run_if_term_is_a_graph_node(start, graph_name, || { - // hash_deduplicate( - // once(Ok(start.clone())) - // .chain(self.eval_from_in_graph(p, start, graph_name)), - // ) - // }) - // } - // PlanPropertyPath::NegatedPropertySet(ps) => { - // let ps = Rc::clone(ps); - // Box::new( - // self.dataset - // .encoded_quads_for_pattern(Some(start), None, None, Some(graph_name)) - // .filter_map(move |t| match t { - // Ok(t) => { - // if ps.iter().any(|p| p.encoded == t.predicate) { - // None - // } else { - // Some(Ok(t.object)) - // } - // } - // Err(e) => Some(Err(e)), - // }), - // ) - // } - // } - // } fn eval_from_in_unknown_graph( &self, path: &PlanPropertyPath, start: &EncodedTerm, - // ) -> Box>> { - // match path { - // PlanPropertyPath::Path(p) => Box::new( - // self.dataset - // .encoded_quads_for_pattern(Some(start), Some(&p.encoded), None, None) - // .map(|t| { - // let t = t?; - // Ok((t.object, t.graph_name)) - // }), - // ), - // PlanPropertyPath::Reverse(p) => self.eval_to_in_unknown_graph(p, start), - // PlanPropertyPath::Sequence(a, b) => { - // let eval = self.clone(); - // let b = Rc::clone(b); - // Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok( - // move |(middle, graph_name)| { - // eval.eval_from_in_graph(&b, &middle, &graph_name) - // .map(move |end| Ok((end?, graph_name.clone()))) - // }, - // )) - // } - // PlanPropertyPath::Alternative(a, b) => Box::new(hash_deduplicate( - // self.eval_from_in_unknown_graph(a, start) - // .chain(self.eval_from_in_unknown_graph(b, start)), - // )), - // PlanPropertyPath::ZeroOrMore(p) => { - // let start2 = start.clone(); - // let eval = self.clone(); - // let p = Rc::clone(p); - // self.run_if_term_is_a_dataset_node(start, move |graph_name| { - // let eval = eval.clone(); - // let p = Rc::clone(&p); - // let graph_name2 = graph_name.clone(); - // transitive_closure(Some(Ok(start2.clone())), move |e| { - // eval.eval_from_in_graph(&p, &e, &graph_name2) - // }) - // .map(move |e| Ok((e?, graph_name.clone()))) - // }) - // } - // PlanPropertyPath::OneOrMore(p) => { - // let eval = self.clone(); - // let p = Rc::clone(p); - // Box::new(transitive_closure( - // self.eval_from_in_unknown_graph(&p, start), - // move |(e, graph_name)| { - // eval.eval_from_in_graph(&p, &e, &graph_name) - // .map(move |e| Ok((e?, graph_name.clone()))) - // }, - // )) - // } - // PlanPropertyPath::ZeroOrOne(p) => { - // let eval = self.clone(); - // let start2 = start.clone(); - // let p = Rc::clone(p); - // self.run_if_term_is_a_dataset_node(start, move |graph_name| { - // hash_deduplicate(once(Ok(start2.clone())).chain(eval.eval_from_in_graph( - // &p, - // &start2, - // &graph_name, - // ))) - // .map(move |e| Ok((e?, graph_name.clone()))) - // }) - // } - // PlanPropertyPath::NegatedPropertySet(ps) => { - // let ps = Rc::clone(ps); - // Box::new( - // self.dataset - // .encoded_quads_for_pattern(Some(start), None, None, None) - // .filter_map(move |t| match t { - // Ok(t) => { - // if ps.iter().any(|p| p.encoded == t.predicate) { - // None - // } else { - // Some(Ok((t.object, t.graph_name))) - // } - // } - // Err(e) => Some(Err(e)), - // }), - // ) - // } - // } - // } + ) -> Box>> { + match path { + PlanPropertyPath::Path(p) => Box::new( + self.dataset + .encoded_quads_for_pattern(Some(start), Some(&p.encoded), None, None) + .map(|t| { + let t = t?; + Ok((t.object, t.graph_name)) + }), + ), + PlanPropertyPath::Reverse(p) => self.eval_to_in_unknown_graph(p, start), + PlanPropertyPath::Sequence(a, b) => { + let eval = self.clone(); + let b = Rc::clone(b); + Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok( + move |(middle, graph_name)| { + eval.eval_from_in_graph(&b, &middle, &graph_name) + .map(move |end| Ok((end?, graph_name.clone()))) + }, + )) + } + PlanPropertyPath::Alternative(a, b) => Box::new(hash_deduplicate( + self.eval_from_in_unknown_graph(a, start) + .chain(self.eval_from_in_unknown_graph(b, start)), + )), + PlanPropertyPath::ZeroOrMore(p) => { + let start2 = start.clone(); + let eval = self.clone(); + let p = Rc::clone(p); + self.run_if_term_is_a_dataset_node(start, move |graph_name| { + let eval = eval.clone(); + let p = Rc::clone(&p); + let graph_name2 = graph_name.clone(); + transitive_closure(Some(Ok(start2.clone())), move |e| { + eval.eval_from_in_graph(&p, &e, &graph_name2) + }) + .map(move |e| Ok((e?, graph_name.clone()))) + }) + } + PlanPropertyPath::OneOrMore(p) => { + let eval = self.clone(); + let p = Rc::clone(p); + Box::new(transitive_closure( + self.eval_from_in_unknown_graph(&p, start), + move |(e, graph_name)| { + eval.eval_from_in_graph(&p, &e, &graph_name) + .map(move |e| Ok((e?, graph_name.clone()))) + }, + )) + } + PlanPropertyPath::ZeroOrOne(p) => { + let eval = self.clone(); + let start2 = start.clone(); + let p = Rc::clone(p); + self.run_if_term_is_a_dataset_node(start, move |graph_name| { + hash_deduplicate(once(Ok(start2.clone())).chain(eval.eval_from_in_graph( + &p, + &start2, + &graph_name, + ))) + .map(move |e| Ok((e?, graph_name.clone()))) + }) + } + PlanPropertyPath::NegatedPropertySet(ps) => { + let ps = Rc::clone(ps); + Box::new( + self.dataset + .encoded_quads_for_pattern(Some(start), None, None, None) + .filter_map(move |t| match t { + Ok(t) => { + if ps.iter().any(|p| p.encoded == t.predicate) { + None + } else { + Some(Ok((t.object, t.graph_name))) + } + } + Err(e) => Some(Err(e)), + }), + ) + } + } + } fn eval_to_in_graph( &self, diff --git a/lib/src/storage/mod.rs b/lib/src/storage/mod.rs index 8af5fe5b..e36c3c12 100644 --- a/lib/src/storage/mod.rs +++ b/lib/src/storage/mod.rs @@ -378,8 +378,14 @@ impl StorageReader { predicate: Option<&EncodedTerm>, object: Option<&EncodedTerm>, graph_name: Option<&EncodedTerm>, - ) -> Vec { - return Vec::new(); + ) -> ChainedDecodingQuadIterator { + return ChainedDecodingQuadIterator { + first: DecodingQuadIterator { + terms: Vec::new(), + encoding: QuadEncoding::Spog, + }, + second: None, + }; // match subject { // Some(subject) => match predicate { // Some(predicate) => match object { @@ -436,8 +442,11 @@ impl StorageReader { // } } - pub fn quads(&self) -> Vec { - Vec::new() + pub fn quads(&self) -> ChainedDecodingQuadIterator { + ChainedDecodingQuadIterator::new(DecodingQuadIterator { + terms: Vec::new(), + encoding: QuadEncoding::Spog, + }) // ChainedDecodingQuadIterator::pair(self.dspo_quads(&[]), self.gspo_quads(&[])) } @@ -608,8 +617,8 @@ impl StorageReader { // }) // } - pub fn named_graphs(&self) -> Vec { - Vec::new() + pub fn named_graphs(&self) -> DecodingGraphIterator { + DecodingGraphIterator { terms: Vec::new() } } pub fn contains_named_graph(&self, graph_name: &EncodedTerm) -> Result { @@ -671,7 +680,7 @@ impl Iterator for ChainedDecodingQuadIterator { } pub struct DecodingQuadIterator { - iter: Iter, + terms: Vec, encoding: QuadEncoding, } @@ -679,29 +688,29 @@ impl Iterator for DecodingQuadIterator { type Item = Result; fn next(&mut self) -> Option> { - if let Err(e) = self.iter.status() { - return Some(Err(e)); - } - let term = self.encoding.decode(self.iter.key()?); - self.iter.next(); - Some(term) + // if let Err(e) = self.iter.status() { + // return Some(Err(e)); + // } + // let term = self.encoding.decode(self.iter.key()?); + // self.iter.next(); + self.terms.pop().map(|x| Ok(x)) } } pub struct DecodingGraphIterator { - iter: Iter, + terms: Vec, } impl Iterator for DecodingGraphIterator { type Item = Result; fn next(&mut self) -> Option> { - if let Err(e) = self.iter.status() { - return Some(Err(e)); - } - let term = decode_term(self.iter.key()?); - self.iter.next(); - Some(term) + // if let Err(e) = self.iter.status() { + // return Some(Err(e)); + // } + // let term = self.encoding.decode(self.iter.key()?); + // self.iter.next(); + self.terms.pop().map(|x| Ok(x)) } } diff --git a/lib/src/store.rs b/lib/src/store.rs index 0be13778..95542224 100644 --- a/lib/src/store.rs +++ b/lib/src/store.rs @@ -237,10 +237,7 @@ impl Store { options: QueryOptions, with_stats: bool, ) -> Result<(Result, QueryExplanation), EvaluationError> { - // evaluate_query(self.storage.snapshot(), query, options, with_stats) - Err(EvaluationError::Storage(StorageError::Io( - std::io::Error::new(std::io::ErrorKind::NotFound, "Not yet implemented"), - ))) + evaluate_query(self.storage.snapshot(), query, options, with_stats) } /// Retrieves quads with a filter on each quad component @@ -268,14 +265,17 @@ impl Store { predicate: Option>, object: Option>, graph_name: Option>, - ) -> Vec { + ) -> QuadIter { let reader = self.storage.snapshot(); - reader.quads_for_pattern( - subject.map(EncodedTerm::from).as_ref(), - predicate.map(EncodedTerm::from).as_ref(), - object.map(EncodedTerm::from).as_ref(), - graph_name.map(EncodedTerm::from).as_ref(), - ) + QuadIter { + iter: reader.quads_for_pattern( + subject.map(EncodedTerm::from).as_ref(), + predicate.map(EncodedTerm::from).as_ref(), + object.map(EncodedTerm::from).as_ref(), + graph_name.map(EncodedTerm::from).as_ref(), + ), + reader, + } } /// Returns all the quads contained in the store. @@ -297,7 +297,7 @@ impl Store { /// assert_eq!(vec![quad], results); /// # Result::<_, Box>::Ok(()) /// ``` - pub fn iter(&self) -> Vec { + pub fn iter(&self) -> QuadIter { self.quads_for_pattern(None, None, None, None) } @@ -489,9 +489,8 @@ impl Store { // for quad in &quads { // t.insert(quad.as_ref().in_graph(to_graph_name))?; // } - // Ok(()) - // }) Ok(()) + // }) } /// Loads a dataset file (i.e. quads) into the store. @@ -532,9 +531,8 @@ impl Store { // for quad in &quads { // t.insert(quad.into())?; // } - // Ok(()) - // }) Ok(()) + // }) } /// Adds a quad to this store. @@ -625,9 +623,9 @@ impl Store { from_graph_name: impl Into>, ) -> Result<(), SerializerError> { let mut writer = GraphSerializer::from_format(format).triple_writer(writer)?; - // for quad in self.quads_for_pattern(None, None, None, Some(from_graph_name.into())) { - // writer.write(quad?.as_ref())?; - // } + for quad in self.quads_for_pattern(None, None, None, Some(from_graph_name.into())) { + writer.write(quad?.as_ref())?; + } writer.finish()?; Ok(()) } @@ -654,9 +652,9 @@ impl Store { format: DatasetFormat, ) -> Result<(), SerializerError> { let mut writer = DatasetSerializer::from_format(format).quad_writer(writer)?; - // for quad in self.iter() { - // writer.write(&quad?)?; - // } + for quad in self.iter() { + writer.write(&quad?)?; + } writer.finish()?; Ok(()) } @@ -675,13 +673,13 @@ impl Store { /// assert_eq!(vec![NamedOrBlankNode::from(ex)], store.named_graphs().collect::,_>>()?); /// # Result::<_, Box>::Ok(()) /// ``` - // pub fn named_graphs(&self) -> GraphNameIter { - // let reader = self.storage.snapshot(); - // GraphNameIter { - // iter: reader.named_graphs().iter(), - // reader, - // } - // } + pub fn named_graphs(&self) -> GraphNameIter { + let reader = self.storage.snapshot(); + GraphNameIter { + iter: reader.named_graphs(), + reader, + } + } /// Checks if the store contains a given graph /// @@ -883,7 +881,7 @@ impl Store { impl fmt::Display for Store { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for t in self.iter() { - writeln!(f, "{} .", t)?; + writeln!(f, "{} .", t.map_err(|_| fmt::Error)?)?; } Ok(()) } @@ -990,18 +988,21 @@ impl<'a> Transaction<'a> { predicate: Option>, object: Option>, graph_name: Option>, - ) -> Vec { + ) -> QuadIter { let reader = self.writer.reader(); - reader.quads_for_pattern( - subject.map(EncodedTerm::from).as_ref(), - predicate.map(EncodedTerm::from).as_ref(), - object.map(EncodedTerm::from).as_ref(), - graph_name.map(EncodedTerm::from).as_ref(), - ) + QuadIter { + iter: reader.quads_for_pattern( + subject.map(EncodedTerm::from).as_ref(), + predicate.map(EncodedTerm::from).as_ref(), + object.map(EncodedTerm::from).as_ref(), + graph_name.map(EncodedTerm::from).as_ref(), + ), + reader, + } } /// Returns all the quads contained in the store. - pub fn iter(&self) -> Vec { + pub fn iter(&self) -> QuadIter { self.quads_for_pattern(None, None, None, None) } @@ -1202,13 +1203,12 @@ impl<'a> Transaction<'a> { } /// Returns all the store named graphs. - pub fn named_graphs(&self) -> Vec { - // let reader = self.writer.reader(); - // GraphNameIter { - // iter: reader.named_graphs(), - // reader, - // } - Vec::new() + pub fn named_graphs(&self) -> GraphNameIter { + let reader = self.writer.reader(); + GraphNameIter { + iter: reader.named_graphs(), + reader, + } } /// Checks if the store contains a given graph. @@ -1617,23 +1617,22 @@ fn store() -> Result<(), StorageError> { GraphName::DefaultGraph, ), ]; - // let all_quads = vec![ - // Quad::new( - // main_s.clone(), - // main_p.clone(), - // Literal::from(0), - // GraphName::DefaultGraph, - // ), - // default_quad.clone(), - // Quad::new( - // main_s.clone(), - // main_p.clone(), - // Literal::from(200_000_000), - // GraphName::DefaultGraph, - // ), - // named_quad.clone(), - // ]; - let all_quads = Vec::new(); + let all_quads = vec![ + Quad::new( + main_s.clone(), + main_p.clone(), + Literal::from(0), + GraphName::DefaultGraph, + ), + default_quad.clone(), + Quad::new( + main_s.clone(), + main_p.clone(), + Literal::from(200_000_000), + GraphName::DefaultGraph, + ), + named_quad.clone(), + ]; let store = Store::new()?; for t in &default_quads { @@ -1649,140 +1648,147 @@ fn store() -> Result<(), StorageError> { assert!(!store.insert(&default_quad)?); assert_eq!(store.len()?, 4); - assert_eq!(store.iter(), all_quads); + assert_eq!(store.iter().collect::, _>>()?, all_quads); assert_eq!( - store.quads_for_pattern(Some(main_s.as_ref()), None, None, None), + store + .quads_for_pattern(Some(main_s.as_ref()), None, None, None) + .collect::, _>>()?, all_quads ); assert_eq!( - store.quads_for_pattern(Some(main_s.as_ref()), Some(main_p.as_ref()), None, None), + store + .quads_for_pattern(Some(main_s.as_ref()), Some(main_p.as_ref()), None, None) + .collect::, _>>()?, all_quads ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - Some(main_p.as_ref()), - Some(main_o.as_ref()), - None - ), - // vec![default_quad.clone(), named_quad.clone()] - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + Some(main_p.as_ref()), + Some(main_o.as_ref()), + None + ) + .collect::, _>>()?, + vec![default_quad.clone(), named_quad.clone()] ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - Some(main_p.as_ref()), - Some(main_o.as_ref()), - Some(GraphNameRef::DefaultGraph) - ), - // .collect::, _>>()?, - // vec![default_quad.clone()] - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + Some(main_p.as_ref()), + Some(main_o.as_ref()), + Some(GraphNameRef::DefaultGraph) + ) + .collect::, _>>()?, + vec![default_quad.clone()] ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - Some(main_p.as_ref()), - Some(main_o.as_ref()), - Some(main_g.as_ref()) - ), - // .collect::, _>>()?, - // vec![named_quad.clone()] - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + Some(main_p.as_ref()), + Some(main_o.as_ref()), + Some(main_g.as_ref()) + ) + .collect::, _>>()?, + vec![named_quad.clone()] ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - Some(main_p.as_ref()), - None, - Some(GraphNameRef::DefaultGraph) - ), - // .collect::, _>>()?, - // default_quads - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + Some(main_p.as_ref()), + None, + Some(GraphNameRef::DefaultGraph) + ) + .collect::, _>>()?, + default_quads ); assert_eq!( - store.quads_for_pattern(Some(main_s.as_ref()), None, Some(main_o.as_ref()), None), - // vec![default_quad.clone(), named_quad.clone()] - Vec::new() + store + .quads_for_pattern(Some(main_s.as_ref()), None, Some(main_o.as_ref()), None) + .collect::, _>>()?, + vec![default_quad.clone(), named_quad.clone()] ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - None, - Some(main_o.as_ref()), - Some(GraphNameRef::DefaultGraph) - ), - // .collect::, _>>()?, - // vec![default_quad.clone()] - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + None, + Some(main_o.as_ref()), + Some(GraphNameRef::DefaultGraph) + ) + .collect::, _>>()?, + vec![default_quad.clone()] ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - None, - Some(main_o.as_ref()), - Some(main_g.as_ref()) - ), - // .collect::, _>>()?, - // vec![named_quad.clone()] - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + None, + Some(main_o.as_ref()), + Some(main_g.as_ref()) + ) + .collect::, _>>()?, + vec![named_quad.clone()] ); assert_eq!( - store.quads_for_pattern( - Some(main_s.as_ref()), - None, - None, - Some(GraphNameRef::DefaultGraph) - ), - // .collect::, _>>()?, - // default_quads - Vec::new() + store + .quads_for_pattern( + Some(main_s.as_ref()), + None, + None, + Some(GraphNameRef::DefaultGraph) + ) + .collect::, _>>()?, + default_quads ); assert_eq!( - store.quads_for_pattern(None, Some(main_p.as_ref()), None, None), - // .collect::, _>>()?, + store + .quads_for_pattern(None, Some(main_p.as_ref()), None, None) + .collect::, _>>()?, all_quads ); assert_eq!( - store.quads_for_pattern(None, Some(main_p.as_ref()), Some(main_o.as_ref()), None), - // .collect::, _>>()?, - // vec![default_quad.clone(), named_quad.clone()] - Vec::new() + store + .quads_for_pattern(None, Some(main_p.as_ref()), Some(main_o.as_ref()), None) + .collect::, _>>()?, + vec![default_quad.clone(), named_quad.clone()] ); assert_eq!( - store.quads_for_pattern(None, None, Some(main_o.as_ref()), None), - // .collect::, _>>()?, - // vec![default_quad.clone(), named_quad.clone()] - Vec::new() + store + .quads_for_pattern(None, None, Some(main_o.as_ref()), None) + .collect::, _>>()?, + vec![default_quad.clone(), named_quad.clone()] ); assert_eq!( - store.quads_for_pattern(None, None, None, Some(GraphNameRef::DefaultGraph)), - // .collect::, _>>()?, - // default_quads - Vec::new() + store + .quads_for_pattern(None, None, None, Some(GraphNameRef::DefaultGraph)) + .collect::, _>>()?, + default_quads ); assert_eq!( - store.quads_for_pattern( - None, - Some(main_p.as_ref()), - Some(main_o.as_ref()), - Some(GraphNameRef::DefaultGraph) - ), - // .collect::, _>>()?, - // vec![default_quad] - Vec::new() + store + .quads_for_pattern( + None, + Some(main_p.as_ref()), + Some(main_o.as_ref()), + Some(GraphNameRef::DefaultGraph) + ) + .collect::, _>>()?, + vec![default_quad] ); assert_eq!( - store.quads_for_pattern( - None, - Some(main_p.as_ref()), - Some(main_o.as_ref()), - Some(main_g.as_ref()) - ), - // .collect::, _>>()?, - // vec![named_quad] - Vec::new() + store + .quads_for_pattern( + None, + Some(main_p.as_ref()), + Some(main_o.as_ref()), + Some(main_g.as_ref()) + ) + .collect::, _>>()?, + vec![named_quad] ); Ok(())