Makes RepositoryConnection.prepare_query take &str instead of Read

Simpler and faster API (SPARQL parser was reading into a String anyway)
pull/10/head
Tpt 5 years ago
parent 9339e1063e
commit 45d78d490d
  1. 2
      lib/src/lib.rs
  2. 8
      lib/src/repository.rs
  3. 7
      lib/src/sparql/mod.rs
  4. 16
      lib/src/sparql/parser.rs
  5. 2
      lib/src/store/memory.rs
  6. 4
      lib/src/store/mod.rs
  7. 2
      lib/src/store/rocksdb.rs
  8. 13
      lib/tests/sparql_test_cases.rs
  9. 8
      server/src/main.rs

@ -27,7 +27,7 @@
//! assert_eq!(vec![quad], results.unwrap());
//!
//! // SPARQL query
//! let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
//! let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }").unwrap();
//! let results = prepared_query.exec().unwrap();
//! if let QueryResult::Bindings(results) = results {
//! assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));

@ -1,7 +1,7 @@
use crate::model::*;
use crate::sparql::PreparedQuery;
use crate::{DatasetSyntax, GraphSyntax, Result};
use std::io::{BufRead, Read};
use std::io::BufRead;
/// A `Repository` stores a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// and allows to query and update it using SPARQL.
@ -30,7 +30,7 @@ use std::io::{BufRead, Read};
/// assert_eq!(vec![quad], results.unwrap());
///
/// // SPARQL query
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }").unwrap();
/// let results = prepared_query.exec().unwrap();
/// if let QueryResult::Bindings(results) = results {
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));
@ -75,13 +75,13 @@ pub trait RepositoryConnection: Clone {
/// connection.insert(&Quad::new(ex.clone(), ex.clone(), ex.clone(), None));
///
/// // SPARQL query
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }").unwrap();
/// let results = prepared_query.exec().unwrap();
/// if let QueryResult::Bindings(results) = results {
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));
/// }
/// ```
fn prepare_query(&self, query: impl Read) -> Result<Self::PreparedQuery>;
fn prepare_query(&self, query: &str) -> Result<Self::PreparedQuery>;
/// Retrieves quads with a filter on each quad component
///

@ -17,7 +17,6 @@ use crate::sparql::plan_builder::PlanBuilder;
use crate::store::StoreConnection;
use crate::Result;
use std::fmt;
use std::io::Read;
pub use crate::sparql::model::BindingsIterator;
pub use crate::sparql::model::QueryResult;
@ -55,7 +54,7 @@ enum SimplePreparedQueryOptions<S: StoreConnection> {
}
impl<S: StoreConnection> SimplePreparedQuery<S> {
pub(crate) fn new(connection: S, query: impl Read) -> Result<Self> {
pub(crate) fn new(connection: S, query: &str) -> Result<Self> {
Ok(Self(match read_sparql_query(query, None)? {
QueryVariants::Select {
algebra,
@ -143,7 +142,7 @@ impl fmt::Display for Query {
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)?))
pub fn parse(query: &str, base_iri: Option<&str>) -> Result<Self> {
Ok(Query(read_sparql_query(query, base_iri)?))
}
}

@ -19,8 +19,6 @@ mod grammar {
use std::char;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::io::BufReader;
use std::io::Read;
use std::str::Chars;
struct FocusedTriplePattern<F> {
@ -533,9 +531,9 @@ mod grammar {
include!(concat!(env!("OUT_DIR"), "/sparql_grammar.rs"));
pub fn read_sparql_query<'a, R: Read + 'a>(
source: R,
base_iri: Option<&'a str>,
pub fn read_sparql_query(
query: &str,
base_iri: Option<&str>,
) -> super::super::super::Result<QueryVariants> {
let mut state = ParserState {
base_iri: if let Some(base_iri) = base_iri {
@ -548,13 +546,7 @@ mod grammar {
aggregations: BTreeMap::default(),
};
let mut string_buffer = String::default();
BufReader::new(source).read_to_string(&mut string_buffer)?;
Ok(QueryUnit(
&unescape_unicode_codepoints(&string_buffer),
&mut state,
)?)
Ok(QueryUnit(&unescape_unicode_codepoints(query), &mut state)?)
}
}

@ -32,7 +32,7 @@ use std::sync::RwLockWriteGuard;
/// assert_eq!(vec![quad], results.unwrap());
///
/// // SPARQL query
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }").unwrap();
/// let results = prepared_query.exec().unwrap();
/// if let QueryResult::Bindings(results) = results {
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));

@ -17,7 +17,7 @@ use rio_api::parser::{QuadParser, TripleParser};
use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleParser};
use rio_xml::RdfXmlParser;
use std::collections::HashMap;
use std::io::{BufRead, Read};
use std::io::BufRead;
use std::iter::{once, Iterator};
/// Defines the `Store` traits that is used to have efficient binary storage
@ -59,7 +59,7 @@ impl<S: StoreConnection> From<S> for StoreRepositoryConnection<S> {
impl<S: StoreConnection> RepositoryConnection for StoreRepositoryConnection<S> {
type PreparedQuery = SimplePreparedQuery<S>;
fn prepare_query(&self, query: impl Read) -> Result<SimplePreparedQuery<S>> {
fn prepare_query(&self, query: &str) -> Result<SimplePreparedQuery<S>> {
SimplePreparedQuery::new(self.inner.clone(), query) //TODO: avoid clone
}

@ -42,7 +42,7 @@ use std::sync::Mutex;
/// assert_eq!(vec![quad], results.unwrap());
///
/// // SPARQL query
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }").unwrap();
/// let results = prepared_query.exec().unwrap();
/// if let QueryResult::Bindings(results) = results {
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));

@ -31,10 +31,10 @@ fn sparql_w3c_syntax_testsuite() -> Result<()> {
continue;
}
if test.kind == "PositiveSyntaxTest" || test.kind == "PositiveSyntaxTest11" {
match load_query(&test.query) {
match Query::parse(&read_file_to_string(&test.query)?, Some(&test.query)) {
Err(error) => assert!(false, "Failure on {} with error: {}", test, error),
Ok(query) => {
if let Err(error) = Query::read(query.to_string().as_bytes(), None) {
if let Err(error) = Query::parse(&query.to_string(), None) {
assert!(
false,
"Failure to deserialize \"{}\" of {} with error: {}",
@ -47,7 +47,8 @@ fn sparql_w3c_syntax_testsuite() -> Result<()> {
}
} else if test.kind == "NegativeSyntaxTest" || test.kind == "NegativeSyntaxTest11" {
//TODO
if let Ok(result) = load_query(&test.query) {
if let Ok(result) = Query::parse(&read_file_to_string(&test.query)?, Some(&test.query))
{
eprintln!("Failure on {}. The output tree is: {}", test, result);
}
} else {
@ -128,7 +129,7 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
}
match repository
.connection()?
.prepare_query(read_file(&test.query)?)
.prepare_query(&read_file_to_string(&test.query)?)
{
Err(error) => assert!(
false,
@ -214,10 +215,6 @@ fn load_sparql_query_result_graph(url: &str) -> Result<SimpleGraph> {
}
}
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(

@ -96,7 +96,9 @@ fn handle_request<R: RepositoryConnection>(
if let Some(mut body) = request.data() {
if let Some(content_type) = request.header("Content-Type") {
if content_type.starts_with("application/sparql-query") {
evaluate_sparql_query(connection, body)
let mut buffer = String::default();
body.read_to_string(&mut buffer).unwrap();
evaluate_sparql_query(connection, &buffer)
} else if content_type.starts_with("application/x-www-form-urlencoded") {
let mut buffer = Vec::default();
body.read_to_end(&mut buffer).unwrap();
@ -124,13 +126,13 @@ fn evaluate_urlencoded_sparql_query<R: RepositoryConnection>(
encoded: &[u8],
) -> Response {
if let Some((_, query)) = form_urlencoded::parse(encoded).find(|(k, _)| k == "query") {
evaluate_sparql_query(connection, query.as_bytes())
evaluate_sparql_query(connection, &query)
} else {
Response::text("You should set the 'query' parameter").with_status_code(400)
}
}
fn evaluate_sparql_query<R: RepositoryConnection>(connection: R, query: impl Read) -> Response {
fn evaluate_sparql_query<R: RepositoryConnection>(connection: R, query: &str) -> Response {
//TODO: stream
match connection.prepare_query(query) {
Ok(query) => match query.exec().unwrap() {

Loading…
Cancel
Save