ran clippy and fmt

pull/13/head
Dustin Whitney 6 years ago
parent 75b6c22d37
commit 88773fc942
  1. 15
      lib/src/sparql/eval.rs
  2. 61
      lib/src/sparql/mod.rs
  3. 10
      lib/src/sparql/plan.rs
  4. 5
      lib/src/sparql/plan_builder.rs
  5. 104
      lib/tests/custom_functions_test_cases.rs
  6. 6
      lib/tests/service_test_cases.rs
  7. 1
      lib/tests/support/mod.rs

@ -1416,13 +1416,14 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
}), }),
PlanExpression::CustomFunction { name, parameters } => { PlanExpression::CustomFunction { name, parameters } => {
let parameters = parameters let parameters = parameters
.iter() .iter()
.map(|p| { .map(|p| {
self.eval_expression(p, tuple) self.eval_expression(p, tuple)
.and_then(|encoded| self.dataset.decode_term(encoded).ok()) .and_then(|encoded| self.dataset.decode_term(encoded).ok())
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
self.custom_functions_handler.handle(name, &parameters) self.custom_functions_handler
.handle(name, &parameters)
.and_then(|term| self.dataset.encoder().encode_term(&term).ok()) .and_then(|term| self.dataset.encoder().encode_term(&term).ok())
} }
} }

@ -9,7 +9,7 @@ mod plan;
mod plan_builder; mod plan_builder;
mod xml_results; mod xml_results;
use crate::model::{NamedNode,Term}; use crate::model::{NamedNode, Term};
use crate::sparql::algebra::QueryVariants; 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;
@ -70,7 +70,12 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
SimplePreparedQueryAction::Select { SimplePreparedQueryAction::Select {
plan, plan,
variables, variables,
evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler, options.custom_functions_handler), evaluator: SimpleEvaluator::new(
dataset,
base_iri,
options.service_handler,
options.custom_functions_handler,
),
} }
} }
QueryVariants::Ask { QueryVariants::Ask {
@ -81,7 +86,12 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
let (plan, _) = PlanBuilder::build(dataset.encoder(), &algebra)?; let (plan, _) = PlanBuilder::build(dataset.encoder(), &algebra)?;
SimplePreparedQueryAction::Ask { SimplePreparedQueryAction::Ask {
plan, plan,
evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler, options.custom_functions_handler), evaluator: SimpleEvaluator::new(
dataset,
base_iri,
options.service_handler,
options.custom_functions_handler,
),
} }
} }
QueryVariants::Construct { QueryVariants::Construct {
@ -98,7 +108,12 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
&construct, &construct,
variables, variables,
)?, )?,
evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler, options.custom_functions_handler), evaluator: SimpleEvaluator::new(
dataset,
base_iri,
options.service_handler,
options.custom_functions_handler,
),
} }
} }
QueryVariants::Describe { QueryVariants::Describe {
@ -109,7 +124,12 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
let (plan, _) = PlanBuilder::build(dataset.encoder(), &algebra)?; let (plan, _) = PlanBuilder::build(dataset.encoder(), &algebra)?;
SimplePreparedQueryAction::Describe { SimplePreparedQueryAction::Describe {
plan, plan,
evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler, options.custom_functions_handler), evaluator: SimpleEvaluator::new(
dataset,
base_iri,
options.service_handler,
options.custom_functions_handler,
),
} }
} }
})) }))
@ -131,7 +151,12 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
Ok(Self(SimplePreparedQueryAction::Select { Ok(Self(SimplePreparedQueryAction::Select {
plan, plan,
variables, variables,
evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler, options.custom_functions_handler), evaluator: SimpleEvaluator::new(
dataset,
base_iri,
options.service_handler,
options.custom_functions_handler,
),
})) }))
} }
} }
@ -185,36 +210,35 @@ impl ServiceHandler for EmptyServiceHandler {
} }
} }
/// Handler for custom functions. /// Handler for custom functions.
/// ///
/// For example, the following query uses a custom function to reverse a string: /// For example, the following query uses a custom function to reverse a string:
/// ///
///```sparql ///```sparql
/// PREFIX ex: <http://example.com#> /// PREFIX ex: <http://example.com#>
/// PREFIX foaf: <http://xmlns.com/foaf/0.1/> /// PREFIX foaf: <http://xmlns.com/foaf/0.1/>
/// SELECT ?name ?reverse /// SELECT ?name ?reverse
/// WHERE /// WHERE
/// { /// {
/// ?s foaf:name ?name . /// ?s foaf:name ?name .
/// BIND(ex:REVERSE(?name) as ?reverse) /// BIND(ex:REVERSE(?name) as ?reverse)
/// } /// }
/// ``` /// ```
pub trait CustomFunctionsHandler { pub trait CustomFunctionsHandler {
/// Handles all custom functions for a given query /// Handles all custom functions for a given query
/// ///
/// For the example above node would have the value http://example.com#REVERSE /// For the example above node would have the value http://example.com#REVERSE
/// and would recieve one parameter with the value mapped to ?name /// and would recieve one parameter with the value mapped to ?name
/// ///
/// Returns `None` if there is an error or the given NamedNode isn't recognized /// Returns `None` if there is an error or the given NamedNode isn't recognized
fn handle(&self, node: &NamedNode, parameters: &Vec<Option<Term>>) -> Option<Term>; fn handle(&self, node: &NamedNode, parameters: &[Option<Term>]) -> Option<Term>;
} }
#[derive(Default)] #[derive(Default)]
struct EmptyCustomFunctionsHandler {} struct EmptyCustomFunctionsHandler {}
impl CustomFunctionsHandler for EmptyCustomFunctionsHandler { impl CustomFunctionsHandler for EmptyCustomFunctionsHandler {
fn handle(&self, _node: &NamedNode, _parameters: &Vec<Option<Term>>) -> Option<Term> { fn handle(&self, _node: &NamedNode, _parameters: &[Option<Term>]) -> Option<Term> {
None None
} }
} }
@ -258,12 +282,13 @@ impl<'a> QueryOptions<'a> {
} }
/// Set a CustomFunctionHandler to add your own functions /// Set a CustomFunctionHandler to add your own functions
pub fn with_custom_functions_handler(mut self, custom_functions_handler: Box<dyn CustomFunctionsHandler>) -> Self { pub fn with_custom_functions_handler(
mut self,
custom_functions_handler: Box<dyn CustomFunctionsHandler>,
) -> Self {
self.custom_functions_handler = custom_functions_handler; self.custom_functions_handler = custom_functions_handler;
self self
} }
} }
/// A parsed [SPARQL query](https://www.w3.org/TR/sparql11-query/) /// A parsed [SPARQL query](https://www.w3.org/TR/sparql11-query/)

@ -1,7 +1,7 @@
use crate::model::NamedNode; use crate::model::NamedNode;
use crate::sparql::GraphPattern;
use crate::sparql::model::Variable;
use crate::sparql::eval::StringOrStoreString; use crate::sparql::eval::StringOrStoreString;
use crate::sparql::model::Variable;
use crate::sparql::GraphPattern;
use crate::store::numeric_encoder::{ use crate::store::numeric_encoder::{
EncodedQuad, EncodedTerm, Encoder, MemoryStrStore, StrContainer, StrLookup, EncodedQuad, EncodedTerm, Encoder, MemoryStrStore, StrContainer, StrLookup,
ENCODED_DEFAULT_GRAPH, ENCODED_DEFAULT_GRAPH,
@ -307,9 +307,9 @@ pub enum PlanExpression {
TimeCast(Box<PlanExpression>), TimeCast(Box<PlanExpression>),
DateTimeCast(Box<PlanExpression>), DateTimeCast(Box<PlanExpression>),
StringCast(Box<PlanExpression>), StringCast(Box<PlanExpression>),
CustomFunction { CustomFunction {
name: NamedNode, name: NamedNode,
parameters: Vec<PlanExpression> parameters: Vec<PlanExpression>,
}, },
} }
@ -420,7 +420,7 @@ impl PlanExpression {
e.add_variables(set); e.add_variables(set);
} }
} }
PlanExpression::CustomFunction{ parameters, .. } => { PlanExpression::CustomFunction { parameters, .. } => {
for p in parameters { for p in parameters {
p.add_variables(set); p.add_variables(set);
} }

@ -646,7 +646,10 @@ impl<E: Encoder> PlanBuilder<E> {
)? )?
} else { } else {
let parameters = self.expression_list(parameters, variables, graph_name)?; let parameters = self.expression_list(parameters, variables, graph_name)?;
PlanExpression::CustomFunction { name: name.clone(), parameters } PlanExpression::CustomFunction {
name: name.clone(),
parameters,
}
} }
} }
}, },

@ -6,29 +6,28 @@ use support::*;
#[test] #[test]
fn simple_custom_function_test() { fn simple_custom_function_test() {
struct TestHandler;
struct TestHandler; impl CustomFunctionsHandler for TestHandler {
fn handle(&self, node: &NamedNode, parameters: &[Option<Term>]) -> Option<Term> {
impl CustomFunctionsHandler for TestHandler { let reverse = NamedNode::parse("http://example.com#REVERSE").ok()?;
fn handle(&self, node: &NamedNode, parameters: &Vec<Option<Term>>) -> Option<Term> { if *node == reverse {
let reverse = NamedNode::parse("http://example.com#REVERSE").ok()?; let param = &parameters[0];
if *node == reverse { if let Some(Term::Literal(literal)) = param {
let param = &parameters[0]; let value = literal.value();
if let Some(Term::Literal(literal)) = param { let reversed = value.chars().rev().collect::<String>();
let value = literal.value(); let literal = Literal::new_simple_literal(reversed);
let reversed = value.chars().rev().collect::<String>(); Some(Term::Literal(literal))
let literal = Literal::new_simple_literal(reversed); } else {
Some(Term::Literal(literal)) None
} else { }
None } else {
None
}
} }
} else {
None
}
} }
}
let query = r#" let query = r#"
PREFIX ex: <http://example.com#> PREFIX ex: <http://example.com#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?reverse SELECT ?name ?reverse
@ -38,28 +37,36 @@ fn simple_custom_function_test() {
BIND(ex:REVERSE(?name) as ?reverse) BIND(ex:REVERSE(?name) as ?reverse)
} }
ORDER BY ?name ORDER BY ?name
"#.to_string(); "#
.to_string();
let options = QueryOptions::default().with_custom_functions_handler(Box::new(TestHandler)); let options = QueryOptions::default().with_custom_functions_handler(Box::new(TestHandler));
let triples = br#" let triples = br#"
<http://example.com/bob> <http://xmlns.com/foaf/0.1/name> "Bob" . <http://example.com/bob> <http://xmlns.com/foaf/0.1/name> "Bob" .
<http://example.com/alice> <http://xmlns.com/foaf/0.1/name> "Alice" . <http://example.com/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
"#.as_ref(); "#
let results = do_query(triples, query, options).unwrap(); .as_ref();
let collected = results.into_values_iter().map(move |b| b.unwrap()).collect::<Vec<_>>(); let results = do_query(triples, query, options).unwrap();
let solution = vec![ let collected = results
vec![ Some(literal(String::from("Alice"))), Some(literal(String::from("ecilA"))) ], .into_values_iter()
vec![ Some(literal(String::from("Bob"))), Some(literal(String::from("boB"))) ], .map(move |b| b.unwrap())
]; .collect::<Vec<_>>();
assert_eq!(collected, solution); let solution = vec![
vec![
Some(literal(String::from("Alice"))),
Some(literal(String::from("ecilA"))),
],
vec![
Some(literal(String::from("Bob"))),
Some(literal(String::from("boB"))),
],
];
assert_eq!(collected, solution);
} }
#[test] #[test]
fn simple_default_custom_function_test() { fn simple_default_custom_function_test() {
let query = r#"
let query = r#"
PREFIX ex: <http://example.com#> PREFIX ex: <http://example.com#>
SELECT ?name ?reverse SELECT ?name ?reverse
WHERE WHERE
@ -68,20 +75,23 @@ fn simple_default_custom_function_test() {
BIND(ex:REVERSE(?name) as ?reverse) BIND(ex:REVERSE(?name) as ?reverse)
} }
ORDER BY ?name ORDER BY ?name
"#.to_string(); "#
.to_string();
let options = QueryOptions::default(); let options = QueryOptions::default();
let triples = br#" let triples = br#"
<http://example.com/bob> <http://xmlns.com/foaf/0.1/name> "Bob" . <http://example.com/bob> <http://xmlns.com/foaf/0.1/name> "Bob" .
<http://example.com/alice> <http://xmlns.com/foaf/0.1/name> "Alice" . <http://example.com/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
"#.as_ref(); "#
let results = do_query(triples, query, options).unwrap(); .as_ref();
let collected = results.into_values_iter().map(move |b| b.unwrap()).collect::<Vec<_>>(); let results = do_query(triples, query, options).unwrap();
let solution = vec![ let collected = results
vec![ Some(literal(String::from("Alice"))), None ], .into_values_iter()
vec![ Some(literal(String::from("Bob"))), None ], .map(move |b| b.unwrap())
]; .collect::<Vec<_>>();
assert_eq!(collected, solution); let solution = vec![
vec![Some(literal(String::from("Alice"))), None],
vec![Some(literal(String::from("Bob"))), None],
];
assert_eq!(collected, solution);
} }

@ -1,8 +1,6 @@
use failure::format_err; use failure::format_err;
use rudf::model::*; use rudf::model::*;
use rudf::sparql::{ use rudf::sparql::{BindingsIterator, GraphPattern, QueryOptions, ServiceHandler};
BindingsIterator, GraphPattern, QueryOptions, ServiceHandler,
};
use rudf::Result; use rudf::Result;
mod support; mod support;
@ -216,4 +214,4 @@ fn non_silent_service_test() {
"This should have been an error since the service fails" "This should have been an error since the service fails"
), ),
} }
} }

@ -6,7 +6,6 @@ use rudf::sparql::{BindingsIterator, GraphPattern, PreparedQuery, QueryOptions,
use rudf::{GraphSyntax, MemoryRepository, Repository, RepositoryConnection, Result}; use rudf::{GraphSyntax, MemoryRepository, Repository, RepositoryConnection, Result};
use std::io::BufRead; use std::io::BufRead;
pub(crate) fn ex(id: String) -> Term { pub(crate) fn ex(id: String) -> Term {
Term::NamedNode(NamedNode::parse(format!("http://example.com/{}", &id)).unwrap()) Term::NamedNode(NamedNode::parse(format!("http://example.com/{}", &id)).unwrap())
} }

Loading…
Cancel
Save