Simplifies QueryResults write API and adds examples

pull/46/head
Tpt 4 years ago
parent a3dce12d94
commit 1ee4ee1a96
  1. 4
      lib/src/sparql/json_results.rs
  2. 53
      lib/src/sparql/model.rs
  3. 4
      lib/src/sparql/xml_results.rs
  4. 9
      server/src/main.rs
  5. 9
      wikibase/src/main.rs

@ -6,7 +6,7 @@ use crate::Error;
use crate::Result; use crate::Result;
use std::io::Write; use std::io::Write;
pub fn write_json_results<W: Write>(results: QueryResult, mut sink: W) -> Result<W> { pub fn write_json_results(results: QueryResult, mut sink: &mut impl Write) -> Result<()> {
match results { match results {
QueryResult::Boolean(value) => { QueryResult::Boolean(value) => {
sink.write_all(b"{\"head\":{},\"boolean\":")?; sink.write_all(b"{\"head\":{},\"boolean\":")?;
@ -78,7 +78,7 @@ pub fn write_json_results<W: Write>(results: QueryResult, mut sink: W) -> Result
)); ));
} }
} }
Ok(sink) Ok(())
} }
fn write_escaped_json_string(s: &str, sink: &mut impl Write) -> Result<()> { fn write_escaped_json_string(s: &str, sink: &mut impl Write) -> Result<()> {

@ -32,38 +32,77 @@ impl QueryResult {
} }
} }
pub fn write<W: Write>(self, writer: W, syntax: QueryResultSyntax) -> Result<W> { /// Writes the query results (solutions or boolean)
///
/// This method fails if it is called on the `Graph` results
///
/// ```
/// use oxigraph::model::*;
/// use oxigraph::{MemoryStore, Result};
/// use oxigraph::sparql::{QueryOptions, QueryResult, QueryResultSyntax};
///
/// let store = MemoryStore::new();
/// let ex = NamedNode::new("http://example.com")?;
/// store.insert(Quad::new(ex.clone(), ex.clone(), ex.clone(), None));
///
/// let mut results = Vec::new();
/// store.query("SELECT ?s WHERE { ?s ?p ?o }", QueryOptions::default())?.write(&mut results, QueryResultSyntax::Json)?;
/// assert_eq!(results, "{\"head\":{\"vars\":[\"s\"]},\"results\":{\"bindings\":[{\"s\":{\"type\":\"uri\",\"value\":\"http://example.com\"}}]}}".as_bytes());
/// # Result::Ok(())
/// ```
pub fn write(self, writer: &mut impl Write, syntax: QueryResultSyntax) -> Result<()> {
match syntax { match syntax {
QueryResultSyntax::Xml => write_xml_results(self, writer), QueryResultSyntax::Xml => write_xml_results(self, writer),
QueryResultSyntax::Json => write_json_results(self, writer), QueryResultSyntax::Json => write_json_results(self, writer),
} }
} }
pub fn write_graph<W: Write>(self, write: W, syntax: GraphSyntax) -> Result<W> { /// Writes the graph query results
///
/// This method fails if it is called on the `Solution` or `Boolean` results
///
/// ```
/// use oxigraph::model::*;
/// use oxigraph::{MemoryStore, Result, GraphSyntax};
/// use oxigraph::sparql::{QueryOptions, QueryResult, QueryResultSyntax};
/// use std::io::Cursor;
///
/// let graph = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
///
/// let store = MemoryStore::new();
/// store.load_graph(Cursor::new(graph), GraphSyntax::NTriples, &GraphName::DefaultGraph, None);
///
/// let mut results = Vec::new();
/// store.query("CONSTRUCT WHERE { ?s ?p ?o }", QueryOptions::default())?.write_graph(&mut results, GraphSyntax::NTriples)?;
/// assert_eq!(results, graph);
/// # Result::Ok(())
/// ```
pub fn write_graph(self, write: &mut impl Write, syntax: GraphSyntax) -> Result<()> {
if let QueryResult::Graph(triples) = self { if let QueryResult::Graph(triples) = self {
Ok(match syntax { match syntax {
GraphSyntax::NTriples => { GraphSyntax::NTriples => {
let mut formatter = NTriplesFormatter::new(write); let mut formatter = NTriplesFormatter::new(write);
for triple in triples { for triple in triples {
formatter.format(&(&triple?).into())?; formatter.format(&(&triple?).into())?;
} }
formatter.finish() formatter.finish();
} }
GraphSyntax::Turtle => { GraphSyntax::Turtle => {
let mut formatter = TurtleFormatter::new(write); let mut formatter = TurtleFormatter::new(write);
for triple in triples { for triple in triples {
formatter.format(&(&triple?).into())?; formatter.format(&(&triple?).into())?;
} }
formatter.finish()? formatter.finish()?;
} }
GraphSyntax::RdfXml => { GraphSyntax::RdfXml => {
let mut formatter = RdfXmlFormatter::new(write)?; let mut formatter = RdfXmlFormatter::new(write)?;
for triple in triples { for triple in triples {
formatter.format(&(&triple?).into())?; formatter.format(&(&triple?).into())?;
} }
formatter.finish()? formatter.finish()?;
} }
}) }
Ok(())
} else { } else {
Err(Error::msg( Err(Error::msg(
"Bindings or booleans could not be formatted as an RDF graph", "Bindings or booleans could not be formatted as an RDF graph",

@ -17,7 +17,7 @@ use std::io::Write;
use std::iter::empty; use std::iter::empty;
use std::rc::Rc; use std::rc::Rc;
pub fn write_xml_results<W: Write>(results: QueryResult, sink: W) -> Result<W> { pub fn write_xml_results(results: QueryResult, sink: &mut impl Write) -> Result<()> {
let mut writer = Writer::new(sink); let mut writer = Writer::new(sink);
match results { match results {
QueryResult::Boolean(value) => { QueryResult::Boolean(value) => {
@ -100,7 +100,7 @@ pub fn write_xml_results<W: Write>(results: QueryResult, sink: W) -> Result<W> {
)); ));
} }
} }
Ok(writer.into_inner()) Ok(())
} }
pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult> { pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult> {

@ -179,8 +179,9 @@ async fn evaluate_sparql_query(
GraphSyntax::RdfXml.media_type(), GraphSyntax::RdfXml.media_type(),
], ],
)?; )?;
let mut body = Vec::default();
let mut response = Response::from(results.write_graph(Vec::default(), format)?); results.write_graph(&mut body, format)?;
let mut response = Response::from(body);
response.insert_header(headers::CONTENT_TYPE, format.media_type()); response.insert_header(headers::CONTENT_TYPE, format.media_type());
Ok(response) Ok(response)
} else { } else {
@ -191,7 +192,9 @@ async fn evaluate_sparql_query(
QueryResultSyntax::Json.media_type(), QueryResultSyntax::Json.media_type(),
], ],
)?; )?;
let mut response = Response::from(results.write(Vec::default(), format)?); let mut body = Vec::default();
results.write(&mut body, format)?;
let mut response = Response::from(body);
response.insert_header(headers::CONTENT_TYPE, format.media_type()); response.insert_header(headers::CONTENT_TYPE, format.media_type());
Ok(response) Ok(response)
} }

@ -189,8 +189,9 @@ async fn evaluate_sparql_query(
GraphSyntax::RdfXml.media_type(), GraphSyntax::RdfXml.media_type(),
], ],
)?; )?;
let mut body = Vec::default();
let mut response = Response::from(results.write_graph(Vec::default(), format)?); results.write_graph(&mut body, format)?;
let mut response = Response::from(body);
response.insert_header(headers::CONTENT_TYPE, format.media_type()); response.insert_header(headers::CONTENT_TYPE, format.media_type());
Ok(response) Ok(response)
} else { } else {
@ -201,7 +202,9 @@ async fn evaluate_sparql_query(
QueryResultSyntax::Json.media_type(), QueryResultSyntax::Json.media_type(),
], ],
)?; )?;
let mut response = Response::from(results.write(Vec::default(), format)?); let mut body = Vec::default();
results.write(&mut body, format)?;
let mut response = Response::from(body);
response.insert_header(headers::CONTENT_TYPE, format.media_type()); response.insert_header(headers::CONTENT_TYPE, format.media_type());
Ok(response) Ok(response)
} }

Loading…
Cancel
Save