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

127 lines
4.0 KiB

//! [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<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: impl Read) -> Result<Self> {
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<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)
}
}
}
}