Cleanup SPARQL module public API

pull/10/head
Tpt 5 years ago
parent fd3def2daf
commit d617e72550
  1. 12
      lib/src/lib.rs
  2. 2
      lib/src/model/isomorphism.rs
  3. 4
      lib/src/repository.rs
  4. 196
      lib/src/sparql/algebra.rs
  5. 2
      lib/src/sparql/eval.rs
  6. 48
      lib/src/sparql/mod.rs
  7. 210
      lib/src/sparql/model.rs
  8. 6
      lib/src/sparql/parser.rs
  9. 1
      lib/src/sparql/plan.rs
  10. 24
      lib/src/sparql/sparql_grammar.rustpeg
  11. 4
      lib/src/sparql/xml_results.rs
  12. 2
      lib/src/store/memory.rs
  13. 2
      lib/src/store/rocksdb.rs
  14. 0
      lib/src/syntax.rs
  15. 34
      lib/tests/sparql_test_cases.rs
  16. 9
      server/src/main.rs

@ -12,7 +12,7 @@
//! use rudf::model::*; //! use rudf::model::*;
//! use rudf::{Repository, RepositoryConnection, MemoryRepository, Result}; //! use rudf::{Repository, RepositoryConnection, MemoryRepository, Result};
//! use crate::rudf::sparql::PreparedQuery; //! use crate::rudf::sparql::PreparedQuery;
//! use rudf::sparql::algebra::QueryResult; //! use rudf::sparql::QueryResult;
//! //!
//! let repository = MemoryRepository::default(); //! let repository = MemoryRepository::default();
//! let connection = repository.connection().unwrap(); //! let connection = repository.connection().unwrap();
@ -36,16 +36,16 @@
pub mod model; pub mod model;
mod repository; mod repository;
mod rio;
pub mod sparql; pub mod sparql;
pub(crate) mod store; pub(crate) mod store;
mod syntax;
pub use failure::Error; pub use failure::Error;
pub type Result<T> = ::std::result::Result<T, failure::Error>; pub type Result<T> = ::std::result::Result<T, failure::Error>;
pub use crate::repository::Repository;
pub use crate::repository::RepositoryConnection;
pub use crate::store::MemoryRepository; pub use crate::store::MemoryRepository;
#[cfg(feature = "rocksdb")] #[cfg(feature = "rocksdb")]
pub use crate::store::RocksDbRepository; pub use crate::store::RocksDbRepository;
pub use repository::Repository; pub use crate::syntax::DatasetSyntax;
pub use repository::RepositoryConnection; pub use crate::syntax::GraphSyntax;
pub use rio::DatasetSyntax;
pub use rio::GraphSyntax;

@ -151,7 +151,7 @@ fn build_and_check_containment_from_hashes<'a>(
let mut new_b_nodes = b_bnodes_by_hash let mut new_b_nodes = b_bnodes_by_hash
.get(&hash) .get(&hash)
.map_or(BTreeSet::default(), |v| v.into_iter().cloned().collect()); .map_or(BTreeSet::default(), |v| v.iter().cloned().collect());
if new_a_nodes.len() != new_b_nodes.len() { if new_a_nodes.len() != new_b_nodes.len() {
return false; return false;
} }

@ -15,7 +15,7 @@ use std::io::{BufRead, Read};
/// use rudf::model::*; /// use rudf::model::*;
/// use rudf::{Repository, RepositoryConnection, MemoryRepository, Result}; /// use rudf::{Repository, RepositoryConnection, MemoryRepository, Result};
/// use crate::rudf::sparql::PreparedQuery; /// use crate::rudf::sparql::PreparedQuery;
/// use rudf::sparql::algebra::QueryResult; /// use rudf::sparql::QueryResult;
/// ///
/// let repository = MemoryRepository::default(); /// let repository = MemoryRepository::default();
/// let connection = repository.connection().unwrap(); /// let connection = repository.connection().unwrap();
@ -65,7 +65,7 @@ pub trait RepositoryConnection: Clone {
/// use rudf::model::*; /// use rudf::model::*;
/// use rudf::{Repository, RepositoryConnection, MemoryRepository}; /// use rudf::{Repository, RepositoryConnection, MemoryRepository};
/// use rudf::sparql::PreparedQuery; /// use rudf::sparql::PreparedQuery;
/// use rudf::sparql::algebra::QueryResult; /// use rudf::sparql::QueryResult;
/// ///
/// let repository = MemoryRepository::default(); /// let repository = MemoryRepository::default();
/// let connection = repository.connection().unwrap(); /// let connection = repository.connection().unwrap();

@ -1,151 +1,13 @@
//! [SPARQL 1.1 Query Algebra](https://www.w3.org/TR/sparql11-query/#sparqlQuery) AST //! [SPARQL 1.1 Query Algebra](https://www.w3.org/TR/sparql11-query/#sparqlQuery) AST
use crate::model::*; use crate::model::*;
use crate::Result; use crate::sparql::model::*;
use failure::format_err;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use rio_api::model as rio; use rio_api::model as rio;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::fmt; use std::fmt;
use std::ops::Add; use std::ops::Add;
use uuid::Uuid;
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Variable {
Variable { name: String },
BlankNode { id: Uuid },
Internal { id: Uuid },
}
impl Variable {
pub fn new(name: impl Into<String>) -> Self {
Variable::Variable { name: name.into() }
}
pub fn has_name(&self) -> bool {
match self {
Variable::Variable { .. } => true,
_ => false,
}
}
pub fn name(&self) -> Result<&str> {
match self {
Variable::Variable { name } => Ok(name),
_ => Err(format_err!("The variable {} has no name", self)),
}
}
}
impl fmt::Display for Variable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Variable::Variable { name } => write!(f, "?{}", name),
Variable::BlankNode { id } => write!(f, "_:{}", id.to_simple()),
Variable::Internal { id } => write!(f, "?{}", id.to_simple()),
}
}
}
impl Default for Variable {
fn default() -> Self {
Variable::Internal { id: Uuid::new_v4() }
}
}
impl From<BlankNode> for Variable {
fn from(blank_node: BlankNode) -> Self {
Variable::BlankNode {
id: *blank_node.as_uuid(),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum NamedNodeOrVariable {
NamedNode(NamedNode),
Variable(Variable),
}
impl fmt::Display for NamedNodeOrVariable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NamedNodeOrVariable::NamedNode(node) => write!(f, "{}", node),
NamedNodeOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for NamedNodeOrVariable {
fn from(node: NamedNode) -> Self {
NamedNodeOrVariable::NamedNode(node)
}
}
impl From<Variable> for NamedNodeOrVariable {
fn from(var: Variable) -> Self {
NamedNodeOrVariable::Variable(var)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum TermOrVariable {
Term(Term),
Variable(Variable),
}
impl fmt::Display for TermOrVariable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TermOrVariable::Term(term) => write!(f, "{}", term),
TermOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for TermOrVariable {
fn from(node: NamedNode) -> Self {
TermOrVariable::Term(node.into())
}
}
impl From<BlankNode> for TermOrVariable {
fn from(node: BlankNode) -> Self {
TermOrVariable::Variable(node.into())
}
}
impl From<Literal> for TermOrVariable {
fn from(literal: Literal) -> Self {
TermOrVariable::Term(literal.into())
}
}
impl From<Variable> for TermOrVariable {
fn from(var: Variable) -> Self {
TermOrVariable::Variable(var)
}
}
impl From<Term> for TermOrVariable {
fn from(term: Term) -> Self {
match term {
Term::NamedNode(node) => TermOrVariable::Term(node.into()),
Term::BlankNode(node) => TermOrVariable::Variable(node.into()),
Term::Literal(literal) => TermOrVariable::Term(literal.into()),
}
}
}
impl From<NamedNodeOrVariable> for TermOrVariable {
fn from(element: NamedNodeOrVariable) -> Self {
match element {
NamedNodeOrVariable::NamedNode(node) => TermOrVariable::Term(node.into()),
NamedNodeOrVariable::Variable(var) => TermOrVariable::Variable(var),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct StaticBindings { pub struct StaticBindings {
@ -170,13 +32,6 @@ impl StaticBindings {
self.values.iter() self.values.iter()
} }
pub fn into_iterator(self) -> BindingsIterator<'static> {
BindingsIterator {
variables: self.variables,
iter: Box::new(self.values.into_iter().map(Ok)),
}
}
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.values.is_empty() self.values.is_empty()
} }
@ -191,37 +46,6 @@ impl Default for StaticBindings {
} }
} }
pub struct BindingsIterator<'a> {
variables: Vec<Variable>,
iter: Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>,
}
impl<'a> BindingsIterator<'a> {
pub fn new(
variables: Vec<Variable>,
iter: Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>,
) -> Self {
Self { variables, iter }
}
pub fn variables(&self) -> &[Variable] {
&*self.variables
}
pub fn into_values_iter(self) -> Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a> {
self.iter
}
pub fn destruct(
self,
) -> (
Vec<Variable>,
Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>,
) {
(self.variables, self.iter)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct TriplePattern { pub struct TriplePattern {
pub subject: TermOrVariable, pub subject: TermOrVariable,
@ -1364,7 +1188,7 @@ lazy_static! {
} }
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Query { pub enum QueryVariants {
Select { Select {
dataset: DatasetSpec, dataset: DatasetSpec,
algebra: GraphPattern, algebra: GraphPattern,
@ -1384,10 +1208,10 @@ pub enum Query {
}, },
} }
impl fmt::Display for Query { impl fmt::Display for QueryVariants {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Query::Select { dataset, algebra } => write!( QueryVariants::Select { dataset, algebra } => write!(
f, f,
"{}", "{}",
SparqlGraphRootPattern { SparqlGraphRootPattern {
@ -1395,7 +1219,7 @@ impl fmt::Display for Query {
dataset: &dataset dataset: &dataset
} }
), ),
Query::Construct { QueryVariants::Construct {
construct, construct,
dataset, dataset,
algebra, algebra,
@ -1413,7 +1237,7 @@ impl fmt::Display for Query {
dataset: &EMPTY_DATASET dataset: &EMPTY_DATASET
} }
), ),
Query::Describe { dataset, algebra } => write!( QueryVariants::Describe { dataset, algebra } => write!(
f, f,
"DESCRIBE * {} WHERE {{ {} }}", "DESCRIBE * {} WHERE {{ {} }}",
dataset, dataset,
@ -1422,7 +1246,7 @@ impl fmt::Display for Query {
dataset: &EMPTY_DATASET dataset: &EMPTY_DATASET
} }
), ),
Query::Ask { dataset, algebra } => write!( QueryVariants::Ask { dataset, algebra } => write!(
f, f,
"ASK {} WHERE {{ {} }}", "ASK {} WHERE {{ {} }}",
dataset, dataset,
@ -1434,9 +1258,3 @@ impl fmt::Display for Query {
} }
} }
} }
pub enum QueryResult<'a> {
Bindings(BindingsIterator<'a>),
Boolean(bool),
Graph(Box<dyn Iterator<Item = Result<Triple>> + 'a>),
}

@ -1,6 +1,6 @@
use crate::model::BlankNode; use crate::model::BlankNode;
use crate::model::Triple; use crate::model::Triple;
use crate::sparql::algebra::*; use crate::sparql::model::*;
use crate::sparql::plan::*; use crate::sparql::plan::*;
use crate::store::numeric_encoder::*; use crate::store::numeric_encoder::*;
use crate::store::StoreConnection; use crate::store::StoreConnection;

@ -1,8 +1,13 @@
//! [SPARQL](https://www.w3.org/TR/sparql11-overview/) implementation. //! [SPARQL](https://www.w3.org/TR/sparql11-overview/) implementation.
use crate::sparql::algebra::Query; mod algebra;
use crate::sparql::algebra::QueryResult; mod eval;
use crate::sparql::algebra::Variable; mod model;
mod parser;
mod plan;
mod xml_results;
use crate::sparql::algebra::QueryVariants;
use crate::sparql::eval::SimpleEvaluator; use crate::sparql::eval::SimpleEvaluator;
use crate::sparql::parser::read_sparql_query; use crate::sparql::parser::read_sparql_query;
use crate::sparql::plan::PlanBuilder; use crate::sparql::plan::PlanBuilder;
@ -10,15 +15,15 @@ use crate::sparql::plan::PlanNode;
use crate::sparql::plan::TripleTemplate; use crate::sparql::plan::TripleTemplate;
use crate::store::StoreConnection; use crate::store::StoreConnection;
use crate::Result; use crate::Result;
use std::fmt;
use std::io::Read; use std::io::Read;
pub mod algebra; pub use crate::sparql::model::BindingsIterator;
mod eval; pub use crate::sparql::model::QueryResult;
pub mod parser; pub use crate::sparql::model::QueryResultSyntax;
mod plan; pub use crate::sparql::model::Variable;
pub mod xml_results;
/// A prepared [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/) query /// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/)
pub trait PreparedQuery { pub trait PreparedQuery {
/// Evaluates the query and returns its results /// Evaluates the query and returns its results
fn exec(&self) -> Result<QueryResult<'_>>; fn exec(&self) -> Result<QueryResult<'_>>;
@ -51,7 +56,7 @@ enum SimplePreparedQueryOptions<S: StoreConnection> {
impl<S: StoreConnection> SimplePreparedQuery<S> { impl<S: StoreConnection> SimplePreparedQuery<S> {
pub(crate) fn new(connection: S, query: impl Read) -> Result<Self> { pub(crate) fn new(connection: S, query: impl Read) -> Result<Self> {
Ok(Self(match read_sparql_query(query, None)? { Ok(Self(match read_sparql_query(query, None)? {
Query::Select { QueryVariants::Select {
algebra, algebra,
dataset: _, dataset: _,
} => { } => {
@ -62,7 +67,7 @@ impl<S: StoreConnection> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(connection), evaluator: SimpleEvaluator::new(connection),
} }
} }
Query::Ask { QueryVariants::Ask {
algebra, algebra,
dataset: _, dataset: _,
} => { } => {
@ -72,7 +77,7 @@ impl<S: StoreConnection> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(connection), evaluator: SimpleEvaluator::new(connection),
} }
} }
Query::Construct { QueryVariants::Construct {
construct, construct,
algebra, algebra,
dataset: _, dataset: _,
@ -88,7 +93,7 @@ impl<S: StoreConnection> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(connection), evaluator: SimpleEvaluator::new(connection),
} }
} }
Query::Describe { QueryVariants::Describe {
algebra, algebra,
dataset: _, dataset: _,
} => { } => {
@ -124,3 +129,20 @@ impl<S: StoreConnection> PreparedQuery for SimplePreparedQuery<S> {
} }
} }
} }
/// A parsed [SPARQL query](https://www.w3.org/TR/sparql11-query/)
#[derive(Eq, PartialEq, Ord, PartialOrd, 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 read<'a>(reader: impl Read + 'a, base_iri: Option<&'a str>) -> Result<Self> {
Ok(Query(read_sparql_query(reader, base_iri)?))
}
}

@ -0,0 +1,210 @@
use crate::model::*;
use crate::sparql::xml_results::{read_xml_results, write_xml_results};
use crate::Result;
use failure::format_err;
use std::fmt;
use std::io::{BufRead, Write};
use uuid::Uuid;
/// Results of a [SPARQL query](https://www.w3.org/TR/sparql11-query/)
pub enum QueryResult<'a> {
/// Results of a [SELECT](https://www.w3.org/TR/sparql11-query/#select) query
Bindings(BindingsIterator<'a>),
/// Result of a [ASK](https://www.w3.org/TR/sparql11-query/#ask) query
Boolean(bool),
/// Results of a [CONSTRUCT](https://www.w3.org/TR/sparql11-query/#construct) or [DESCRIBE](https://www.w3.org/TR/sparql11-query/#describe) query
Graph(Box<dyn Iterator<Item = Result<Triple>> + 'a>),
}
impl<'a> QueryResult<'a> {
pub fn read(
reader: impl BufRead + 'static,
syntax: QueryResultSyntax,
) -> Result<QueryResult<'static>> {
match syntax {
QueryResultSyntax::Xml => read_xml_results(reader),
}
}
pub fn write<W: Write>(self, writer: W, syntax: QueryResultSyntax) -> Result<W> {
match syntax {
QueryResultSyntax::Xml => write_xml_results(self, writer),
}
}
}
/// [SPARQL query](https://www.w3.org/TR/sparql11-query/) serialization formats
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum QueryResultSyntax {
/// [SPARQL Query Results XML Format](http://www.w3.org/TR/rdf-sparql-XMLres/)
Xml,
}
/// An iterator over results bindings
pub struct BindingsIterator<'a> {
variables: Vec<Variable>,
iter: Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>,
}
impl<'a> BindingsIterator<'a> {
pub(crate) fn new(
variables: Vec<Variable>,
iter: Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>,
) -> Self {
Self { variables, iter }
}
pub fn variables(&self) -> &[Variable] {
&*self.variables
}
pub fn into_values_iter(self) -> Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a> {
self.iter
}
pub fn destruct(
self,
) -> (
Vec<Variable>,
Box<dyn Iterator<Item = Result<Vec<Option<Term>>>> + 'a>,
) {
(self.variables, self.iter)
}
}
/// A SPARQL query variable
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Variable {
Variable { name: String },
BlankNode { id: Uuid },
Internal { id: Uuid },
}
impl Variable {
pub fn new(name: impl Into<String>) -> Self {
Variable::Variable { name: name.into() }
}
pub fn has_name(&self) -> bool {
match self {
Variable::Variable { .. } => true,
_ => false,
}
}
pub fn name(&self) -> Result<&str> {
match self {
Variable::Variable { name } => Ok(name),
_ => Err(format_err!("The variable {} has no name", self)),
}
}
}
impl fmt::Display for Variable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Variable::Variable { name } => write!(f, "?{}", name),
Variable::BlankNode { id } => write!(f, "_:{}", id.to_simple()),
Variable::Internal { id } => write!(f, "?{}", id.to_simple()),
}
}
}
impl Default for Variable {
fn default() -> Self {
Variable::Internal { id: Uuid::new_v4() }
}
}
impl From<BlankNode> for Variable {
fn from(blank_node: BlankNode) -> Self {
Variable::BlankNode {
id: *blank_node.as_uuid(),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum NamedNodeOrVariable {
NamedNode(NamedNode),
Variable(Variable),
}
impl fmt::Display for NamedNodeOrVariable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NamedNodeOrVariable::NamedNode(node) => write!(f, "{}", node),
NamedNodeOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for NamedNodeOrVariable {
fn from(node: NamedNode) -> Self {
NamedNodeOrVariable::NamedNode(node)
}
}
impl From<Variable> for NamedNodeOrVariable {
fn from(var: Variable) -> Self {
NamedNodeOrVariable::Variable(var)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum TermOrVariable {
Term(Term),
Variable(Variable),
}
impl fmt::Display for TermOrVariable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TermOrVariable::Term(term) => write!(f, "{}", term),
TermOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for TermOrVariable {
fn from(node: NamedNode) -> Self {
TermOrVariable::Term(node.into())
}
}
impl From<BlankNode> for TermOrVariable {
fn from(node: BlankNode) -> Self {
TermOrVariable::Variable(node.into())
}
}
impl From<Literal> for TermOrVariable {
fn from(literal: Literal) -> Self {
TermOrVariable::Term(literal.into())
}
}
impl From<Variable> for TermOrVariable {
fn from(var: Variable) -> Self {
TermOrVariable::Variable(var)
}
}
impl From<Term> for TermOrVariable {
fn from(term: Term) -> Self {
match term {
Term::NamedNode(node) => TermOrVariable::Term(node.into()),
Term::BlankNode(node) => TermOrVariable::Variable(node.into()),
Term::Literal(literal) => TermOrVariable::Term(literal.into()),
}
}
}
impl From<NamedNodeOrVariable> for TermOrVariable {
fn from(element: NamedNodeOrVariable) -> Self {
match element {
NamedNodeOrVariable::NamedNode(node) => TermOrVariable::Term(node.into()),
NamedNodeOrVariable::Variable(var) => TermOrVariable::Variable(var),
}
}
}

@ -7,11 +7,13 @@ mod grammar {
clippy::naive_bytecount, clippy::naive_bytecount,
clippy::cognitive_complexity, clippy::cognitive_complexity,
clippy::many_single_char_names, clippy::many_single_char_names,
clippy::type_complexity clippy::type_complexity,
ellipsis_inclusive_range_patterns
)] )]
use crate::model::*; use crate::model::*;
use crate::sparql::algebra::*; use crate::sparql::algebra::*;
use crate::sparql::model::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::borrow::Cow; use std::borrow::Cow;
use std::char; use std::char;
@ -532,7 +534,7 @@ mod grammar {
pub fn read_sparql_query<'a, R: Read + 'a>( pub fn read_sparql_query<'a, R: Read + 'a>(
source: R, source: R,
base_uri: Option<&'a str>, base_uri: Option<&'a str>,
) -> super::super::super::Result<Query> { ) -> super::super::super::Result<QueryVariants> {
let mut state = ParserState { let mut state = ParserState {
base_uri: if let Some(base_uri) = base_uri { base_uri: if let Some(base_uri) = base_uri {
Some(Url::parse(base_uri)?) Some(Url::parse(base_uri)?)

@ -1,6 +1,7 @@
use crate::model::vocab::xsd; use crate::model::vocab::xsd;
use crate::model::Literal; use crate::model::Literal;
use crate::sparql::algebra::*; use crate::sparql::algebra::*;
use crate::sparql::model::*;
use crate::store::numeric_encoder::EncodedTerm; use crate::store::numeric_encoder::EncodedTerm;
use crate::store::numeric_encoder::ENCODED_DEFAULT_GRAPH; use crate::store::numeric_encoder::ENCODED_DEFAULT_GRAPH;
use crate::store::StoreConnection; use crate::store::StoreConnection;

@ -8,10 +8,10 @@ use std::str::FromStr;
//[1] //[1]
pub QueryUnit -> Query = Query pub QueryUnit -> QueryVariants = Query
//[2] //[2]
Query -> Query = _ Prologue _ q:(SelectQuery / ConstructQuery / DescribeQuery / AskQuery) _ { //TODO: ValuesClause Query -> QueryVariants = _ Prologue _ q:(SelectQuery / ConstructQuery / DescribeQuery / AskQuery) _ { //TODO: ValuesClause
q q
} }
@ -35,8 +35,8 @@ PrefixDecl -> () = "PREFIX"i _ ns:PNAME_NS _ i:IRIREF {
} }
//[7] //[7]
SelectQuery -> Query = s:SelectClause _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { //TODO: Modifier SelectQuery -> QueryVariants = s:SelectClause _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { //TODO: Modifier
Query::Select { QueryVariants::Select {
dataset: d, dataset: d,
algebra: build_select(s, w, g, h, o, l, v, state) algebra: build_select(s, w, g, h, o, l, v, state)
} }
@ -66,16 +66,16 @@ SelectClause_member -> SelectionMember =
'(' _ e:Expression _ "AS"i _ v:Var _ ')' _ { SelectionMember::Expression(e, v) } '(' _ e:Expression _ "AS"i _ v:Var _ ')' _ { SelectionMember::Expression(e, v) }
//[10] //[10]
ConstructQuery -> Query = ConstructQuery -> QueryVariants =
"CONSTRUCT"i _ c:ConstructTemplate _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { "CONSTRUCT"i _ c:ConstructTemplate _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Construct { QueryVariants::Construct {
construct: c, construct: c,
dataset: d, dataset: d,
algebra: build_select(Selection::default(), w, g, h, o, l, v, state) algebra: build_select(Selection::default(), w, g, h, o, l, v, state)
} }
} / } /
"CONSTRUCT"i _ d:DatasetClauses _ "WHERE"i _ '{' _ c:ConstructQuery_optional_triple_template _ '}' _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { "CONSTRUCT"i _ d:DatasetClauses _ "WHERE"i _ '{' _ c:ConstructQuery_optional_triple_template _ '}' _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Construct { QueryVariants::Construct {
construct: c.clone(), construct: c.clone(),
dataset: d, dataset: d,
algebra: build_select( algebra: build_select(
@ -89,15 +89,15 @@ ConstructQuery -> Query =
ConstructQuery_optional_triple_template -> Vec<TriplePattern> = TriplesTemplate / { Vec::default() } ConstructQuery_optional_triple_template -> Vec<TriplePattern> = TriplesTemplate / { Vec::default() }
//[11] //[11]
DescribeQuery -> Query = DescribeQuery -> QueryVariants =
"DESCRIBE"i _ '*' _ d:DatasetClauses w:WhereClause? _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { "DESCRIBE"i _ '*' _ d:DatasetClauses w:WhereClause? _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Describe { QueryVariants::Describe {
dataset: d, dataset: d,
algebra: build_select(Selection::default(), w.unwrap_or_else(GraphPattern::default), g, h, o, l, v, state) algebra: build_select(Selection::default(), w.unwrap_or_else(GraphPattern::default), g, h, o, l, v, state)
} }
} / } /
"DESCRIBE"i _ p:DescribeQuery_item+ _ d:DatasetClauses w:WhereClause? _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { "DESCRIBE"i _ p:DescribeQuery_item+ _ d:DatasetClauses w:WhereClause? _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Describe { QueryVariants::Describe {
dataset: d, dataset: d,
algebra: build_select(Selection { algebra: build_select(Selection {
option: SelectionOption::Default, option: SelectionOption::Default,
@ -111,8 +111,8 @@ DescribeQuery -> Query =
DescribeQuery_item -> NamedNodeOrVariable = i:VarOrIri _ { i } DescribeQuery_item -> NamedNodeOrVariable = i:VarOrIri _ { i }
//[12] //[12]
AskQuery -> Query = "ASK"i _ d:DatasetClauses w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { AskQuery -> QueryVariants = "ASK"i _ d:DatasetClauses w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Ask { QueryVariants::Ask {
dataset: d, dataset: d,
algebra: build_select(Selection::default(), w, g, h, o, l, v, state) algebra: build_select(Selection::default(), w, g, h, o, l, v, state)
} }

@ -1,9 +1,7 @@
//! Implementation of [SPARQL Query Results XML Format](http://www.w3.org/TR/rdf-sparql-XMLres/) //! Implementation of [SPARQL Query Results XML Format](http://www.w3.org/TR/rdf-sparql-XMLres/)
use crate::model::*; use crate::model::*;
use crate::sparql::algebra::BindingsIterator; use crate::sparql::model::*;
use crate::sparql::algebra::QueryResult;
use crate::sparql::algebra::Variable;
use crate::Result; use crate::Result;
use failure::format_err; use failure::format_err;
use quick_xml::events::BytesDecl; use quick_xml::events::BytesDecl;

@ -18,7 +18,7 @@ use std::sync::RwLockWriteGuard;
/// use rudf::model::*; /// use rudf::model::*;
/// use rudf::{Repository, RepositoryConnection, MemoryRepository, Result}; /// use rudf::{Repository, RepositoryConnection, MemoryRepository, Result};
/// use crate::rudf::sparql::PreparedQuery; /// use crate::rudf::sparql::PreparedQuery;
/// use rudf::sparql::algebra::QueryResult; /// use rudf::sparql::QueryResult;
/// ///
/// let repository = MemoryRepository::default(); /// let repository = MemoryRepository::default();
/// let connection = repository.connection().unwrap(); /// let connection = repository.connection().unwrap();

@ -28,7 +28,7 @@ use std::sync::Mutex;
/// use rudf::model::*; /// use rudf::model::*;
/// use rudf::{Repository, RepositoryConnection, RocksDbRepository, Result}; /// use rudf::{Repository, RepositoryConnection, RocksDbRepository, Result};
/// use crate::rudf::sparql::PreparedQuery; /// use crate::rudf::sparql::PreparedQuery;
/// use rudf::sparql::algebra::QueryResult; /// use rudf::sparql::QueryResult;
/// ///
/// let repository = RocksDbRepository::open("example.db").unwrap(); /// let repository = RocksDbRepository::open("example.db").unwrap();
/// let connection = repository.connection().unwrap(); /// let connection = repository.connection().unwrap();

@ -3,14 +3,12 @@ use failure::format_err;
use rudf::model::vocab::rdf; use rudf::model::vocab::rdf;
use rudf::model::vocab::rdfs; use rudf::model::vocab::rdfs;
use rudf::model::*; use rudf::model::*;
use rudf::sparql::algebra::Query;
use rudf::sparql::algebra::QueryResult;
use rudf::sparql::parser::read_sparql_query;
use rudf::sparql::xml_results::read_xml_results;
use rudf::sparql::PreparedQuery; use rudf::sparql::PreparedQuery;
use rudf::sparql::{Query, QueryResult, QueryResultSyntax};
use rudf::{GraphSyntax, MemoryRepository, Repository, RepositoryConnection, Result}; use rudf::{GraphSyntax, MemoryRepository, Repository, RepositoryConnection, Result};
use std::fmt; use std::fmt;
use std::fs::File; use std::fs::File;
use std::io::Read;
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use std::path::PathBuf; use std::path::PathBuf;
@ -21,7 +19,6 @@ fn sparql_w3c_syntax_testsuite() {
"http://www.w3.org/2009/sparql/docs/tests/data-sparql11/syntax-query/manifest.ttl"; "http://www.w3.org/2009/sparql/docs/tests/data-sparql11/syntax-query/manifest.ttl";
let test_blacklist = vec![ let test_blacklist = vec![
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql2/manifest#syntax-form-construct02"), NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql2/manifest#syntax-form-construct02"),
//TODO: Deserialization of the serialization failing:
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql2/manifest#syntax-form-construct04"), NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql2/manifest#syntax-form-construct04"),
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql2/manifest#syntax-function-04"), NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql2/manifest#syntax-function-04"),
NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql1/manifest#syntax-qname-04"), NamedNode::new("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql1/manifest#syntax-qname-04"),
@ -34,10 +31,10 @@ fn sparql_w3c_syntax_testsuite() {
continue; continue;
} }
if test.kind == "PositiveSyntaxTest" || test.kind == "PositiveSyntaxTest11" { if test.kind == "PositiveSyntaxTest" || test.kind == "PositiveSyntaxTest11" {
match load_sparql_query(&test.query) { match load_query(&test.query) {
Err(error) => assert!(false, "Failure on {} with error: {}", test, error), Err(error) => assert!(false, "Failure on {} with error: {}", test, error),
Ok(query) => { Ok(query) => {
if let Err(error) = read_sparql_query(query.to_string().as_bytes(), None) { if let Err(error) = Query::read(query.to_string().as_bytes(), None) {
assert!( assert!(
false, false,
"Failure to deserialize \"{}\" of {} with error: {}", "Failure to deserialize \"{}\" of {} with error: {}",
@ -50,7 +47,7 @@ fn sparql_w3c_syntax_testsuite() {
} }
} else if test.kind == "NegativeSyntaxTest" || test.kind == "NegativeSyntaxTest11" { } else if test.kind == "NegativeSyntaxTest" || test.kind == "NegativeSyntaxTest11" {
//TODO //TODO
if let Ok(result) = load_sparql_query(&test.query) { if let Ok(result) = load_query(&test.query) {
eprintln!("Failure on {}. The output tree is: {}", test, result); eprintln!("Failure on {}. The output tree is: {}", test, result);
} }
} else { } else {
@ -163,7 +160,7 @@ fn sparql_w3c_query_evaluation_testsuite() {
test, test,
expected_graph, expected_graph,
actual_graph, actual_graph,
load_sparql_query(&test.query).unwrap(), read_file_to_string(&test.query).unwrap(),
repository_to_string(&repository) repository_to_string(&repository)
) )
} }
@ -210,18 +207,21 @@ fn load_graph_to_repository(
connection.load_graph(read_file(url)?, syntax, to_graph_name, Some(url)) connection.load_graph(read_file(url)?, syntax, to_graph_name, Some(url))
} }
fn load_sparql_query(url: &str) -> Result<Query> {
read_sparql_query(read_file(url)?, Some(url))
}
fn load_sparql_query_result_graph(url: &str) -> Result<SimpleGraph> { fn load_sparql_query_result_graph(url: &str) -> Result<SimpleGraph> {
if url.ends_with(".srx") { if url.ends_with(".srx") {
to_graph(read_xml_results(read_file(url)?)?, false) to_graph(
QueryResult::read(read_file(url)?, QueryResultSyntax::Xml)?,
false,
)
} else { } else {
load_graph(url) load_graph(url)
} }
} }
fn load_query(url: &str) -> Result<Query> {
Query::read(read_file(&url)?, Some(&url))
}
fn to_relative_path(url: &str) -> Result<String> { fn to_relative_path(url: &str) -> Result<String> {
if url.starts_with("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/") { if url.starts_with("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/") {
Ok(url.replace( Ok(url.replace(
@ -248,6 +248,12 @@ fn read_file(url: &str) -> Result<impl BufRead> {
})?)) })?))
} }
fn read_file_to_string(url: &str) -> Result<String> {
let mut string = String::default();
read_file(url)?.read_to_string(&mut string)?;
Ok(string)
}
mod rs { mod rs {
use lazy_static::lazy_static; use lazy_static::lazy_static;
use rudf::model::NamedNode; use rudf::model::NamedNode;

@ -27,9 +27,8 @@ use hyper::StatusCode;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use mime; use mime;
use mime::Mime; use mime::Mime;
use rudf::sparql::algebra::QueryResult; use rudf::sparql::QueryResult;
use rudf::sparql::xml_results::write_xml_results; use rudf::sparql::{PreparedQuery, QueryResultSyntax};
use rudf::sparql::PreparedQuery;
use rudf::RepositoryConnection; use rudf::RepositoryConnection;
use rudf::{GraphSyntax, Repository}; use rudf::{GraphSyntax, Repository};
use rudf::{MemoryRepository, RocksDbRepository}; use rudf::{MemoryRepository, RocksDbRepository};
@ -282,7 +281,9 @@ where
&state, &state,
StatusCode::OK, StatusCode::OK,
APPLICATION_SPARQL_RESULTS_UTF_8.clone(), APPLICATION_SPARQL_RESULTS_UTF_8.clone(),
write_xml_results(result, Vec::default()).unwrap(), result
.write(Vec::default(), QueryResultSyntax::Xml)
.unwrap(),
), ),
Err(error) => error_to_response(&state, &error, StatusCode::INTERNAL_SERVER_ERROR), Err(error) => error_to_response(&state, &error, StatusCode::INTERNAL_SERVER_ERROR),
}, },

Loading…
Cancel
Save