Fork of https://github.com/oxigraph/oxigraph.git for the purpose of NextGraph project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
oxigraph/lib/src/sparql/mod.rs

154 lines
4.8 KiB

//! [SPARQL](https://www.w3.org/TR/sparql11-overview/) implementation.
mod algebra;
mod eval;
mod json_results;
mod model;
mod parser;
mod plan;
mod plan_builder;
mod xml_results;
use crate::sparql::algebra::QueryVariants;
use crate::sparql::eval::SimpleEvaluator;
use crate::sparql::parser::read_sparql_query;
use crate::sparql::plan::PlanNode;
use crate::sparql::plan::TripleTemplate;
use crate::sparql::plan_builder::PlanBuilder;
use crate::store::StoreConnection;
use crate::Result;
use std::fmt;
pub use crate::sparql::model::BindingsIterator;
pub use crate::sparql::model::QueryResult;
pub use crate::sparql::model::QueryResultSyntax;
pub use crate::sparql::model::Variable;
/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/)
pub trait PreparedQuery {
/// Evaluates the query and returns its results
fn exec(&self) -> Result<QueryResult>;
}
/// An implementation of `PreparedQuery` for internal use
pub struct SimplePreparedQuery<S: StoreConnection>(SimplePreparedQueryOptions<S>);
enum SimplePreparedQueryOptions<S: StoreConnection> {
Select {
plan: PlanNode,
variables: Vec<Variable>,
evaluator: SimpleEvaluator<S>,
},
Ask {
plan: PlanNode,
evaluator: SimpleEvaluator<S>,
},
Construct {
plan: PlanNode,
construct: Vec<TripleTemplate>,
evaluator: SimpleEvaluator<S>,
},
Describe {
plan: PlanNode,
evaluator: SimpleEvaluator<S>,
},
}
impl<S: StoreConnection> SimplePreparedQuery<S> {
pub(crate) fn new(connection: S, query: &str, base_iri: Option<&str>) -> Result<Self> {
//TODO avoid inserting terms in the Repository StringStore
Ok(Self(match read_sparql_query(query, base_iri)? {
QueryVariants::Select {
algebra,
dataset: _,
base_iri,
} => {
let (plan, variables) = PlanBuilder::build(&connection, &algebra)?;
SimplePreparedQueryOptions::Select {
plan,
variables,
evaluator: SimpleEvaluator::new(connection, base_iri),
}
}
QueryVariants::Ask {
algebra,
dataset: _,
base_iri,
} => {
let (plan, _) = PlanBuilder::build(&connection, &algebra)?;
SimplePreparedQueryOptions::Ask {
plan,
evaluator: SimpleEvaluator::new(connection, base_iri),
}
}
QueryVariants::Construct {
construct,
algebra,
dataset: _,
base_iri,
} => {
let (plan, variables) = PlanBuilder::build(&connection, &algebra)?;
SimplePreparedQueryOptions::Construct {
plan,
construct: PlanBuilder::build_graph_template(
&connection,
&construct,
variables,
)?,
evaluator: SimpleEvaluator::new(connection, base_iri),
}
}
QueryVariants::Describe {
algebra,
dataset: _,
base_iri,
} => {
let (plan, _) = PlanBuilder::build(&connection, &algebra)?;
SimplePreparedQueryOptions::Describe {
plan,
evaluator: SimpleEvaluator::new(connection, base_iri),
}
}
}))
}
}
impl<S: StoreConnection> PreparedQuery for SimplePreparedQuery<S> {
fn exec(&self) -> Result<QueryResult<'_>> {
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)
}
}
}
}
/// A parsed [SPARQL query](https://www.w3.org/TR/sparql11-query/)
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Query(QueryVariants);
impl fmt::Display for Query {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl Query {
/// Parses a SPARQL query
pub fn parse(query: &str, base_iri: Option<&str>) -> Result<Self> {
Ok(Query(read_sparql_query(query, base_iri)?))
}
}