Migrates to failure from error_chain

pull/10/head
Tpt 6 years ago
parent f991fb2ccd
commit 12f80fc622
  1. 2
      lib/Cargo.toml
  2. 45
      lib/src/errors.rs
  3. 9
      lib/src/lib.rs
  4. 2
      lib/src/rio/ntriples/mod.rs
  5. 3
      lib/src/rio/turtle/mod.rs
  6. 16
      lib/src/rio/xml.rs
  7. 2
      lib/src/sparql/algebra.rs
  8. 3
      lib/src/sparql/parser.rs
  9. 7
      lib/src/sparql/plan.rs
  10. 72
      lib/src/sparql/xml_results.rs
  11. 20
      lib/src/store/encoded.rs
  12. 79
      lib/src/store/memory.rs
  13. 45
      lib/src/store/numeric_encoder.rs
  14. 24
      lib/src/store/rocksdb.rs
  15. 25
      lib/tests/rdf_test_cases.rs
  16. 36
      lib/tests/sparql_test_cases.rs
  17. 6
      python/src/lib.rs

@ -15,7 +15,6 @@ build = "build.rs"
travis-ci = { repository = "Tpt/rudf" }
[dependencies]
error-chain = "0.12"
lazy_static = "1"
rocksdb = "0.10"
url = "1"
@ -28,6 +27,7 @@ num-traits = "0.2"
rust_decimal = "0.10"
chrono = "0.4"
language-tags = "0.2"
failure = "0.1"
[build-dependencies]
peg = "0.5"

@ -1,45 +0,0 @@
use quick_xml::Error as Xml_Error;
use std::fmt;
use std::sync::PoisonError;
error_chain! {
foreign_links {
Url(::url::ParseError);
RocksDB(::rocksdb::Error);
Utf8(::std::str::Utf8Error);
Io(::std::io::Error);
NTriples(::rio::ntriples::ParseError);
Turtle(::rio::turtle::ParseError);
SparqlParser(::sparql::parser::ParseError);
}
errors {
Xml(error: Xml_Error) {
description("XML parsing error")
display("XML parsing error: {:?}", error)
}
}
}
impl<T> From<PoisonError<T>> for Error {
fn from(_: PoisonError<T>) -> Self {
//TODO: improve conversion
"Unexpected lock error".into()
}
}
impl From<Xml_Error> for Error {
fn from(error: Xml_Error) -> Self {
match error {
Xml_Error::Io(error) => error.into(),
Xml_Error::Utf8(error) => error.into(),
error => ErrorKind::Xml(error).into(),
}
}
}
impl From<Error> for fmt::Error {
fn from(_: Error) -> Self {
fmt::Error
}
}

@ -33,8 +33,6 @@
extern crate byteorder;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate lazy_static;
extern crate chrono;
extern crate language_tags;
@ -45,13 +43,14 @@ extern crate rocksdb;
extern crate rust_decimal;
extern crate url;
extern crate uuid;
#[macro_use]
extern crate failure;
mod errors;
pub mod model;
pub mod rio;
pub mod sparql;
pub mod store;
mod utils;
pub use errors::Error;
pub use errors::Result;
pub use failure::Error;
pub type Result<T> = ::std::result::Result<T, failure::Error>;

@ -41,8 +41,6 @@ use std::io::BufReader;
use std::io::Read;
use Result;
pub(crate) type ParseError = self::grammar::ParseError;
struct NTriplesIterator<R: Read> {
buffer: String,
reader: BufReader<R>,

@ -45,7 +45,7 @@ mod grammar {
pub fn read_turtle<'a, R: Read + 'a>(
source: R,
base_uri: impl Into<Option<Url>>,
) -> super::super::super::errors::Result<impl Iterator<Item = Triple>> {
) -> super::super::super::Result<impl Iterator<Item = Triple>> {
let mut state = ParserState {
base_uri: base_uri.into(),
namespaces: HashMap::default(),
@ -78,5 +78,4 @@ mod grammar {
}
}
pub(crate) type ParseError = self::grammar::ParseError;
pub use self::grammar::read_turtle;

@ -283,7 +283,11 @@ impl<R: BufRead> RdfXmlIterator<R> {
Some(RdfXmlState::ParseTypeCollectionPropertyElt { .. }) => {
RdfXmlNextProduction::NodeElt {}
}
None => return Err("No state in the stack: the XML is not balanced".into()),
None => {
return Err(format_err!(
"No state in the stack: the XML is not balanced"
))
}
};
let new_state = match next_production {
@ -356,7 +360,9 @@ impl<R: BufRead> RdfXmlIterator<R> {
}
}
RdfXmlParseType::Literal => {
return Err("rdf:parseType=\"Literal\" is not supported yet".into());
return Err(format_err!(
"rdf:parseType=\"Literal\" is not supported yet"
));
}
RdfXmlParseType::Resource => self.build_parse_type_resource_property_elt(
NamedNode::from(uri),
@ -366,10 +372,12 @@ impl<R: BufRead> RdfXmlIterator<R> {
id_attr,
),
RdfXmlParseType::Collection => {
return Err("rdf:parseType=\"Collection\" is not supported yet".into());
return Err(format_err!(
"rdf:parseType=\"Collection\" is not supported yet"
));
}
RdfXmlParseType::Other => {
return Err("Arbitrary rdf:parseType are not supported yet".into());
return Err(format_err!("Arbitrary rdf:parseType are not supported yet"));
}
},
};

@ -30,7 +30,7 @@ impl Variable {
pub fn name(&self) -> Result<&str> {
match self {
Variable::Variable { name } => Ok(name),
_ => Err(format!("The variable {} has no name", self).into()),
_ => Err(format_err!("The variable {} has no name", self)),
}
}
}

@ -334,7 +334,7 @@ mod grammar {
pub fn read_sparql_query<'a, R: Read + 'a>(
source: R,
base_uri: impl Into<Option<Url>>,
) -> super::super::super::errors::Result<Query> {
) -> super::super::super::Result<Query> {
let mut state = ParserState {
base_uri: base_uri.into(),
namespaces: HashMap::default(),
@ -352,5 +352,4 @@ mod grammar {
}
}
pub(crate) type ParseError = self::grammar::ParseError;
pub use self::grammar::read_sparql_query;

@ -629,7 +629,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
} else if *name == *xsd::STRING {
self.build_cast(parameters, PlanExpression::StringCast, variables, "string")?
} else {
Err(format!("Not supported custom function {}", expression))?
Err(format_err!("Not supported custom function {}", expression))?
},
_ => unimplemented!(),
})
@ -647,7 +647,10 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
self.build_for_expression(&parameters[0], variables)?,
)))
} else {
Err(format!("The xsd:{} casting takes only one parameter", name).into())
Err(format_err!(
"The xsd:{} casting takes only one parameter",
name
))
}
}

@ -33,10 +33,10 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
let (ns, event) = reader.read_namespaced_event(&mut buffer, &mut namespace_buffer)?;
if let Some(ns) = ns {
if ns != b"http://www.w3.org/2005/sparql-results#".as_ref() {
return Err(format!(
return Err(format_err!(
"Unexpected namespace found in RDF/XML query result: {}",
reader.decode(ns)
).into());
));
}
}
event
@ -47,21 +47,21 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
if event.name() == b"sparql" {
state = State::Sparql;
} else {
return Err(format!("Expecting <sparql> tag, found {}", reader.decode(event.name())).into());
return Err(format_err!("Expecting <sparql> tag, found {}", reader.decode(event.name())));
}
}
State::Sparql => {
if event.name() == b"head" {
state = State::Head;
} else {
return Err(format!("Expecting <head> tag, found {}", reader.decode(event.name())).into());
return Err(format_err!("Expecting <head> tag, found {}", reader.decode(event.name())));
}
}
State::Head => if event.name() == b"variable" || event.name() == b"link" {
return Err("<variable> and <link> tag should be autoclosing".into());
return Err(format_err!("<variable> and <link> tag should be autoclosing"));
} else {
return Err(format!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())).into());
},
return Err(format_err!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())));
}
State::AfterHead => {
if event.name() == b"boolean" {
state = State::Boolean
@ -81,10 +81,10 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
}),
)));
} else if event.name() != b"link" && event.name() != b"results" && event.name() != b"boolean" {
return Err(format!("Expecting sparql tag, found {}", reader.decode(event.name())).into());
return Err(format_err!("Expecting sparql tag, found {}", reader.decode(event.name())));
}
}
State::Boolean => return Err(format!("Unexpected tag inside of <boolean> tag: {}", reader.decode(event.name())).into())
State::Boolean => return Err(format_err!("Unexpected tag inside of <boolean> tag: {}", reader.decode(event.name())))
},
Event::Empty(event) => match state {
State::Head => {
@ -92,12 +92,12 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
let name = event.attributes()
.filter_map(|attr| attr.ok())
.find(|attr| attr.key == b"name")
.ok_or("No name attribute found for the <variable> tag");
.ok_or(format_err!("No name attribute found for the <variable> tag"));
variables.push(name?.unescape_and_decode_value(&reader)?);
} else if event.name() == b"link" {
// no op
} else {
return Err(format!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())).into());
return Err(format_err!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())));
}
},
State::AfterHead => {
@ -107,10 +107,10 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
Box::new(empty()),
)))
} else {
return Err(format!("Unexpected autoclosing tag <{}>", reader.decode(event.name())).into())
return Err(format_err!("Unexpected autoclosing tag <{}>", reader.decode(event.name())))
}
}
_ => return Err(format!("Unexpected autoclosing tag <{}>", reader.decode(event.name())).into())
_ => return Err(format_err!("Unexpected autoclosing tag <{}>", reader.decode(event.name())))
},
Event::Text(event) => {
let value = event.unescaped()?;
@ -121,18 +121,18 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
} else if value.as_ref() == b"false" {
Ok(QueryResult::Boolean(false))
} else {
Err(format!("Unexpected boolean value. Found {}", reader.decode(&value)).into())
Err(format_err!("Unexpected boolean value. Found {}", reader.decode(&value)))
};
}
_ => Err(format!("Unexpected textual value found: {}", reader.decode(&value)).into())
_ => Err(format_err!("Unexpected textual value found: {}", reader.decode(&value)))
};
},
Event::End(_) => if let State::Head = state {
state = State::AfterHead;
} else {
return Err("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag".into());
return Err(format_err!("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag"));
},
Event::Eof => return Err("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag".into()),
Event::Eof => return Err(format_err!("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag")),
_ => (),
}
}
@ -178,10 +178,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
};
if let Some(ns) = ns {
if ns != b"http://www.w3.org/2005/sparql-results#".as_ref() {
return Some(Err(format!(
return Some(Err(format_err!(
"Unexpected namespace found in RDF/XML query result: {}",
self.reader.decode(ns)
).into()));
)));
}
}
match event {
@ -189,10 +189,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
State::Start => if event.name() == b"result" {
state = State::Result;
} else {
return Some(Err(format!(
return Some(Err(format_err!(
"Expecting <result>, found {}",
self.reader.decode(event.name())
).into()));
)));
},
State::Result => if event.name() == b"binding" {
match event
@ -205,23 +205,23 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
Err(error) => return Some(Err(error.into())),
},
None => {
return Some(Err(
"No name attribute found for the <binding> tag".into()
))
return Some(Err(format_err!(
"No name attribute found for the <binding> tag"
)))
}
}
state = State::Binding;
} else {
return Some(Err(format!(
return Some(Err(format_err!(
"Expecting <binding>, found {}",
self.reader.decode(event.name())
).into()));
)));
},
State::Binding => {
if term.is_some() {
return Some(Err(
"There is already a value for the current binding".into()
));
return Some(Err(format_err!(
"There is already a value for the current binding"
)));
}
if event.name() == b"uri" {
state = State::Uri;
@ -251,10 +251,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
}
state = State::Literal;
} else {
return Some(Err(format!(
return Some(Err(format_err!(
"Expecting <uri>, <bnode> or <literal> found {}",
self.reader.decode(event.name())
).into()));
)));
}
}
_ => (),
@ -279,10 +279,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
term = Some(build_literal(value, &lang, &datatype).into());
}
_ => {
return Some(Err(format!(
return Some(Err(format_err!(
"Unexpected textual value found: {}",
self.reader.decode(&data)
).into()))
)))
}
},
Err(error) => return Some(Err(error.into())),
@ -296,12 +296,12 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
new_bindings[self.mapping[var]] = Some(term.clone())
}
(Some(var), None) => {
return Some(Err(format!(
return Some(Err(format_err!(
"No variable found for variable {}",
self.reader.decode(&var)
).into()))
)))
}
_ => return Some(Err("No name found for <binding> tag".into())),
_ => return Some(Err(format_err!("No name found for <binding> tag"))),
}
term = None;
state = State::Result;

@ -353,8 +353,8 @@ impl<S: EncodedQuadsStore> Dataset for StoreDataset<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreDataset<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for quad in self.iter()? {
writeln!(fmt, "{}", quad?)?;
for quad in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", quad.map_err(|_| fmt::Error)?)?;
}
Ok(())
}
@ -539,8 +539,8 @@ impl<S: EncodedQuadsStore> NamedGraph for StoreNamedGraph<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreNamedGraph<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for triple in self.iter()? {
writeln!(fmt, "{}", triple?)?;
for triple in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?;
}
Ok(())
}
@ -694,8 +694,8 @@ impl<S: EncodedQuadsStore> Graph for StoreDefaultGraph<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreDefaultGraph<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for triple in self.iter()? {
writeln!(fmt, "{}", triple?)?;
for triple in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?;
}
Ok(())
}
@ -840,11 +840,11 @@ impl<S: EncodedQuadsStore> Graph for StoreUnionGraph<S> {
}
fn insert(&self, _triple: &Triple) -> Result<()> {
Err("Union graph is not writable".into())
Err(format_err!("Union graph is not writable"))
}
fn remove(&self, _triple: &Triple) -> Result<()> {
Err("Union graph is not writable".into())
Err(format_err!("Union graph is not writable"))
}
fn len(&self) -> Result<usize> {
@ -858,8 +858,8 @@ impl<S: EncodedQuadsStore> Graph for StoreUnionGraph<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreUnionGraph<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for triple in self.iter()? {
writeln!(fmt, "{}", triple?)?;
for triple in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?;
}
Ok(())
}

@ -1,6 +1,10 @@
use failure::Backtrace;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::sync::PoisonError;
use std::sync::RwLock;
use std::sync::RwLockReadGuard;
use std::sync::RwLockWriteGuard;
use store::encoded::*;
use store::numeric_encoder::*;
use Result;
@ -71,8 +75,8 @@ impl BytesStore for MemoryStore {
type BytesOutput = Vec<u8>;
fn insert_bytes(&self, value: &[u8]) -> Result<u64> {
let mut id2str = self.id2str.write()?;
let mut str2id = self.str2id.write()?;
let mut id2str = self.id2str.write().map_err(MemoryStorePoisonError::from)?;
let mut str2id = self.str2id.write().map_err(MemoryStorePoisonError::from)?;
let id = str2id.entry(value.to_vec()).or_insert_with(|| {
let id = id2str.len() as u64;
id2str.push(value.to_vec());
@ -83,7 +87,7 @@ impl BytesStore for MemoryStore {
fn get_bytes(&self, id: u64) -> Result<Option<Vec<u8>>> {
//TODO: use try_from when stable
let id2str = self.id2str.read()?;
let id2str = self.id2str.read().map_err(MemoryStorePoisonError::from)?;
Ok(if id2str.len() as u64 <= id {
None
} else {
@ -114,7 +118,7 @@ impl EncodedQuadsStore for MemoryStore {
fn quads(&self) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
for (s, pos) in &graph.spo {
for (p, os) in pos.iter() {
for o in os.iter() {
@ -131,7 +135,7 @@ impl EncodedQuadsStore for MemoryStore {
subject: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(pos) = graph.spo.get(&subject) {
for (p, os) in pos.iter() {
for o in os.iter() {
@ -149,7 +153,7 @@ impl EncodedQuadsStore for MemoryStore {
predicate: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(pos) = graph.spo.get(&subject) {
if let Some(os) = pos.get(&predicate) {
for o in os.iter() {
@ -168,7 +172,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(pos) = graph.spo.get(&subject) {
if let Some(os) = pos.get(&predicate) {
if os.contains(&object) {
@ -191,7 +195,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(sps) = graph.osp.get(&object) {
if let Some(ps) = sps.get(&subject) {
for p in ps.iter() {
@ -208,7 +212,7 @@ impl EncodedQuadsStore for MemoryStore {
predicate: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(oss) = graph.pos.get(&predicate) {
for (o, ss) in oss.iter() {
for s in ss.iter() {
@ -226,7 +230,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(oss) = graph.pos.get(&predicate) {
if let Some(ss) = oss.get(&object) {
for s in ss.iter() {
@ -243,7 +247,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() {
for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(sps) = graph.osp.get(&object) {
for (s, ps) in sps.iter() {
for p in ps.iter() {
@ -260,7 +264,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
for (s, pos) in &graph.spo {
for (p, os) in pos.iter() {
for o in os.iter() {
@ -278,7 +282,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(pos) = graph.spo.get(&subject) {
for (p, os) in pos.iter() {
for o in os.iter() {
@ -297,7 +301,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(pos) = graph.spo.get(&subject) {
if let Some(os) = pos.get(&predicate) {
for o in os.iter() {
@ -316,7 +320,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(sps) = graph.osp.get(&object) {
if let Some(ps) = sps.get(&subject) {
for p in ps.iter() {
@ -334,7 +338,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(oss) = graph.pos.get(&predicate) {
for (o, ss) in oss.iter() {
for s in ss.iter() {
@ -353,7 +357,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(oss) = graph.pos.get(&predicate) {
if let Some(ss) = oss.get(&object) {
for s in ss.iter() {
@ -371,7 +375,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) {
if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(sps) = graph.osp.get(&object) {
for (s, ps) in sps.iter() {
for p in ps.iter() {
@ -385,8 +389,7 @@ impl EncodedQuadsStore for MemoryStore {
fn contains(&self, quad: &EncodedQuad) -> Result<bool> {
Ok(self
.graph_indexes
.read()?
.graph_indexes()?
.get(&quad.graph_name)
.map_or(false, |graph| {
graph.spo.get(&quad.subject).map_or(false, |po| {
@ -397,7 +400,7 @@ impl EncodedQuadsStore for MemoryStore {
}
fn insert(&self, quad: &EncodedQuad) -> Result<()> {
let mut graph_indexes = self.graph_indexes.write()?;
let mut graph_indexes = self.graph_indexes_mut()?;
let graph = graph_indexes
.entry(quad.graph_name)
.or_insert_with(MemoryGraphIndexes::default);
@ -426,7 +429,7 @@ impl EncodedQuadsStore for MemoryStore {
}
fn remove(&self, quad: &EncodedQuad) -> Result<()> {
let mut graph_indexes = self.graph_indexes.write()?;
let mut graph_indexes = self.graph_indexes_mut()?;
let mut empty_graph = false;
if let Some(graph) = graph_indexes.get_mut(&quad.graph_name) {
{
@ -491,3 +494,35 @@ impl EncodedQuadsStore for MemoryStore {
Ok(())
}
}
impl MemoryStore {
fn graph_indexes(&self) -> Result<RwLockReadGuard<BTreeMap<EncodedTerm, MemoryGraphIndexes>>> {
Ok(self
.graph_indexes
.read()
.map_err(MemoryStorePoisonError::from)?)
}
fn graph_indexes_mut(
&self,
) -> Result<RwLockWriteGuard<BTreeMap<EncodedTerm, MemoryGraphIndexes>>> {
Ok(self
.graph_indexes
.write()
.map_err(MemoryStorePoisonError::from)?)
}
}
#[derive(Debug, Fail)]
#[fail(display = "MemoryStore Mutex was poisoned")]
pub struct MemoryStorePoisonError {
backtrace: Backtrace,
}
impl<T> From<PoisonError<T>> for MemoryStorePoisonError {
fn from(_: PoisonError<T>) -> Self {
Self {
backtrace: Backtrace::new(),
}
}
}

@ -14,7 +14,6 @@ use std::str;
use std::str::FromStr;
use url::Url;
use uuid::Uuid;
use Error;
use Result;
const EMPTY_STRING_ID: u64 = 0;
@ -47,7 +46,9 @@ pub trait BytesStore {
{
Ok(())
} else {
Err("Failed to properly setup the basic string ids in the dictionnary".into())
Err(format_err!(
"Failed to properly setup the basic string ids in the dictionnary"
))
}
}
}
@ -317,17 +318,17 @@ impl<R: Read> TermReader for R {
NaiveDateTime::from_timestamp_opt(
self.read_i64::<LittleEndian>()?,
self.read_u32::<LittleEndian>()?,
).ok_or("Invalid date time serialization")?,
).ok_or_else(|| format_err!("Invalid date time serialization"))?,
FixedOffset::east_opt(self.read_i32::<LittleEndian>()?)
.ok_or("Invalid timezone offset")?,
.ok_or_else(|| format_err!("Invalid timezone offset"))?,
))),
TYPE_NAIVE_DATE_TIME_LITERAL => Ok(EncodedTerm::NaiveDateTime(
NaiveDateTime::from_timestamp_opt(
self.read_i64::<LittleEndian>()?,
self.read_u32::<LittleEndian>()?,
).ok_or("Invalid date time serialization")?,
).ok_or_else(|| format_err!("Invalid date time serialization"))?,
)),
_ => Err("the term buffer has an invalid type id".into()),
_ => Err(format_err!("the term buffer has an invalid type id")),
}
}
@ -483,37 +484,37 @@ impl<S: BytesStore> Encoder<S> {
} else if literal.is_boolean() {
literal
.to_bool()
.ok_or_else(|| Error::from("boolean literal without boolean value"))?
.ok_or_else(|| format_err!("boolean literal without boolean value"))?
.into()
} else if literal.is_float() {
literal
.to_float()
.ok_or_else(|| Error::from("float literal without float value"))?
.ok_or_else(|| format_err!("float literal without float value"))?
.into()
} else if literal.is_double() {
literal
.to_double()
.ok_or_else(|| Error::from("double literal without double value"))?
.ok_or_else(|| format_err!("double literal without double value"))?
.into()
} else if literal.is_integer() {
literal
.to_integer()
.ok_or_else(|| Error::from("integer literal without integer value"))?
.ok_or_else(|| format_err!("integer literal without integer value"))?
.into()
} else if literal.is_decimal() {
literal
.to_decimal()
.ok_or_else(|| Error::from("decimal literal without decimal value"))?
.ok_or_else(|| format_err!("decimal literal without decimal value"))?
.into()
} else if literal.is_date_time_stamp() {
literal
.to_date_time_stamp()
.ok_or_else(|| Error::from("dateTimeStamp literal without dateTimeStamp value"))?
.ok_or_else(|| format_err!("dateTimeStamp literal without dateTimeStamp value"))?
.into()
} else if literal.is_decimal() {
literal
.to_date_time()
.ok_or_else(|| Error::from("dateTime literal without dateTime value"))?
.ok_or_else(|| format_err!("dateTime literal without dateTime value"))?
.into()
} else {
EncodedTerm::TypedLiteral {
@ -565,7 +566,9 @@ impl<S: BytesStore> Encoder<S> {
pub fn decode_term(&self, encoded: EncodedTerm) -> Result<Term> {
match encoded {
EncodedTerm::DefaultGraph {} => Err("The default graph tag is not a valid term".into()),
EncodedTerm::DefaultGraph {} => {
Err(format_err!("The default graph tag is not a valid term"))
}
EncodedTerm::NamedNode { iri_id } => {
Ok(NamedNode::from(self.decode_url_value(iri_id)?).into())
}
@ -604,15 +607,21 @@ impl<S: BytesStore> Encoder<S> {
match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node.into()),
Term::BlankNode(blank_node) => Ok(blank_node.into()),
Term::Literal(_) => Err("A literal has ben found instead of a named node".into()),
Term::Literal(_) => Err(format_err!(
"A literal has ben found instead of a named node"
)),
}
}
pub fn decode_named_node(&self, encoded: EncodedTerm) -> Result<NamedNode> {
match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node),
Term::BlankNode(_) => Err("A blank node has been found instead of a named node".into()),
Term::Literal(_) => Err("A literal has ben found instead of a named node".into()),
Term::BlankNode(_) => Err(format_err!(
"A blank node has been found instead of a named node"
)),
Term::Literal(_) => Err(format_err!(
"A literal has ben found instead of a named node"
)),
}
}
@ -653,7 +662,7 @@ impl<S: BytesStore> Encoder<S> {
fn decode_value(&self, id: u64) -> Result<S::BytesOutput> {
self.string_store
.get_bytes(id)?
.ok_or_else(|| "value not found in the dictionary".into())
.ok_or_else(|| format_err!("value not found in the dictionary"))
}
}

@ -1,5 +1,6 @@
use byteorder::ByteOrder;
use byteorder::LittleEndian;
use failure::Backtrace;
use rocksdb::ColumnFamily;
use rocksdb::DBRawIterator;
use rocksdb::DBVector;
@ -10,6 +11,7 @@ use std::io::Cursor;
use std::path::Path;
use std::str;
use std::sync::Mutex;
use std::sync::PoisonError;
use store::encoded::EncodedQuadsStore;
use store::encoded::StoreDataset;
use store::numeric_encoder::*;
@ -86,7 +88,11 @@ impl BytesStore for RocksDbStore {
Ok(if let Some(id) = self.db.get_cf(self.str2id_cf, value)? {
LittleEndian::read_u64(&id)
} else {
let id = self.str_id_counter.lock()?.get_and_increment(&self.db)? as u64;
let id = self
.str_id_counter
.lock()
.map_err(RocksDBCounterMutexPoisonError::from)?
.get_and_increment(&self.db)? as u64;
let id_bytes = to_bytes(id);
let mut batch = WriteBatch::default();
batch.put_cf(self.id2str_cf, &id_bytes, value)?;
@ -326,7 +332,7 @@ impl EncodedQuadsStore for RocksDbStore {
pub fn get_cf(db: &DB, name: &str) -> Result<ColumnFamily> {
db.cf_handle(name)
.ok_or_else(|| "column family not found".into())
.ok_or_else(|| format_err!("column family not found"))
}
struct RocksDBCounter {
@ -516,3 +522,17 @@ fn to_bytes(int: u64) -> [u8; 8] {
LittleEndian::write_u64(&mut buf, int);
buf
}
#[derive(Debug, Fail)]
#[fail(display = "RocksDBStore Mutex was poisoned")]
pub struct RocksDBCounterMutexPoisonError {
backtrace: Backtrace,
}
impl<T> From<PoisonError<T>> for RocksDBCounterMutexPoisonError {
fn from(_: PoisonError<T>) -> Self {
Self {
backtrace: Backtrace::new(),
}
}
}

@ -5,6 +5,8 @@ extern crate lazy_static;
extern crate reqwest;
extern crate rudf;
extern crate url;
#[macro_use]
extern crate failure;
use reqwest::Client;
use reqwest::Response;
@ -212,7 +214,7 @@ impl RDFClient {
{
self.get(url)
} else {
Err(format!("HTTP request error: {}", error.description()).into())
Err(format_err!("HTTP request error: {}", error.description()))
},
}
}
@ -296,9 +298,9 @@ impl<'a> Iterator for TestManifest<'a> {
{
Some(Term::NamedNode(c)) => match c.as_str().split("#").last() {
Some(k) => k.to_string(),
None => return Some(Err("no type".into())),
None => return Some(Err(format_err!("no type"))),
},
_ => return Some(Err("no type".into())),
_ => return Some(Err(format_err!("no type"))),
};
let name = match self
.graph
@ -322,8 +324,8 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap()
{
Some(Term::NamedNode(n)) => n.as_url().clone(),
Some(_) => return Some(Err("invalid action".into())),
None => return Some(Err("action not found".into())),
Some(_) => return Some(Err(format_err!("invalid action"))),
None => return Some(Err(format_err!("action not found"))),
};
let result = match self
.graph
@ -331,7 +333,7 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap()
{
Some(Term::NamedNode(n)) => Some(n.as_url().clone()),
Some(_) => return Some(Err("invalid result".into())),
Some(_) => return Some(Err(format_err!("invalid result"))),
None => None,
};
Some(Ok(Test {
@ -343,7 +345,7 @@ impl<'a> Iterator for TestManifest<'a> {
result,
}))
}
Some(_) => Some(Err("invalid test list".into())),
Some(_) => Some(Err(format_err!("invalid test list"))),
None => {
match self.manifests_to_do.pop() {
Some(url) => {
@ -371,7 +373,7 @@ impl<'a> Iterator for TestManifest<'a> {
}),
);
}
Some(_) => return Some(Err("invalid tests list".into())),
Some(_) => return Some(Err(format_err!("invalid tests list"))),
None => (),
}
@ -388,9 +390,10 @@ impl<'a> Iterator for TestManifest<'a> {
));
}
Some(term) => {
return Some(Err(
format!("Invalid tests list. Got term {}", term).into()
))
return Some(Err(format_err!(
"Invalid tests list. Got term {}",
term
)))
}
None => (),
}

@ -4,6 +4,8 @@ extern crate lazy_static;
extern crate reqwest;
extern crate rudf;
extern crate url;
#[macro_use]
extern crate failure;
use reqwest::Client;
use reqwest::Response;
@ -276,7 +278,7 @@ impl RDFClient {
} else if url.as_str().ends_with(".rdf") {
read_rdf_xml(BufReader::new(self.get(&url)?), Some(url)).collect()
} else {
Err(format!("Serialization type not found for {}", url).into())
Err(format_err!("Serialization type not found for {}", url))
}
}
@ -299,7 +301,7 @@ impl RDFClient {
{
self.get(url)
} else {
Err(format!("HTTP request error: {}", error.description()).into())
Err(format_err!("HTTP request error: {}", error.description()))
},
}
}
@ -518,9 +520,9 @@ impl<'a> Iterator for TestManifest<'a> {
{
Some(Term::NamedNode(c)) => match c.as_str().split("#").last() {
Some(k) => k.to_string(),
None => return Some(Err("no type".into())),
None => return Some(Err(format_err!("no type"))),
},
_ => return Some(Err("no type".into())),
_ => return Some(Err(format_err!("no type"))),
};
let name = match self
.graph
@ -552,8 +554,8 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap()
{
Some(Term::NamedNode(q)) => q.into(),
Some(_) => return Some(Err("invalid query".into())),
None => return Some(Err("query not found".into())),
Some(_) => return Some(Err(format_err!("invalid query"))),
None => return Some(Err(format_err!("query not found"))),
};
let data = match self
.graph
@ -573,11 +575,12 @@ impl<'a> Iterator for TestManifest<'a> {
}).collect();
(query, data, graph_data)
}
Some(_) => return Some(Err("invalid action".into())),
Some(_) => return Some(Err(format_err!("invalid action"))),
None => {
return Some(Err(
format!("action not found for test {}", test_subject).into()
))
return Some(Err(format_err!(
"action not found for test {}",
test_subject
)))
}
};
let result = match self
@ -586,7 +589,7 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap()
{
Some(Term::NamedNode(n)) => Some(n.into()),
Some(_) => return Some(Err("invalid result".into())),
Some(_) => return Some(Err(format_err!("invalid result"))),
None => None,
};
Some(Ok(Test {
@ -600,7 +603,7 @@ impl<'a> Iterator for TestManifest<'a> {
result,
}))
}
Some(_) => Some(Err("invalid test list".into())),
Some(_) => Some(Err(format_err!("invalid test list"))),
None => {
match self.manifests_to_do.pop() {
Some(url) => {
@ -628,7 +631,7 @@ impl<'a> Iterator for TestManifest<'a> {
}),
);
}
Some(_) => return Some(Err("invalid tests list".into())),
Some(_) => return Some(Err(format_err!("invalid tests list"))),
None => (),
}
@ -645,9 +648,10 @@ impl<'a> Iterator for TestManifest<'a> {
));
}
Some(term) => {
return Some(Err(
format!("Invalid tests list. Got term {}", term).into()
));
return Some(Err(format_err!(
"Invalid tests list. Got term {}",
term
)));
}
None => (),
}

@ -15,8 +15,8 @@ use cpython::Python;
use cpython::PythonObject;
use cpython::ToPyObject;
use rudf::model;
use rudf::Error;
use std::collections::hash_map::DefaultHasher;
use std::error::Error;
use std::hash::Hash;
use std::hash::Hasher;
use std::str::FromStr;
@ -29,8 +29,8 @@ py_module_initializer!(rudf, initrudf, PyInit_rudf, |py, m| {
Ok(())
});
fn new_value_error(py: Python, error: &impl Error) -> PyErr {
PyErr::new::<ValueError, _>(py, error.description())
fn new_value_error(py: Python, error: &Error) -> PyErr {
PyErr::new::<ValueError, _>(py, error.to_string())
}
fn eq_compare<T: Eq + Ord>(a: &T, b: &T, op: &CompareOp) -> bool {

Loading…
Cancel
Save