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

@ -151,7 +151,7 @@ fn build_and_check_containment_from_hashes<'a>(
let mut new_b_nodes = b_bnodes_by_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() {
return false;
}

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

@ -1,151 +1,13 @@
//! [SPARQL 1.1 Query Algebra](https://www.w3.org/TR/sparql11-query/#sparqlQuery) AST
use crate::model::*;
use crate::Result;
use failure::format_err;
use crate::sparql::model::*;
use lazy_static::lazy_static;
use rio_api::model as rio;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::fmt;
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)]
pub struct StaticBindings {
@ -170,13 +32,6 @@ impl StaticBindings {
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 {
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)]
pub struct TriplePattern {
pub subject: TermOrVariable,
@ -1364,7 +1188,7 @@ lazy_static! {
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Query {
pub enum QueryVariants {
Select {
dataset: DatasetSpec,
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 {
match self {
Query::Select { dataset, algebra } => write!(
QueryVariants::Select { dataset, algebra } => write!(
f,
"{}",
SparqlGraphRootPattern {
@ -1395,7 +1219,7 @@ impl fmt::Display for Query {
dataset: &dataset
}
),
Query::Construct {
QueryVariants::Construct {
construct,
dataset,
algebra,
@ -1413,7 +1237,7 @@ impl fmt::Display for Query {
dataset: &EMPTY_DATASET
}
),
Query::Describe { dataset, algebra } => write!(
QueryVariants::Describe { dataset, algebra } => write!(
f,
"DESCRIBE * {} WHERE {{ {} }}",
dataset,
@ -1422,7 +1246,7 @@ impl fmt::Display for Query {
dataset: &EMPTY_DATASET
}
),
Query::Ask { dataset, algebra } => write!(
QueryVariants::Ask { dataset, algebra } => write!(
f,
"ASK {} WHERE {{ {} }}",
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::Triple;
use crate::sparql::algebra::*;
use crate::sparql::model::*;
use crate::sparql::plan::*;
use crate::store::numeric_encoder::*;
use crate::store::StoreConnection;

@ -1,8 +1,13 @@
//! [SPARQL](https://www.w3.org/TR/sparql11-overview/) implementation.
use crate::sparql::algebra::Query;
use crate::sparql::algebra::QueryResult;
use crate::sparql::algebra::Variable;
mod algebra;
mod eval;
mod model;
mod parser;
mod plan;
mod xml_results;
use crate::sparql::algebra::QueryVariants;
use crate::sparql::eval::SimpleEvaluator;
use crate::sparql::parser::read_sparql_query;
use crate::sparql::plan::PlanBuilder;
@ -10,15 +15,15 @@ use crate::sparql::plan::PlanNode;
use crate::sparql::plan::TripleTemplate;
use crate::store::StoreConnection;
use crate::Result;
use std::fmt;
use std::io::Read;
pub mod algebra;
mod eval;
pub mod parser;
mod plan;
pub mod xml_results;
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 1.1](https://www.w3.org/TR/sparql11-query/) query
/// 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<'_>>;
@ -51,7 +56,7 @@ enum SimplePreparedQueryOptions<S: StoreConnection> {
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 {
QueryVariants::Select {
algebra,
dataset: _,
} => {
@ -62,7 +67,7 @@ impl<S: StoreConnection> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(connection),
}
}
Query::Ask {
QueryVariants::Ask {
algebra,
dataset: _,
} => {
@ -72,7 +77,7 @@ impl<S: StoreConnection> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(connection),
}
}
Query::Construct {
QueryVariants::Construct {
construct,
algebra,
dataset: _,
@ -88,7 +93,7 @@ impl<S: StoreConnection> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(connection),
}
}
Query::Describe {
QueryVariants::Describe {
algebra,
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::cognitive_complexity,
clippy::many_single_char_names,
clippy::type_complexity
clippy::type_complexity,
ellipsis_inclusive_range_patterns
)]
use crate::model::*;
use crate::sparql::algebra::*;
use crate::sparql::model::*;
use lazy_static::lazy_static;
use std::borrow::Cow;
use std::char;
@ -532,7 +534,7 @@ mod grammar {
pub fn read_sparql_query<'a, R: Read + 'a>(
source: R,
base_uri: Option<&'a str>,
) -> super::super::super::Result<Query> {
) -> super::super::super::Result<QueryVariants> {
let mut state = ParserState {
base_uri: if let Some(base_uri) = base_uri {
Some(Url::parse(base_uri)?)

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

@ -8,10 +8,10 @@ use std::str::FromStr;
//[1]
pub QueryUnit -> Query = Query
pub QueryUnit -> QueryVariants = Query
//[2]
Query -> Query = _ Prologue _ q:(SelectQuery / ConstructQuery / DescribeQuery / AskQuery) _ { //TODO: ValuesClause
Query -> QueryVariants = _ Prologue _ q:(SelectQuery / ConstructQuery / DescribeQuery / AskQuery) _ { //TODO: ValuesClause
q
}
@ -35,8 +35,8 @@ PrefixDecl -> () = "PREFIX"i _ ns:PNAME_NS _ i:IRIREF {
}
//[7]
SelectQuery -> Query = s:SelectClause _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { //TODO: Modifier
Query::Select {
SelectQuery -> QueryVariants = s:SelectClause _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause { //TODO: Modifier
QueryVariants::Select {
dataset: d,
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) }
//[10]
ConstructQuery -> Query =
ConstructQuery -> QueryVariants =
"CONSTRUCT"i _ c:ConstructTemplate _ d:DatasetClauses _ w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Construct {
QueryVariants::Construct {
construct: c,
dataset: d,
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 {
Query::Construct {
QueryVariants::Construct {
construct: c.clone(),
dataset: d,
algebra: build_select(
@ -89,15 +89,15 @@ ConstructQuery -> Query =
ConstructQuery_optional_triple_template -> Vec<TriplePattern> = TriplesTemplate / { Vec::default() }
//[11]
DescribeQuery -> Query =
DescribeQuery -> QueryVariants =
"DESCRIBE"i _ '*' _ d:DatasetClauses w:WhereClause? _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Describe {
QueryVariants::Describe {
dataset: d,
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 {
Query::Describe {
QueryVariants::Describe {
dataset: d,
algebra: build_select(Selection {
option: SelectionOption::Default,
@ -111,8 +111,8 @@ DescribeQuery -> Query =
DescribeQuery_item -> NamedNodeOrVariable = i:VarOrIri _ { i }
//[12]
AskQuery -> Query = "ASK"i _ d:DatasetClauses w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
Query::Ask {
AskQuery -> QueryVariants = "ASK"i _ d:DatasetClauses w:WhereClause _ g:GroupClause? _ h:HavingClause? _ o:OrderClause? _ l:LimitOffsetClauses? _ v:ValuesClause {
QueryVariants::Ask {
dataset: d,
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/)
use crate::model::*;
use crate::sparql::algebra::BindingsIterator;
use crate::sparql::algebra::QueryResult;
use crate::sparql::algebra::Variable;
use crate::sparql::model::*;
use crate::Result;
use failure::format_err;
use quick_xml::events::BytesDecl;

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

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

@ -3,14 +3,12 @@ use failure::format_err;
use rudf::model::vocab::rdf;
use rudf::model::vocab::rdfs;
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::{Query, QueryResult, QueryResultSyntax};
use rudf::{GraphSyntax, MemoryRepository, Repository, RepositoryConnection, Result};
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::io::{BufRead, BufReader};
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";
let test_blacklist = vec![
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-function-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;
}
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),
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!(
false,
"Failure to deserialize \"{}\" of {} with error: {}",
@ -50,7 +47,7 @@ fn sparql_w3c_syntax_testsuite() {
}
} else if test.kind == "NegativeSyntaxTest" || test.kind == "NegativeSyntaxTest11" {
//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);
}
} else {
@ -163,7 +160,7 @@ fn sparql_w3c_query_evaluation_testsuite() {
test,
expected_graph,
actual_graph,
load_sparql_query(&test.query).unwrap(),
read_file_to_string(&test.query).unwrap(),
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))
}
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> {
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 {
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> {
if url.starts_with("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/") {
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 {
use lazy_static::lazy_static;
use rudf::model::NamedNode;

@ -27,9 +27,8 @@ use hyper::StatusCode;
use lazy_static::lazy_static;
use mime;
use mime::Mime;
use rudf::sparql::algebra::QueryResult;
use rudf::sparql::xml_results::write_xml_results;
use rudf::sparql::PreparedQuery;
use rudf::sparql::QueryResult;
use rudf::sparql::{PreparedQuery, QueryResultSyntax};
use rudf::RepositoryConnection;
use rudf::{GraphSyntax, Repository};
use rudf::{MemoryRepository, RocksDbRepository};
@ -282,7 +281,9 @@ where
&state,
StatusCode::OK,
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),
},

Loading…
Cancel
Save