|
|
|
@ -4,18 +4,30 @@ use crate::oxigraph::sparql::EvaluationError; |
|
|
|
|
use crate::oxigraph::storage::numeric_encoder::{ |
|
|
|
|
insert_term, EncodedQuad, EncodedTerm, StrHash, StrLookup, |
|
|
|
|
}; |
|
|
|
|
use crate::oxigraph::storage::{StorageError, StorageReader}; |
|
|
|
|
use crate::oxigraph::storage::{MatchBy, StorageError, StorageReader}; |
|
|
|
|
use crate::oxigraph::store::CorruptionError; |
|
|
|
|
|
|
|
|
|
use std::cell::RefCell; |
|
|
|
|
use std::collections::hash_map::Entry; |
|
|
|
|
use std::collections::HashMap; |
|
|
|
|
use std::iter::empty; |
|
|
|
|
|
|
|
|
|
pub struct DatasetView { |
|
|
|
|
reader: StorageReader, |
|
|
|
|
extra: RefCell<HashMap<StrHash, String>>, |
|
|
|
|
dataset: EncodedDatasetSpec, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ErrorIterator { |
|
|
|
|
err: Option<Result<EncodedQuad, EvaluationError>>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Iterator for ErrorIterator { |
|
|
|
|
type Item = Result<EncodedQuad, EvaluationError>; |
|
|
|
|
fn next(&mut self) -> Option<Self::Item> { |
|
|
|
|
self.err.take() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl DatasetView { |
|
|
|
|
pub fn new(reader: StorageReader, dataset: &QueryDataset) -> Self { |
|
|
|
|
let dataset = EncodedDatasetSpec { |
|
|
|
@ -33,16 +45,47 @@ impl DatasetView { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn store_encoded_quads_for_pattern( |
|
|
|
|
&self, |
|
|
|
|
subject: Option<&EncodedTerm>, |
|
|
|
|
predicate: Option<&EncodedTerm>, |
|
|
|
|
object: Option<&EncodedTerm>, |
|
|
|
|
graph_name: Option<&EncodedTerm>, |
|
|
|
|
) -> impl Iterator<Item = Result<EncodedQuad, EvaluationError>> + 'static { |
|
|
|
|
self.reader |
|
|
|
|
.quads_for_pattern(subject, predicate, object, graph_name) |
|
|
|
|
.map(|t| t.map_err(Into::into)) |
|
|
|
|
fn parse_graph_name(&self, graph_name: &EncodedTerm) -> Result<MatchBy, StorageError> { |
|
|
|
|
match graph_name { |
|
|
|
|
EncodedTerm::NamedNode { iri_id } => { |
|
|
|
|
let graph_name_string = self.get_str(iri_id)?.ok_or::<StorageError>( |
|
|
|
|
CorruptionError::msg("graph_name not found in parse_graph_name").into(), |
|
|
|
|
)?; |
|
|
|
|
self.reader |
|
|
|
|
.parse_graph_name(&graph_name_string, Some(*iri_id)) |
|
|
|
|
} |
|
|
|
|
_ => Err(CorruptionError::msg( |
|
|
|
|
"Invalid graph_name (not a NamedNode) in parse_graph_name", |
|
|
|
|
) |
|
|
|
|
.into()), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn store_encoded_quads_for_pattern<'a>( |
|
|
|
|
&'a self, |
|
|
|
|
subject: Option<&'a EncodedTerm>, |
|
|
|
|
predicate: Option<&'a EncodedTerm>, |
|
|
|
|
object: Option<&'a EncodedTerm>, |
|
|
|
|
graph_name: Option<&'a EncodedTerm>, |
|
|
|
|
) -> Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>> { |
|
|
|
|
let graph = if let Some(g) = graph_name { |
|
|
|
|
match self.parse_graph_name(g) { |
|
|
|
|
Ok(match_by) => Some(match_by), |
|
|
|
|
Err(e) => { |
|
|
|
|
return Box::new(ErrorIterator { |
|
|
|
|
err: Some(Err(e.into())), |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
None |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Box::new( |
|
|
|
|
self.reader |
|
|
|
|
.quads_for_pattern(subject, predicate, object, graph) |
|
|
|
|
.map(|t| t.map_err(Into::into)), |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[allow(clippy::needless_collect)] |
|
|
|
@ -141,6 +184,7 @@ impl DatasetView { |
|
|
|
|
Box::new(iters.into_iter().flatten()) |
|
|
|
|
} else { |
|
|
|
|
Box::new( |
|
|
|
|
// TODO: filter could be removed here as we never return quads with defaultGraph as graph
|
|
|
|
|
self.store_encoded_quads_for_pattern(subject, predicate, object, None) |
|
|
|
|
.filter(|quad| match quad { |
|
|
|
|
Err(_) => true, |
|
|
|
|