diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index c513fba8..47f3b3fb 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -6,7 +6,7 @@ use crate::sparql::model::*; use crate::sparql::plan::*; use crate::sparql::ServiceHandler; use crate::store::numeric_encoder::*; -use crate::store::StoreConnection; +use crate::store::ReadableEncodedStore; use crate::Error; use crate::Result; use digest::Digest; @@ -31,7 +31,7 @@ const REGEX_SIZE_LIMIT: usize = 1_000_000; type EncodedTuplesIterator<'a> = Box> + 'a>; -pub struct SimpleEvaluator { +pub struct SimpleEvaluator { dataset: DatasetView, base_iri: Option>, bnodes_map: Mutex>, @@ -39,7 +39,7 @@ pub struct SimpleEvaluator { service_handler: Box, } -impl<'a, S: StoreConnection + 'a> SimpleEvaluator { +impl<'a, S: ReadableEncodedStore + 'a> SimpleEvaluator { pub fn new( dataset: DatasetView, base_iri: Option>, @@ -2044,14 +2044,14 @@ impl<'a> Iterator for AntiJoinIterator<'a> { } } -struct LeftJoinIterator<'a, S: StoreConnection> { +struct LeftJoinIterator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, right_plan: &'a PlanNode, left_iter: EncodedTuplesIterator<'a>, current_right: EncodedTuplesIterator<'a>, } -impl<'a, S: StoreConnection> Iterator for LeftJoinIterator<'a, S> { +impl<'a, S: ReadableEncodedStore> Iterator for LeftJoinIterator<'a, S> { type Item = Result; fn next(&mut self) -> Option> { @@ -2072,7 +2072,7 @@ impl<'a, S: StoreConnection> Iterator for LeftJoinIterator<'a, S> { } } -struct BadLeftJoinIterator<'a, S: StoreConnection> { +struct BadLeftJoinIterator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, right_plan: &'a PlanNode, left_iter: EncodedTuplesIterator<'a>, @@ -2081,7 +2081,7 @@ struct BadLeftJoinIterator<'a, S: StoreConnection> { problem_vars: &'a [usize], } -impl<'a, S: StoreConnection> Iterator for BadLeftJoinIterator<'a, S> { +impl<'a, S: ReadableEncodedStore> Iterator for BadLeftJoinIterator<'a, S> { type Item = Result; fn next(&mut self) -> Option> { @@ -2124,7 +2124,7 @@ impl<'a, S: StoreConnection> Iterator for BadLeftJoinIterator<'a, S> { } } -struct UnionIterator<'a, S: StoreConnection> { +struct UnionIterator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, plans: &'a [PlanNode], input: EncodedTuple, @@ -2132,7 +2132,7 @@ struct UnionIterator<'a, S: StoreConnection> { current_plan: usize, } -impl<'a, S: StoreConnection> Iterator for UnionIterator<'a, S> { +impl<'a, S: ReadableEncodedStore> Iterator for UnionIterator<'a, S> { type Item = Result; fn next(&mut self) -> Option> { @@ -2151,7 +2151,7 @@ impl<'a, S: StoreConnection> Iterator for UnionIterator<'a, S> { } } -struct ConstructIterator<'a, S: StoreConnection> { +struct ConstructIterator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, iter: EncodedTuplesIterator<'a>, template: &'a [TripleTemplate], @@ -2159,7 +2159,7 @@ struct ConstructIterator<'a, S: StoreConnection> { bnodes: Vec, } -impl<'a, S: StoreConnection + 'a> Iterator for ConstructIterator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> Iterator for ConstructIterator<'a, S> { type Item = Result; fn next(&mut self) -> Option> { @@ -2222,13 +2222,13 @@ fn decode_triple( )) } -struct DescribeIterator<'a, S: StoreConnection> { +struct DescribeIterator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, iter: EncodedTuplesIterator<'a>, quads: Box> + 'a>, } -impl<'a, S: StoreConnection + 'a> Iterator for DescribeIterator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> Iterator for DescribeIterator<'a, S> { type Item = Result; fn next(&mut self) -> Option> { @@ -2517,18 +2517,18 @@ impl Accumulator for AvgAccumulator { } #[allow(clippy::option_option)] -struct MinAccumulator<'a, S: StoreConnection> { +struct MinAccumulator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, min: Option>, } -impl<'a, S: StoreConnection + 'a> MinAccumulator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> MinAccumulator<'a, S> { fn new(eval: &'a SimpleEvaluator) -> Self { Self { eval, min: None } } } -impl<'a, S: StoreConnection + 'a> Accumulator for MinAccumulator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> Accumulator for MinAccumulator<'a, S> { fn add(&mut self, element: Option) { if let Some(min) = self.min { if self.eval.cmp_terms(element, min) == Ordering::Less { @@ -2545,18 +2545,18 @@ impl<'a, S: StoreConnection + 'a> Accumulator for MinAccumulator<'a, S> { } #[allow(clippy::option_option)] -struct MaxAccumulator<'a, S: StoreConnection> { +struct MaxAccumulator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, max: Option>, } -impl<'a, S: StoreConnection + 'a> MaxAccumulator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> MaxAccumulator<'a, S> { fn new(eval: &'a SimpleEvaluator) -> Self { Self { eval, max: None } } } -impl<'a, S: StoreConnection + 'a> Accumulator for MaxAccumulator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> Accumulator for MaxAccumulator<'a, S> { fn add(&mut self, element: Option) { if let Some(max) = self.max { if self.eval.cmp_terms(element, max) == Ordering::Greater { @@ -2590,14 +2590,14 @@ impl Accumulator for SampleAccumulator { } #[allow(clippy::option_option)] -struct GroupConcatAccumulator<'a, S: StoreConnection> { +struct GroupConcatAccumulator<'a, S: ReadableEncodedStore> { eval: &'a SimpleEvaluator, concat: Option, language: Option>, separator: &'a str, } -impl<'a, S: StoreConnection + 'a> GroupConcatAccumulator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> GroupConcatAccumulator<'a, S> { fn new(eval: &'a SimpleEvaluator, separator: &'a str) -> Self { Self { eval, @@ -2608,7 +2608,7 @@ impl<'a, S: StoreConnection + 'a> GroupConcatAccumulator<'a, S> { } } -impl<'a, S: StoreConnection + 'a> Accumulator for GroupConcatAccumulator<'a, S> { +impl<'a, S: ReadableEncodedStore + 'a> Accumulator for GroupConcatAccumulator<'a, S> { fn add(&mut self, element: Option) { if let Some(concat) = self.concat.as_mut() { let element = if let Some(element) = element { diff --git a/lib/src/sparql/mod.rs b/lib/src/sparql/mod.rs index 44c6dc14..2cc7dcb2 100644 --- a/lib/src/sparql/mod.rs +++ b/lib/src/sparql/mod.rs @@ -16,7 +16,7 @@ use crate::sparql::parser::read_sparql_query; use crate::sparql::plan::TripleTemplate; use crate::sparql::plan::{DatasetView, PlanNode}; use crate::sparql::plan_builder::PlanBuilder; -use crate::store::StoreConnection; +use crate::store::ReadableEncodedStore; use crate::Error; use crate::Result; use oxiri::Iri; @@ -35,9 +35,9 @@ pub trait PreparedQuery { } /// An implementation of `PreparedQuery` for internal use -pub struct SimplePreparedQuery(SimplePreparedQueryAction); +pub struct SimplePreparedQuery(SimplePreparedQueryAction); -enum SimplePreparedQueryAction { +enum SimplePreparedQueryAction { Select { plan: PlanNode, variables: Vec, @@ -58,7 +58,7 @@ enum SimplePreparedQueryAction { }, } -impl<'a, S: StoreConnection + 'a> SimplePreparedQuery { +impl<'a, S: ReadableEncodedStore + 'a> SimplePreparedQuery { pub(crate) fn new(connection: S, query: &str, options: QueryOptions<'_>) -> Result { let dataset = DatasetView::new(connection, options.default_graph_as_union); Ok(Self(match read_sparql_query(query, options.base_iri)? { @@ -131,7 +131,7 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery { } } -impl PreparedQuery for SimplePreparedQuery { +impl PreparedQuery for SimplePreparedQuery { fn exec(&self) -> Result> { match &self.0 { SimplePreparedQueryAction::Select { diff --git a/lib/src/sparql/plan.rs b/lib/src/sparql/plan.rs index 5577d032..34c5f580 100644 --- a/lib/src/sparql/plan.rs +++ b/lib/src/sparql/plan.rs @@ -4,7 +4,7 @@ use crate::store::numeric_encoder::{ EncodedQuad, EncodedTerm, Encoder, MemoryStrStore, StrContainer, StrHash, StrLookup, ENCODED_DEFAULT_GRAPH, }; -use crate::store::StoreConnection; +use crate::store::ReadableEncodedStore; use crate::Result; use std::cell::{RefCell, RefMut}; use std::collections::BTreeSet; @@ -553,13 +553,13 @@ impl EncodedTuple { } } -pub struct DatasetView { +pub struct DatasetView { store: S, extra: RefCell, default_graph_as_union: bool, } -impl DatasetView { +impl DatasetView { pub fn new(store: S, default_graph_as_union: bool) -> Self { Self { store, @@ -578,7 +578,7 @@ impl DatasetView { if graph_name == None { Box::new( self.store - .quads_for_pattern(subject, predicate, object, None) + .encoded_quads_for_pattern(subject, predicate, object, None) .filter(|quad| match quad { Err(_) => true, Ok(quad) => quad.graph_name != ENCODED_DEFAULT_GRAPH, @@ -587,7 +587,7 @@ impl DatasetView { } else if graph_name == Some(ENCODED_DEFAULT_GRAPH) && self.default_graph_as_union { Box::new( self.store - .quads_for_pattern(subject, predicate, object, None) + .encoded_quads_for_pattern(subject, predicate, object, None) .map(|quad| { let quad = quad?; Ok(EncodedQuad::new( @@ -600,7 +600,7 @@ impl DatasetView { ) } else { self.store - .quads_for_pattern(subject, predicate, object, graph_name) + .encoded_quads_for_pattern(subject, predicate, object, graph_name) } } @@ -612,7 +612,7 @@ impl DatasetView { } } -impl StrLookup for DatasetView { +impl StrLookup for DatasetView { fn get_str(&self, id: StrHash) -> Result> { if let Some(value) = self.extra.borrow().get_str(id)? { Ok(Some(value)) @@ -622,12 +622,12 @@ impl StrLookup for DatasetView { } } -struct DatasetViewStrContainer<'a, S: StoreConnection> { +struct DatasetViewStrContainer<'a, S: ReadableEncodedStore> { store: &'a S, extra: RefMut<'a, MemoryStrStore>, } -impl<'a, S: StoreConnection> StrContainer for DatasetViewStrContainer<'a, S> { +impl<'a, S: ReadableEncodedStore> StrContainer for DatasetViewStrContainer<'a, S> { fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { if self.store.get_str(key)?.is_none() { self.extra.insert_str(key, value) diff --git a/lib/src/store/mod.rs b/lib/src/store/mod.rs index 5f4c653e..e092bf60 100644 --- a/lib/src/store/mod.rs +++ b/lib/src/store/mod.rs @@ -58,6 +58,28 @@ pub trait StoreTransaction: StrContainer + Sized { fn commit(self) -> Result<()>; } +pub trait ReadableEncodedStore: StrLookup + Sized { + fn encoded_quads_for_pattern<'a>( + &'a self, + subject: Option, + predicate: Option, + object: Option, + graph_name: Option, + ) -> Box> + 'a>; +} + +impl ReadableEncodedStore for S { + fn encoded_quads_for_pattern<'a>( + &'a self, + subject: Option, + predicate: Option, + object: Option, + graph_name: Option, + ) -> Box> + 'a> { + self.quads_for_pattern(subject, predicate, object, graph_name) + } +} + /// A `RepositoryConnection` from a `StoreConnection` #[derive(Clone)] pub struct StoreRepositoryConnection {