//! [SPARQL](https://www.w3.org/TR/sparql11-overview/) implementation. use crate::sparql::algebra::Query; use crate::sparql::algebra::QueryResult; use crate::sparql::algebra::Variable; use crate::sparql::eval::SimpleEvaluator; use crate::sparql::parser::read_sparql_query; use crate::sparql::plan::PlanBuilder; use crate::sparql::plan::PlanNode; use crate::sparql::plan::TripleTemplate; use crate::store::StoreConnection; use crate::Result; use std::io::Read; pub mod algebra; mod eval; pub mod parser; mod plan; pub mod xml_results; /// A prepared [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/) query pub trait PreparedQuery { /// Evaluates the query and returns its results fn exec(&self) -> Result>; } /// An implementation of `PreparedQuery` for internal use pub struct SimplePreparedQuery(SimplePreparedQueryOptions); enum SimplePreparedQueryOptions { Select { plan: PlanNode, variables: Vec, evaluator: SimpleEvaluator, }, Ask { plan: PlanNode, evaluator: SimpleEvaluator, }, Construct { plan: PlanNode, construct: Vec, evaluator: SimpleEvaluator, }, Describe { plan: PlanNode, evaluator: SimpleEvaluator, }, } impl SimplePreparedQuery { pub(crate) fn new(connection: S, query: impl Read) -> Result { Ok(Self(match read_sparql_query(query, None)? { Query::Select { algebra, dataset: _, } => { let (plan, variables) = PlanBuilder::build(&connection, &algebra)?; SimplePreparedQueryOptions::Select { plan, variables, evaluator: SimpleEvaluator::new(connection), } } Query::Ask { algebra, dataset: _, } => { let (plan, _) = PlanBuilder::build(&connection, &algebra)?; SimplePreparedQueryOptions::Ask { plan, evaluator: SimpleEvaluator::new(connection), } } Query::Construct { construct, algebra, dataset: _, } => { let (plan, variables) = PlanBuilder::build(&connection, &algebra)?; SimplePreparedQueryOptions::Construct { plan, construct: PlanBuilder::build_graph_template( &connection, &construct, variables, )?, evaluator: SimpleEvaluator::new(connection), } } Query::Describe { algebra, dataset: _, } => { let (plan, _) = PlanBuilder::build(&connection, &algebra)?; SimplePreparedQueryOptions::Describe { plan, evaluator: SimpleEvaluator::new(connection), } } })) } } impl PreparedQuery for SimplePreparedQuery { fn exec(&self) -> Result> { match &self.0 { SimplePreparedQueryOptions::Select { plan, variables, evaluator, } => evaluator.evaluate_select_plan(&plan, &variables), SimplePreparedQueryOptions::Ask { plan, evaluator } => { evaluator.evaluate_ask_plan(&plan) } SimplePreparedQueryOptions::Construct { plan, construct, evaluator, } => evaluator.evaluate_construct_plan(&plan, &construct), SimplePreparedQueryOptions::Describe { plan, evaluator } => { evaluator.evaluate_describe_plan(&plan) } } } }