diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index 341704b1..bda91208 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -92,14 +92,14 @@ where pub fn evaluate_construct_plan( &self, plan: &PlanNode, - construct: Rc>>, + template: Vec>, ) -> Result { let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len()); Ok(QueryResults::Graph(QueryTripleIter { iter: Box::new(ConstructIterator { eval: self.clone(), iter: self.eval_plan(plan, from), - template: construct, + template, buffered_results: Vec::default(), bnodes: Vec::default(), }), @@ -2634,7 +2634,7 @@ where struct ConstructIterator { eval: SimpleEvaluator, iter: EncodedTuplesIterator, - template: Rc>>, + template: Vec>, buffered_results: Vec>, bnodes: Vec>, } @@ -2652,7 +2652,7 @@ impl + 'static> Iterator for Co Ok(tuple) => tuple, Err(error) => return Some(Err(error)), }; - for template in self.template.iter() { + for template in &self.template { if let (Some(subject), Some(predicate), Some(object)) = ( get_triple_template_value(&template.subject, &tuple, &mut self.bnodes), get_triple_template_value(&template.predicate, &tuple, &mut self.bnodes), diff --git a/lib/src/sparql/mod.rs b/lib/src/sparql/mod.rs index 6b36ad21..838c1c71 100644 --- a/lib/src/sparql/mod.rs +++ b/lib/src/sparql/mod.rs @@ -29,126 +29,63 @@ pub use crate::sparql::model::QuerySolutionIter; pub use crate::sparql::model::QueryTripleIter; pub use crate::sparql::model::{Variable, VariableNameParseError}; pub use crate::sparql::parser::ParseError; -use crate::sparql::plan::{PlanNode, TripleTemplate}; use crate::sparql::plan_builder::PlanBuilder; pub use crate::sparql::service::ServiceHandler; use crate::sparql::service::{EmptyServiceHandler, ErrorConversionServiceHandler}; use crate::sparql::update::SimpleUpdateEvaluator; -use crate::store::numeric_encoder::{StrContainer, StrEncodingAware}; +use crate::store::numeric_encoder::StrContainer; use crate::store::{ReadableEncodedStore, StoreOrParseError, WritableEncodedStore}; use std::convert::TryInto; use std::io; use std::rc::Rc; -/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/) -pub(crate) struct SimplePreparedQuery( - SimplePreparedQueryAction, -); - -#[derive(Clone)] -enum SimplePreparedQueryAction { - Select { - plan: Rc as StrEncodingAware>::StrId>>, - variables: Rc>, - evaluator: SimpleEvaluator>, - }, - Ask { - plan: Rc as StrEncodingAware>::StrId>>, - evaluator: SimpleEvaluator>, - }, - Construct { - plan: Rc as StrEncodingAware>::StrId>>, - construct: Rc as StrEncodingAware>::StrId>>>, - evaluator: SimpleEvaluator>, - }, - Describe { - plan: Rc as StrEncodingAware>::StrId>>, - evaluator: SimpleEvaluator>, - }, -} - -impl SimplePreparedQuery { - pub(crate) fn new( - store: S, - query: impl TryInto>, - options: QueryOptions, - ) -> Result { - Ok(Self(match query.try_into().map_err(|e| e.into())?.0 { - QueryVariants::Select { - algebra, - base_iri, - dataset, - } => { - let dataset = Rc::new(DatasetView::new(store, &dataset)?); - let (plan, variables) = PlanBuilder::build(dataset.as_ref(), &algebra)?; - SimplePreparedQueryAction::Select { - plan: Rc::new(plan), - variables: Rc::new(variables), - evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler), - } - } - QueryVariants::Ask { - algebra, - base_iri, - dataset, - } => { - let dataset = Rc::new(DatasetView::new(store, &dataset)?); - let (plan, _) = PlanBuilder::build(dataset.as_ref(), &algebra)?; - SimplePreparedQueryAction::Ask { - plan: Rc::new(plan), - evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler), - } - } - QueryVariants::Construct { - construct, - algebra, - base_iri, - dataset, - } => { - let dataset = Rc::new(DatasetView::new(store, &dataset)?); - let (plan, variables) = PlanBuilder::build(dataset.as_ref(), &algebra)?; - SimplePreparedQueryAction::Construct { - plan: Rc::new(plan), - construct: Rc::new(PlanBuilder::build_graph_template( - dataset.as_ref(), - &construct, - variables, - )?), - evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler), - } - } - QueryVariants::Describe { - algebra, - base_iri, - dataset, - } => { - let dataset = Rc::new(DatasetView::new(store, &dataset)?); - let (plan, _) = PlanBuilder::build(dataset.as_ref(), &algebra)?; - SimplePreparedQueryAction::Describe { - plan: Rc::new(plan), - evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler), - } - } - })) - } - - /// Evaluates the query and returns its results - pub fn exec(&self) -> Result { - match &self.0 { - SimplePreparedQueryAction::Select { - plan, - variables, - evaluator, - } => evaluator.evaluate_select_plan(plan, variables.clone()), - SimplePreparedQueryAction::Ask { plan, evaluator } => evaluator.evaluate_ask_plan(plan), - SimplePreparedQueryAction::Construct { - plan, - construct, - evaluator, - } => evaluator.evaluate_construct_plan(plan, construct.clone()), - SimplePreparedQueryAction::Describe { plan, evaluator } => { - evaluator.evaluate_describe_plan(plan) - } +pub(crate) fn evaluate_query( + store: R, + query: impl TryInto>, + options: QueryOptions, +) -> Result { + match query.try_into().map_err(|e| e.into())?.0 { + QueryVariants::Select { + algebra, + base_iri, + dataset, + } => { + let dataset = DatasetView::new(store, &dataset)?; + let (plan, variables) = PlanBuilder::build(&dataset, &algebra)?; + SimpleEvaluator::new(Rc::new(dataset), base_iri, options.service_handler) + .evaluate_select_plan(&plan, Rc::new(variables)) + } + QueryVariants::Ask { + algebra, + base_iri, + dataset, + } => { + let dataset = DatasetView::new(store, &dataset)?; + let (plan, _) = PlanBuilder::build(&dataset, &algebra)?; + SimpleEvaluator::new(Rc::new(dataset), base_iri, options.service_handler) + .evaluate_ask_plan(&plan) + } + QueryVariants::Construct { + construct, + algebra, + base_iri, + dataset, + } => { + let dataset = DatasetView::new(store, &dataset)?; + let (plan, variables) = PlanBuilder::build(&dataset, &algebra)?; + let construct = PlanBuilder::build_graph_template(&dataset, &construct, variables)?; + SimpleEvaluator::new(Rc::new(dataset), base_iri, options.service_handler) + .evaluate_construct_plan(&plan, construct) + } + QueryVariants::Describe { + algebra, + base_iri, + dataset, + } => { + let dataset = DatasetView::new(store, &dataset)?; + let (plan, _) = PlanBuilder::build(&dataset, &algebra)?; + SimpleEvaluator::new(Rc::new(dataset), base_iri, options.service_handler) + .evaluate_describe_plan(&plan) } } } diff --git a/lib/src/store/memory.rs b/lib/src/store/memory.rs index 1c76d62f..9eafc116 100644 --- a/lib/src/store/memory.rs +++ b/lib/src/store/memory.rs @@ -4,8 +4,7 @@ use crate::error::{invalid_input_error, UnwrapInfallible}; use crate::io::{DatasetFormat, DatasetParser, GraphFormat, GraphParser}; use crate::model::*; use crate::sparql::{ - evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, SimplePreparedQuery, - Update, + evaluate_query, evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, Update, }; use crate::store::numeric_encoder::{ Decoder, ReadEncoder, StrContainer, StrEncodingAware, StrId, StrLookup, WriteEncoder, @@ -116,41 +115,7 @@ impl MemoryStore { query: impl TryInto>, options: QueryOptions, ) -> Result { - self.prepare_query(query, options)?.exec() - } - - /// Prepares a [SPARQL 1.1 query](https://www.w3.org/TR/sparql11-query/) and returns an object that could be used to execute it. - /// It is useful if you want to execute multiple times the same SPARQL query. - /// - /// Usage example: - /// ``` - /// use oxigraph::MemoryStore; - /// use oxigraph::model::*; - /// use oxigraph::sparql::{QueryResults, QueryOptions}; - /// - /// let store = MemoryStore::new(); - /// - /// // insertions - /// let ex = NamedNode::new("http://example.com")?; - /// store.insert(Quad::new(ex.clone(), ex.clone(), ex.clone(), None)); - /// - /// // SPARQL query - /// let prepared_query = store.prepare_query("SELECT ?s WHERE { ?s ?p ?o }", QueryOptions::default())?; - /// if let QueryResults::Solutions(mut solutions) = prepared_query.exec()? { - /// assert_eq!(solutions.next().unwrap()?.get("s"), Some(&ex.into())); - /// } - /// # Result::<_,Box>::Ok(()) - /// ``` - pub fn prepare_query( - &self, - query: impl TryInto>, - options: QueryOptions, - ) -> Result { - Ok(MemoryPreparedQuery(SimplePreparedQuery::new( - self.clone(), - query, - options, - )?)) + evaluate_query(self.clone(), query, options) } /// Retrieves quads with a filter on each quad component @@ -1110,16 +1075,6 @@ fn quad_map_flatten<'a, T: Copy>(gspo: &'a QuadMap) -> impl Iterator); - -impl MemoryPreparedQuery { - /// Evaluates the query and returns its results - pub fn exec(&self) -> Result { - self.0.exec() - } -} - /// Allows inserting and deleting quads during an ACID transaction with the [`MemoryStore`](struct.MemoryStore.html). pub struct MemoryTransaction { ops: Vec, diff --git a/lib/src/store/rocksdb.rs b/lib/src/store/rocksdb.rs index 728f44e1..20f1e333 100644 --- a/lib/src/store/rocksdb.rs +++ b/lib/src/store/rocksdb.rs @@ -4,8 +4,7 @@ use crate::error::invalid_data_error; use crate::io::{DatasetFormat, GraphFormat}; use crate::model::*; use crate::sparql::{ - evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, SimplePreparedQuery, - Update, + evaluate_query, evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, Update, }; use crate::store::binary_encoder::*; use crate::store::numeric_encoder::{ @@ -130,23 +129,7 @@ impl RocksDbStore { query: impl TryInto>, options: QueryOptions, ) -> Result { - self.prepare_query(query, options)?.exec() - } - - /// Prepares a [SPARQL 1.1 query](https://www.w3.org/TR/sparql11-query/) and returns an object that could be used to execute it. - /// It is useful if you want to execute multiple times the same SPARQL query. - /// - /// See [`MemoryStore`](../memory/struct.MemoryStore.html#method.prepare_query) for a usage example. - pub fn prepare_query( - &self, - query: impl TryInto>, - options: QueryOptions, - ) -> Result { - Ok(RocksDbPreparedQuery(SimplePreparedQuery::new( - (*self).clone(), - query, - options, - )?)) + evaluate_query(self.clone(), query, options) } /// Retrieves quads with a filter on each quad component @@ -749,16 +732,6 @@ impl ReadableEncodedStore for RocksDbStore { } } -/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/) for the [`RocksDbStore`](struct.RocksDbStore.html). -pub struct RocksDbPreparedQuery(SimplePreparedQuery); - -impl RocksDbPreparedQuery { - /// Evaluates the query and returns its results - pub fn exec(&self) -> Result { - self.0.exec() - } -} - struct AutoBatchWriter<'a> { store: &'a RocksDbStore, batch: WriteBatch, diff --git a/lib/src/store/sled.rs b/lib/src/store/sled.rs index e9db4e9c..74a3808c 100644 --- a/lib/src/store/sled.rs +++ b/lib/src/store/sled.rs @@ -4,8 +4,7 @@ use crate::error::invalid_data_error; use crate::io::{DatasetFormat, GraphFormat}; use crate::model::*; use crate::sparql::{ - evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, SimplePreparedQuery, - Update, + evaluate_query, evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, Update, }; use crate::store::binary_encoder::*; use crate::store::numeric_encoder::{ @@ -140,22 +139,7 @@ impl SledStore { query: impl TryInto>, options: QueryOptions, ) -> Result { - self.prepare_query(query, options)?.exec() - } - - /// Prepares a [SPARQL 1.1 query](https://www.w3.org/TR/sparql11-query/) and returns an object that could be used to execute it. - /// - /// See [`MemoryStore`](../memory/struct.MemoryStore.html#method.prepare_query) for a usage example. - pub fn prepare_query( - &self, - query: impl TryInto>, - options: QueryOptions, - ) -> Result { - Ok(SledPreparedQuery(SimplePreparedQuery::new( - (*self).clone(), - query, - options, - )?)) + evaluate_query(self.clone(), query, options) } /// Retrieves quads with a filter on each quad component @@ -1179,16 +1163,6 @@ impl From> for ConflictableTransactionErr } } -/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/) for the [`SledStore`](struct.SledStore.html). -pub struct SledPreparedQuery(SimplePreparedQuery); - -impl SledPreparedQuery { - /// Evaluates the query and returns its results - pub fn exec(&self) -> Result { - self.0.exec() - } -} - pub(crate) struct DecodingQuadsIterator { first: DecodingQuadIterator, second: Option,