Use io::Error in load_graph and load_dataset errors

It is possible to find the kind of error (parsing, loading...) using the std::io::ErrorKind enumeration
pull/46/head
Tpt 4 years ago
parent 4dd7912300
commit 923beb6300
  1. 20
      lib/src/store/memory.rs
  2. 96
      lib/src/store/mod.rs
  3. 18
      lib/src/store/rocksdb.rs
  4. 22
      lib/src/store/sled.rs
  5. 6
      python/src/memory_store.rs
  6. 29
      python/src/sled_store.rs
  7. 16
      python/src/store_utils.rs

@ -266,13 +266,16 @@ impl MemoryStore {
/// assert_eq!(vec![Quad::new(ex.clone(), ex.clone(), ex.clone(), None)], results);
/// # oxigraph::Result::Ok(())
/// ```
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_graph(
&self,
reader: impl BufRead,
syntax: GraphSyntax,
to_graph_name: &GraphName,
base_iri: Option<&str>,
) -> crate::Result<()> {
) -> Result<(), io::Error> {
let mut store = self;
load_graph(&mut store, reader, syntax, to_graph_name, base_iri)
}
@ -296,12 +299,15 @@ impl MemoryStore {
/// assert_eq!(vec![Quad::new(ex.clone(), ex.clone(), ex.clone(), Some(ex.into()))], results);
/// # oxigraph::Result::Ok(())
/// ```
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_dataset(
&self,
reader: impl BufRead,
syntax: DatasetSyntax,
base_iri: Option<&str>,
) -> crate::Result<()> {
) -> Result<(), io::Error> {
let mut store = self;
load_dataset(&mut store, reader, syntax, base_iri)
}
@ -348,6 +354,9 @@ impl MemoryStore {
/// assert_eq!(file, buffer.as_slice());
/// # oxigraph::Result::Ok(())
/// ```
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn dump_graph(
&self,
writer: &mut impl Write,
@ -378,6 +387,9 @@ impl MemoryStore {
/// assert_eq!(file, buffer.as_slice());
/// # oxigraph::Result::Ok(())
/// ```
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn dump_dataset(
&self,
writer: &mut impl Write,
@ -986,7 +998,7 @@ impl<'a> MemoryTransaction<'a> {
syntax: GraphSyntax,
to_graph_name: &GraphName,
base_iri: Option<&str>,
) -> crate::Result<()> {
) -> Result<(), io::Error> {
load_graph(self, reader, syntax, to_graph_name, base_iri)
}
@ -1014,7 +1026,7 @@ impl<'a> MemoryTransaction<'a> {
reader: impl BufRead,
syntax: DatasetSyntax,
base_iri: Option<&str>,
) -> crate::Result<()> {
) -> Result<(), io::Error> {
load_dataset(self, reader, syntax, base_iri)
}

@ -23,7 +23,7 @@ use rio_api::formatter::{QuadsFormatter, TriplesFormatter};
use rio_api::parser::{QuadsParser, TriplesParser};
use rio_turtle::{
NQuadsFormatter, NQuadsParser, NTriplesFormatter, NTriplesParser, TriGFormatter, TriGParser,
TurtleFormatter, TurtleParser,
TurtleError, TurtleFormatter, TurtleParser,
};
use rio_xml::{RdfXmlError, RdfXmlFormatter, RdfXmlParser};
use std::collections::HashMap;
@ -66,45 +66,45 @@ fn load_graph<S: WritableEncodedStore>(
syntax: GraphSyntax,
to_graph_name: &GraphName,
base_iri: Option<&str>,
) -> Result<(), crate::Error>
where
crate::Error: From<<S as WritableEncodedStore>::Error> + From<<S as StrContainer>::Error>,
{
) -> Result<(), io::Error> {
let base_iri = base_iri.unwrap_or("");
match syntax {
GraphSyntax::NTriples => {
load_from_triple_parser(store, NTriplesParser::new(reader)?, to_graph_name)
load_from_triple_parser(store, NTriplesParser::new(reader), to_graph_name)
}
GraphSyntax::Turtle => {
load_from_triple_parser(store, TurtleParser::new(reader, base_iri)?, to_graph_name)
load_from_triple_parser(store, TurtleParser::new(reader, base_iri), to_graph_name)
}
GraphSyntax::RdfXml => {
load_from_triple_parser(store, RdfXmlParser::new(reader, base_iri)?, to_graph_name)
load_from_triple_parser(store, RdfXmlParser::new(reader, base_iri), to_graph_name)
}
}
}
fn load_from_triple_parser<S: WritableEncodedStore, P: TriplesParser>(
store: &mut S,
mut parser: P,
parser: Result<P, P::Error>,
to_graph_name: &GraphName,
) -> Result<(), crate::Error>
) -> Result<(), io::Error>
where
crate::Error: From<P::Error>
+ From<<S as WritableEncodedStore>::Error>
+ From<<S as StrContainer>::Error>,
IoOrParseError<P::Error>: From<P::Error>,
P::Error: Send + Sync + 'static,
{
let mut parser = parser.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
let mut bnode_map = HashMap::default();
let to_graph_name = store
.encode_graph_name(to_graph_name)
.map_err(|e| e.into())?;
parser.parse_all(&mut move |t| {
let result: Result<(), IoOrParseError<_>> = parser.parse_all(&mut move |t| {
let quad = store
.encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map)
.map_err(crate::Error::from)?;
store.insert_encoded(&quad).map_err(crate::Error::from)?;
.map_err(|e| IoOrParseError::Io(e.into()))?;
store
.insert_encoded(&quad)
.map_err(|e| IoOrParseError::Io(e.into()))?;
Ok(())
})
});
Ok(result?)
}
fn dump_graph(
@ -147,34 +147,34 @@ fn load_dataset<S: WritableEncodedStore>(
reader: impl BufRead,
syntax: DatasetSyntax,
base_iri: Option<&str>,
) -> Result<(), crate::Error>
where
crate::Error: From<<S as WritableEncodedStore>::Error> + From<<S as StrContainer>::Error>,
{
) -> Result<(), io::Error> {
let base_iri = base_iri.unwrap_or("");
match syntax {
DatasetSyntax::NQuads => load_from_quad_parser(store, NQuadsParser::new(reader)?),
DatasetSyntax::TriG => load_from_quad_parser(store, TriGParser::new(reader, base_iri)?),
DatasetSyntax::NQuads => load_from_quad_parser(store, NQuadsParser::new(reader)),
DatasetSyntax::TriG => load_from_quad_parser(store, TriGParser::new(reader, base_iri)),
}
}
fn load_from_quad_parser<S: WritableEncodedStore, P: QuadsParser>(
store: &mut S,
mut parser: P,
) -> Result<(), crate::Error>
parser: Result<P, P::Error>,
) -> Result<(), io::Error>
where
crate::Error: From<P::Error>
+ From<<S as WritableEncodedStore>::Error>
+ From<<S as StrContainer>::Error>,
IoOrParseError<P::Error>: From<P::Error>,
P::Error: Send + Sync + 'static,
{
let mut parser = parser.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
let mut bnode_map = HashMap::default();
parser.parse_all(&mut move |q| {
let result: Result<(), IoOrParseError<_>> = parser.parse_all(&mut move |q| {
let quad = store
.encode_rio_quad(q, &mut bnode_map)
.map_err(crate::Error::from)?;
store.insert_encoded(&quad).map_err(crate::Error::from)?;
.map_err(|e| IoOrParseError::Io(e.into()))?;
store
.insert_encoded(&quad)
.map_err(|e| IoOrParseError::Io(e.into()))?;
Ok(())
})
});
Ok(result?)
}
fn dump_dataset(
@ -200,3 +200,35 @@ fn dump_dataset(
}
Ok(())
}
enum IoOrParseError<E: Sized> {
Io(io::Error),
Parse(E),
}
impl<E: Sized> From<io::Error> for IoOrParseError<E> {
fn from(error: io::Error) -> Self {
Self::Io(error)
}
}
impl From<TurtleError> for IoOrParseError<TurtleError> {
fn from(error: TurtleError) -> Self {
Self::Parse(error)
}
}
impl From<RdfXmlError> for IoOrParseError<RdfXmlError> {
fn from(error: RdfXmlError) -> Self {
Self::Parse(error)
}
}
impl<E: Sized + Error + Send + Sync + 'static> From<IoOrParseError<E>> for io::Error {
fn from(error: IoOrParseError<E>) -> Self {
match error {
IoOrParseError::Io(error) => error,
IoOrParseError::Parse(error) => io::Error::new(io::ErrorKind::InvalidData, error),
}
}
}

@ -184,6 +184,10 @@ impl RocksDbStore {
/// only a part of it may be written. Use a (memory greedy) transaction if you do not want that.
///
/// See `MemoryStore` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
/// Errors related to data loading into the store use the other error kinds.
pub fn load_graph(
&self,
reader: impl BufRead,
@ -202,6 +206,10 @@ impl RocksDbStore {
/// only a part of it may be written. Use a (memory greedy) transaction if you do not want that.
///
/// See `MemoryStore` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
/// Errors related to data loading into the store use the other error kinds.
pub fn load_dataset(
&self,
reader: impl BufRead,
@ -567,13 +575,16 @@ impl RocksDbTransaction<'_> {
/// Do not use for big files.
///
/// See `MemoryTransaction` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_graph(
&mut self,
reader: impl BufRead,
syntax: GraphSyntax,
to_graph_name: &GraphName,
base_iri: Option<&str>,
) -> Result<(), crate::Error> {
) -> Result<(), io::Error> {
load_graph(&mut self.inner, reader, syntax, to_graph_name, base_iri)
}
@ -584,12 +595,15 @@ impl RocksDbTransaction<'_> {
/// Do not use for big files.
///
/// See `MemoryTransaction` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_dataset(
&mut self,
reader: impl BufRead,
syntax: DatasetSyntax,
base_iri: Option<&str>,
) -> Result<(), crate::Error> {
) -> Result<(), io::Error> {
load_dataset(&mut self.inner, reader, syntax, base_iri)
}

@ -169,13 +169,17 @@ impl SledStore {
/// only a part of it may be written. Use a (memory greedy) transaction if you do not want that.
///
/// See `MemoryStore` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
/// Errors related to data loading into the store use the other error kinds.
pub fn load_graph(
&self,
reader: impl BufRead,
syntax: GraphSyntax,
to_graph_name: &GraphName,
base_iri: Option<&str>,
) -> Result<(), crate::Error> {
) -> Result<(), io::Error> {
load_graph(
&mut DirectWriter::new(self),
reader,
@ -191,12 +195,16 @@ impl SledStore {
/// only a part of it may be written. Use a (memory greedy) transaction if you do not want that.
///
/// See `MemoryStore` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
/// Errors related to data loading into the store use the other error kinds.
pub fn load_dataset(
&self,
reader: impl BufRead,
syntax: DatasetSyntax,
base_iri: Option<&str>,
) -> Result<(), crate::Error> {
) -> Result<(), io::Error> {
load_dataset(&mut DirectWriter::new(self), reader, syntax, base_iri)
}
@ -658,13 +666,16 @@ impl SledTransaction<'_> {
/// Do not use for big files.
///
/// See `MemoryTransaction` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_graph(
&mut self,
reader: impl BufRead,
syntax: GraphSyntax,
to_graph_name: &GraphName,
base_iri: Option<&str>,
) -> Result<(), crate::Error> {
) -> Result<(), io::Error> {
load_graph(&mut self.inner, reader, syntax, to_graph_name, base_iri)
}
@ -675,12 +686,15 @@ impl SledTransaction<'_> {
/// Do not use for big files.
///
/// See `MemoryTransaction` for a usage example.
///
/// Errors related to parameter validation like the base IRI use the `INVALID_INPUT` error kind.
/// Errors related to a bad syntax in the loaded file use the `INVALID_DATA` error kind.
pub fn load_dataset(
&mut self,
reader: impl BufRead,
syntax: DatasetSyntax,
base_iri: Option<&str>,
) -> Result<(), crate::Error> {
) -> Result<(), io::Error> {
load_dataset(&mut self.inner, reader, syntax, base_iri)
}

@ -58,7 +58,7 @@ impl PyMemoryStore {
let results = self
.inner
.query(query, QueryOptions::default())
.map_err(|e| ParseError::py_err(e.to_string()))?;
.map_err(|e| ValueError::py_err(e.to_string()))?;
query_results_to_python(py, results)
}
@ -89,7 +89,7 @@ impl PyMemoryStore {
&to_graph_name.unwrap_or(GraphName::DefaultGraph),
base_iri,
)
.map_err(|e| ParseError::py_err(e.to_string()))
.map_err(map_io_err)
} else if let Some(dataset_syntax) = DatasetSyntax::from_media_type(mime_type) {
if to_graph_name.is_some() {
return Err(ValueError::py_err(
@ -98,7 +98,7 @@ impl PyMemoryStore {
}
self.inner
.load_dataset(Cursor::new(data), dataset_syntax, base_iri)
.map_err(|e| ParseError::py_err(e.to_string()))
.map_err(map_io_err)
} else {
Err(ValueError::py_err(format!(
"Not supported MIME type: {}",

@ -3,7 +3,7 @@ use crate::store_utils::*;
use oxigraph::model::*;
use oxigraph::sparql::QueryOptions;
use oxigraph::{DatasetSyntax, GraphSyntax, SledStore};
use pyo3::exceptions::{IOError, ValueError};
use pyo3::exceptions::ValueError;
use pyo3::prelude::*;
use pyo3::types::PyTuple;
use pyo3::{PyIterProtocol, PyObjectProtocol, PySequenceProtocol};
@ -22,23 +22,19 @@ impl PySledStore {
fn new(path: Option<&str>) -> PyResult<Self> {
Ok(Self {
inner: if let Some(path) = path {
SledStore::open(path).map_err(|e| IOError::py_err(e.to_string()))?
SledStore::open(path).map_err(map_io_err)?
} else {
SledStore::new().map_err(|e| IOError::py_err(e.to_string()))?
SledStore::new().map_err(map_io_err)?
},
})
}
fn add(&self, quad: &PyTuple) -> PyResult<()> {
self.inner
.insert(&extract_quad(quad)?)
.map_err(|e| IOError::py_err(e.to_string()))
self.inner.insert(&extract_quad(quad)?).map_err(map_io_err)
}
fn remove(&self, quad: &PyTuple) -> PyResult<()> {
self.inner
.remove(&extract_quad(quad)?)
.map_err(|e| IOError::py_err(e.to_string()))
self.inner.remove(&extract_quad(quad)?).map_err(map_io_err)
}
fn r#match(
@ -64,7 +60,7 @@ impl PySledStore {
let results = self
.inner
.query(query, QueryOptions::default())
.map_err(|e| ParseError::py_err(e.to_string()))?;
.map_err(|e| ValueError::py_err(e.to_string()))?;
query_results_to_python(py, results)
}
@ -95,7 +91,7 @@ impl PySledStore {
&to_graph_name.unwrap_or(GraphName::DefaultGraph),
base_iri,
)
.map_err(|e| ParseError::py_err(e.to_string()))
.map_err(map_io_err)
} else if let Some(dataset_syntax) = DatasetSyntax::from_media_type(mime_type) {
if to_graph_name.is_some() {
return Err(ValueError::py_err(
@ -104,7 +100,7 @@ impl PySledStore {
}
self.inner
.load_dataset(Cursor::new(data), dataset_syntax, base_iri)
.map_err(|e| ParseError::py_err(e.to_string()))
.map_err(map_io_err)
} else {
Err(ValueError::py_err(format!(
"Not supported MIME type: {}",
@ -134,7 +130,7 @@ impl PySequenceProtocol for PySledStore {
fn __contains__(&self, quad: &PyTuple) -> PyResult<bool> {
self.inner
.contains(&extract_quad(quad)?)
.map_err(|e| IOError::py_err(e.to_string()))
.map_err(map_io_err)
}
}
@ -163,12 +159,7 @@ impl PyIterProtocol for QuadIter {
) -> PyResult<Option<(PyObject, PyObject, PyObject, PyObject)>> {
slf.inner
.next()
.map(move |q| {
Ok(quad_to_python(
slf.py(),
q.map_err(|e| IOError::py_err(e.to_string()))?,
))
})
.map(move |q| Ok(quad_to_python(slf.py(), q.map_err(map_io_err)?)))
.transpose()
}
}

@ -2,12 +2,11 @@ use crate::model::*;
use oxigraph::model::*;
use oxigraph::sparql::{QueryResult, QuerySolution, QuerySolutionsIterator};
use oxigraph::Result;
use pyo3::exceptions::{IOError, TypeError};
use pyo3::exceptions::{IOError, TypeError, ValueError};
use pyo3::prelude::*;
use pyo3::{create_exception, PyIterProtocol, PyMappingProtocol, PyNativeType, PyObjectProtocol};
use pyo3::{PyIterProtocol, PyMappingProtocol, PyNativeType, PyObjectProtocol};
use std::fmt::Write;
create_exception!(oxigraph, ParseError, pyo3::exceptions::Exception);
use std::io;
pub fn extract_quads_pattern(
subject: &PyAny,
@ -140,3 +139,12 @@ impl PyIterProtocol for TripleResultIter {
.map(move |t| triple_to_python(slf.py(), t)))
}
}
pub fn map_io_err(error: io::Error) -> PyErr {
match error.kind() {
io::ErrorKind::InvalidInput | io::ErrorKind::InvalidData => {
ValueError::py_err(error.to_string())
}
_ => IOError::py_err(error.to_string()),
}
}

Loading…
Cancel
Save