Allows some low level storage trait to specify error type

pull/46/head
Tpt 4 years ago
parent ce2b05b62b
commit 5d54bc2d06
  1. 25
      lib/src/error.rs
  2. 2
      lib/src/sparql/eval.rs
  3. 14
      lib/src/sparql/plan.rs
  4. 38
      lib/src/sparql/plan_builder.rs
  5. 67
      lib/src/store/memory.rs
  6. 28
      lib/src/store/mod.rs
  7. 107
      lib/src/store/numeric_encoder.rs
  8. 10
      lib/src/store/rocksdb.rs
  9. 6
      lib/src/store/sled.rs

@ -2,6 +2,7 @@ use crate::model::{BlankNodeIdParseError, IriParseError, LanguageTagParseError};
use crate::sparql::SparqlParseError; use crate::sparql::SparqlParseError;
use rio_turtle::TurtleError; use rio_turtle::TurtleError;
use rio_xml::RdfXmlError; use rio_xml::RdfXmlError;
use std::convert::Infallible;
use std::error; use std::error;
use std::fmt; use std::fmt;
use std::io; use std::io;
@ -71,6 +72,12 @@ enum ErrorKind {
Other(Box<dyn error::Error + Send + Sync + 'static>), Other(Box<dyn error::Error + Send + Sync + 'static>),
} }
impl From<Infallible> for Error {
fn from(error: Infallible) -> Self {
match error {}
}
}
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(error: io::Error) -> Self { fn from(error: io::Error) -> Self {
Self { Self {
@ -148,3 +155,21 @@ impl From<sled::Error> for Error {
Self::wrap(error) Self::wrap(error)
} }
} }
/// Traits that allows unwrapping only infallible results
pub(crate) trait UnwrapInfallible {
type Value;
fn unwrap_infallible(self) -> Self::Value;
}
impl<T> UnwrapInfallible for Result<T, Infallible> {
type Value = T;
fn unwrap_infallible(self) -> T {
match self {
Ok(value) => value,
Err(error) => match error {},
}
}
}

@ -1652,7 +1652,7 @@ impl<'a, S: ReadableEncodedStore + 'a> SimpleEvaluator<S> {
put_variable_value( put_variable_value(
variable, variable,
variables, variables,
encoder.encode_term(term)?, encoder.encode_term(term).map_err(|e| e.into())?,
&mut encoded_terms, &mut encoded_terms,
) )
} }

@ -1,3 +1,4 @@
use crate::error::UnwrapInfallible;
use crate::sparql::model::Variable; use crate::sparql::model::Variable;
use crate::sparql::GraphPattern; use crate::sparql::GraphPattern;
use crate::store::numeric_encoder::{ use crate::store::numeric_encoder::{
@ -617,8 +618,10 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
} }
impl<S: ReadableEncodedStore> StrLookup for DatasetView<S> { impl<S: ReadableEncodedStore> StrLookup for DatasetView<S> {
fn get_str(&self, id: StrHash) -> Result<Option<String>> { type Error = S::Error;
if let Some(value) = self.extra.borrow().get_str(id)? {
fn get_str(&self, id: StrHash) -> std::result::Result<Option<String>, Self::Error> {
if let Some(value) = self.extra.borrow().get_str(id).unwrap_infallible() {
Ok(Some(value)) Ok(Some(value))
} else { } else {
self.store.get_str(id) self.store.get_str(id)
@ -632,9 +635,12 @@ struct DatasetViewStrContainer<'a, S: ReadableEncodedStore> {
} }
impl<'a, S: ReadableEncodedStore> StrContainer for DatasetViewStrContainer<'a, S> { impl<'a, S: ReadableEncodedStore> StrContainer for DatasetViewStrContainer<'a, S> {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { type Error = S::Error;
fn insert_str(&mut self, key: StrHash, value: &str) -> std::result::Result<(), Self::Error> {
if self.store.get_str(key)?.is_none() { if self.store.get_str(key)?.is_none() {
self.extra.insert_str(key, value) self.extra.insert_str(key, value).unwrap();
Ok(())
} else { } else {
Ok(()) Ok(())
} }

@ -238,9 +238,9 @@ impl<E: Encoder> PlanBuilder<E> {
fn build_for_path(&mut self, path: &PropertyPath) -> Result<PlanPropertyPath> { fn build_for_path(&mut self, path: &PropertyPath) -> Result<PlanPropertyPath> {
Ok(match path { Ok(match path {
PropertyPath::PredicatePath(p) => { PropertyPath::PredicatePath(p) => PlanPropertyPath::PredicatePath(
PlanPropertyPath::PredicatePath(self.encoder.encode_named_node(p)?) self.encoder.encode_named_node(p).map_err(|e| e.into())?,
} ),
PropertyPath::InversePath(p) => { PropertyPath::InversePath(p) => {
PlanPropertyPath::InversePath(Box::new(self.build_for_path(p)?)) PlanPropertyPath::InversePath(Box::new(self.build_for_path(p)?))
} }
@ -263,7 +263,7 @@ impl<E: Encoder> PlanBuilder<E> {
} }
PropertyPath::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet( PropertyPath::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet(
p.iter() p.iter()
.map(|p| self.encoder.encode_named_node(p)) .map(|p| self.encoder.encode_named_node(p).map_err(|e| e.into()))
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
), ),
}) })
@ -276,10 +276,12 @@ impl<E: Encoder> PlanBuilder<E> {
graph_name: PatternValue, graph_name: PatternValue,
) -> Result<PlanExpression> { ) -> Result<PlanExpression> {
Ok(match expression { Ok(match expression {
Expression::NamedNode(node) => { Expression::NamedNode(node) => PlanExpression::Constant(
PlanExpression::Constant(self.encoder.encode_named_node(node)?) self.encoder.encode_named_node(node).map_err(|e| e.into())?,
),
Expression::Literal(l) => {
PlanExpression::Constant(self.encoder.encode_literal(l).map_err(|e| e.into())?)
} }
Expression::Literal(l) => PlanExpression::Constant(self.encoder.encode_literal(l)?),
Expression::Variable(v) => PlanExpression::Variable(variable_key(variables, v)), Expression::Variable(v) => PlanExpression::Variable(variable_key(variables, v)),
Expression::Or(a, b) => PlanExpression::Or( Expression::Or(a, b) => PlanExpression::Or(
Box::new(self.build_for_expression(a, variables, graph_name)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
@ -728,7 +730,9 @@ impl<E: Encoder> PlanBuilder<E> {
PatternValue::Variable(variable_key(variables, &Variable::new(bnode.as_str()))) PatternValue::Variable(variable_key(variables, &Variable::new(bnode.as_str())))
//TODO: very bad hack to convert bnode to variable //TODO: very bad hack to convert bnode to variable
} }
TermOrVariable::Term(term) => PatternValue::Constant(self.encoder.encode_term(term)?), TermOrVariable::Term(term) => {
PatternValue::Constant(self.encoder.encode_term(term).map_err(|e| e.into())?)
}
}) })
} }
@ -738,9 +742,11 @@ impl<E: Encoder> PlanBuilder<E> {
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
) -> Result<PatternValue> { ) -> Result<PatternValue> {
Ok(match named_node_or_variable { Ok(match named_node_or_variable {
NamedNodeOrVariable::NamedNode(named_node) => { NamedNodeOrVariable::NamedNode(named_node) => PatternValue::Constant(
PatternValue::Constant(self.encoder.encode_named_node(named_node)?) self.encoder
} .encode_named_node(named_node)
.map_err(|e| e.into())?,
),
NamedNodeOrVariable::Variable(variable) => { NamedNodeOrVariable::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable)) PatternValue::Variable(variable_key(variables, variable))
} }
@ -765,7 +771,7 @@ impl<E: Encoder> PlanBuilder<E> {
if let Some(term) = value { if let Some(term) = value {
result.set( result.set(
bindings_variables_keys[key], bindings_variables_keys[key],
self.encoder.encode_term(term)?, self.encoder.encode_term(term).map_err(|e| e.into())?,
); );
} }
} }
@ -865,7 +871,7 @@ impl<E: Encoder> PlanBuilder<E> {
TripleTemplateValue::BlankNode(bnode_key(bnodes, bnode)) TripleTemplateValue::BlankNode(bnode_key(bnodes, bnode))
} }
TermOrVariable::Term(term) => { TermOrVariable::Term(term) => {
TripleTemplateValue::Constant(self.encoder.encode_term(term)?) TripleTemplateValue::Constant(self.encoder.encode_term(term).map_err(|e| e.into())?)
} }
}) })
} }
@ -879,9 +885,9 @@ impl<E: Encoder> PlanBuilder<E> {
NamedNodeOrVariable::Variable(variable) => { NamedNodeOrVariable::Variable(variable) => {
TripleTemplateValue::Variable(variable_key(variables, variable)) TripleTemplateValue::Variable(variable_key(variables, variable))
} }
NamedNodeOrVariable::NamedNode(term) => { NamedNodeOrVariable::NamedNode(term) => TripleTemplateValue::Constant(
TripleTemplateValue::Constant(self.encoder.encode_named_node(term)?) self.encoder.encode_named_node(term).map_err(|e| e.into())?,
} ),
}) })
} }

@ -1,12 +1,15 @@
//! In-memory store. //! In-memory store.
use crate::error::UnwrapInfallible;
use crate::model::*; use crate::model::*;
use crate::sparql::{QueryOptions, QueryResult, SimplePreparedQuery}; use crate::sparql::{QueryOptions, QueryResult, SimplePreparedQuery};
use crate::store::numeric_encoder::*; use crate::store::numeric_encoder::*;
use crate::store::*; use crate::store::*;
use crate::{DatasetSyntax, GraphSyntax, Result}; use crate::Result;
use crate::{DatasetSyntax, GraphSyntax};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::convert::Infallible;
use std::fmt; use std::fmt;
use std::hash::{BuildHasherDefault, Hash, Hasher}; use std::hash::{BuildHasherDefault, Hash, Hasher};
use std::io::BufRead; use std::io::BufRead;
@ -75,7 +78,7 @@ impl MemoryStore {
let mut new = Self { let mut new = Self {
indexes: Arc::new(RwLock::default()), indexes: Arc::new(RwLock::default()),
}; };
new.set_first_strings().unwrap(); new.set_first_strings().unwrap_infallible();
new new
} }
@ -288,15 +291,15 @@ impl MemoryStore {
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub fn insert(&self, quad: Quad) { pub fn insert(&self, quad: Quad) {
let mut store = self; let mut store = self;
let quad = store.encode_quad(&quad).unwrap(); // Could never fail let quad = store.encode_quad(&quad).unwrap_infallible();
store.insert_encoded(&quad).unwrap(); // Could never fail store.insert_encoded(&quad).unwrap_infallible();
} }
/// Removes a quad from this store. /// Removes a quad from this store.
pub fn remove(&self, quad: &Quad) { pub fn remove(&self, quad: &Quad) {
let mut store = self; let mut store = self;
let quad = quad.into(); let quad = quad.into();
store.remove_encoded(&quad).unwrap(); // Could never fail store.remove_encoded(&quad).unwrap_infallible();
} }
/// Returns if the current dataset is [isomorphic](https://www.w3.org/TR/rdf11-concepts/#dfn-dataset-isomorphism) with another one. /// Returns if the current dataset is [isomorphic](https://www.w3.org/TR/rdf11-concepts/#dfn-dataset-isomorphism) with another one.
@ -595,33 +598,43 @@ impl MemoryStore {
} }
impl StrLookup for MemoryStore { impl StrLookup for MemoryStore {
fn get_str(&self, id: StrHash) -> Result<Option<String>> { type Error = Infallible;
fn get_str(&self, id: StrHash) -> std::result::Result<Option<String>, Infallible> {
//TODO: avoid copy by adding a lifetime limit to get_str //TODO: avoid copy by adding a lifetime limit to get_str
self.indexes().get_str(id) self.indexes().get_str(id)
} }
} }
impl StrLookup for MemoryStoreIndexes { impl StrLookup for MemoryStoreIndexes {
fn get_str(&self, id: StrHash) -> Result<Option<String>> { type Error = Infallible;
fn get_str(&self, id: StrHash) -> std::result::Result<Option<String>, Infallible> {
//TODO: avoid copy by adding a lifetime limit to get_str //TODO: avoid copy by adding a lifetime limit to get_str
Ok(self.id2str.get(&id).cloned()) Ok(self.id2str.get(&id).cloned())
} }
} }
impl StrContainer for MemoryStore { impl StrContainer for MemoryStore {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { type Error = Infallible;
fn insert_str(&mut self, key: StrHash, value: &str) -> std::result::Result<(), Infallible> {
self.indexes_mut().insert_str(key, value) self.indexes_mut().insert_str(key, value)
} }
} }
impl<'a> StrContainer for &'a MemoryStore { impl<'a> StrContainer for &'a MemoryStore {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { type Error = Infallible;
fn insert_str(&mut self, key: StrHash, value: &str) -> std::result::Result<(), Infallible> {
self.indexes_mut().insert_str(key, value) self.indexes_mut().insert_str(key, value)
} }
} }
impl StrContainer for MemoryStoreIndexes { impl StrContainer for MemoryStoreIndexes {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { type Error = Infallible;
fn insert_str(&mut self, key: StrHash, value: &str) -> std::result::Result<(), Infallible> {
self.id2str.entry(key).or_insert_with(|| value.to_owned()); self.id2str.entry(key).or_insert_with(|| value.to_owned());
Ok(()) Ok(())
} }
@ -644,27 +657,33 @@ impl<'a> ReadableEncodedStore for MemoryStore {
} }
impl WritableEncodedStore for MemoryStore { impl WritableEncodedStore for MemoryStore {
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { type Error = Infallible;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
self.indexes_mut().insert_encoded(quad) self.indexes_mut().insert_encoded(quad)
} }
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn remove_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
self.indexes_mut().remove_encoded(quad) self.indexes_mut().remove_encoded(quad)
} }
} }
impl<'a> WritableEncodedStore for &'a MemoryStore { impl<'a> WritableEncodedStore for &'a MemoryStore {
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { type Error = Infallible;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
self.indexes_mut().insert_encoded(quad) self.indexes_mut().insert_encoded(quad)
} }
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn remove_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
self.indexes_mut().remove_encoded(quad) self.indexes_mut().remove_encoded(quad)
} }
} }
impl WritableEncodedStore for MemoryStoreIndexes { impl WritableEncodedStore for MemoryStoreIndexes {
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { type Error = Infallible;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
insert_into_quad_map( insert_into_quad_map(
&mut self.gosp, &mut self.gosp,
quad.graph_name, quad.graph_name,
@ -710,7 +729,7 @@ impl WritableEncodedStore for MemoryStoreIndexes {
Ok(()) Ok(())
} }
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn remove_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
remove_from_quad_map( remove_from_quad_map(
&mut self.gosp, &mut self.gosp,
&quad.graph_name, &quad.graph_name,
@ -921,14 +940,14 @@ impl<'a> MemoryTransaction<'a> {
/// Adds a quad to this store during the transaction. /// Adds a quad to this store during the transaction.
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub fn insert(&mut self, quad: Quad) { pub fn insert(&mut self, quad: Quad) {
let quad = self.encode_quad(&quad).unwrap(); // Could never fail let quad = self.encode_quad(&quad).unwrap_infallible();
self.insert_encoded(&quad).unwrap(); // Could never fail self.insert_encoded(&quad).unwrap_infallible();
} }
/// Removes a quad from this store during the transaction. /// Removes a quad from this store during the transaction.
pub fn remove(&mut self, quad: &Quad) { pub fn remove(&mut self, quad: &Quad) {
let quad = quad.into(); let quad = quad.into();
self.remove_encoded(&quad).unwrap(); // Could never fail self.remove_encoded(&quad).unwrap_infallible();
} }
fn commit(self) -> Result<()> { fn commit(self) -> Result<()> {
@ -945,19 +964,23 @@ impl<'a> MemoryTransaction<'a> {
} }
impl StrContainer for MemoryTransaction<'_> { impl StrContainer for MemoryTransaction<'_> {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { type Error = Infallible;
fn insert_str(&mut self, key: StrHash, value: &str) -> std::result::Result<(), Infallible> {
self.strings.push((key, value.to_owned())); self.strings.push((key, value.to_owned()));
Ok(()) Ok(())
} }
} }
impl WritableEncodedStore for MemoryTransaction<'_> { impl WritableEncodedStore for MemoryTransaction<'_> {
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { type Error = Infallible;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
self.ops.push(TransactionOp::Insert(*quad)); self.ops.push(TransactionOp::Insert(*quad));
Ok(()) Ok(())
} }
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn remove_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
self.ops.push(TransactionOp::Delete(*quad)); self.ops.push(TransactionOp::Delete(*quad));
Ok(()) Ok(())
} }

@ -38,9 +38,17 @@ pub(crate) trait ReadableEncodedStore: StrLookup {
} }
pub(crate) trait WritableEncodedStore: StrContainer { pub(crate) trait WritableEncodedStore: StrContainer {
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()>; type Error: From<<Self as StrContainer>::Error> + std::error::Error + Into<Error>;
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()>; fn insert_encoded(
&mut self,
quad: &EncodedQuad,
) -> std::result::Result<(), <Self as WritableEncodedStore>::Error>;
fn remove_encoded(
&mut self,
quad: &EncodedQuad,
) -> std::result::Result<(), <Self as WritableEncodedStore>::Error>;
} }
fn load_graph<S: WritableEncodedStore>( fn load_graph<S: WritableEncodedStore>(
@ -73,10 +81,14 @@ where
Error: From<P::Error>, Error: From<P::Error>,
{ {
let mut bnode_map = HashMap::default(); let mut bnode_map = HashMap::default();
let to_graph_name = store.encode_graph_name(to_graph_name)?; let to_graph_name = store
.encode_graph_name(to_graph_name)
.map_err(|e| e.into())?;
parser.parse_all(&mut move |t| { parser.parse_all(&mut move |t| {
let quad = store.encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map)?; let quad = store
store.insert_encoded(&quad) .encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map)
.map_err(|e| e.into())?;
store.insert_encoded(&quad).map_err(|e| e.into())
}) })
} }
@ -102,7 +114,9 @@ where
{ {
let mut bnode_map = HashMap::default(); let mut bnode_map = HashMap::default();
parser.parse_all(&mut move |q| { parser.parse_all(&mut move |q| {
let quad = store.encode_rio_quad(q, &mut bnode_map)?; let quad = store
store.insert_encoded(&quad) .encode_rio_quad(q, &mut bnode_map)
.map_err(|e| e.into())?;
store.insert_encoded(&quad).map_err(|e| e.into())
}) })
} }

@ -1,15 +1,17 @@
#![allow(clippy::unreadable_literal)] #![allow(clippy::unreadable_literal)]
use crate::error::UnwrapInfallible;
use crate::model::vocab::rdf; use crate::model::vocab::rdf;
use crate::model::vocab::xsd; use crate::model::vocab::xsd;
use crate::model::xsd::*; use crate::model::xsd::*;
use crate::model::*; use crate::model::*;
use crate::Error; use crate::{Error as OxError, Result as OxResult};
use crate::Result;
use rand::random; use rand::random;
use rio_api::model as rio; use rio_api::model as rio;
use siphasher::sip128::{Hasher128, SipHasher24}; use siphasher::sip128::{Hasher128, SipHasher24};
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::Infallible;
use std::error::Error;
use std::hash::Hash; use std::hash::Hash;
use std::hash::Hasher; use std::hash::Hasher;
use std::io::{Cursor, Error as IoError, ErrorKind, Read, Result as IoResult}; use std::io::{Cursor, Error as IoError, ErrorKind, Read, Result as IoResult};
@ -923,14 +925,18 @@ impl QuadEncoding {
} }
pub trait StrLookup { pub trait StrLookup {
fn get_str(&self, id: StrHash) -> Result<Option<String>>; type Error: Error + Into<OxError>;
fn get_str(&self, id: StrHash) -> Result<Option<String>, Self::Error>;
} }
pub trait StrContainer { pub trait StrContainer {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()>; type Error: Error + Into<OxError>;
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<(), Self::Error>;
/// Should be called when the bytes store is created /// Should be called when the bytes store is created
fn set_first_strings(&mut self) -> Result<()> { fn set_first_strings(&mut self) -> Result<(), Self::Error> {
self.insert_str(EMPTY_STRING_ID, "")?; self.insert_str(EMPTY_STRING_ID, "")?;
self.insert_str(RDF_LANG_STRING_ID, rdf::LANG_STRING.as_str())?; self.insert_str(RDF_LANG_STRING_ID, rdf::LANG_STRING.as_str())?;
self.insert_str(XSD_STRING_ID, xsd::STRING.as_str())?; self.insert_str(XSD_STRING_ID, xsd::STRING.as_str())?;
@ -961,44 +967,53 @@ impl Default for MemoryStrStore {
let mut new = Self { let mut new = Self {
id2str: HashMap::default(), id2str: HashMap::default(),
}; };
new.set_first_strings().unwrap(); new.set_first_strings().unwrap_infallible();
new new
} }
} }
impl StrLookup for MemoryStrStore { impl StrLookup for MemoryStrStore {
fn get_str(&self, id: StrHash) -> Result<Option<String>> { type Error = Infallible;
fn get_str(&self, id: StrHash) -> Result<Option<String>, Infallible> {
//TODO: avoid copy by adding a lifetime limit to get_str //TODO: avoid copy by adding a lifetime limit to get_str
Ok(self.id2str.get(&id).cloned()) Ok(self.id2str.get(&id).cloned())
} }
} }
impl StrContainer for MemoryStrStore { impl StrContainer for MemoryStrStore {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { type Error = Infallible;
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<(), Infallible> {
self.id2str.entry(key).or_insert_with(|| value.to_owned()); self.id2str.entry(key).or_insert_with(|| value.to_owned());
Ok(()) Ok(())
} }
} }
pub trait Encoder { pub trait Encoder {
fn encode_named_node(&mut self, named_node: &NamedNode) -> Result<EncodedTerm> { type Error: Error + Into<OxError>;
fn encode_named_node(&mut self, named_node: &NamedNode) -> Result<EncodedTerm, Self::Error> {
self.encode_rio_named_node(named_node.into()) self.encode_rio_named_node(named_node.into())
} }
fn encode_blank_node(&mut self, blank_node: &BlankNode) -> Result<EncodedTerm>; fn encode_blank_node(&mut self, blank_node: &BlankNode) -> Result<EncodedTerm, Self::Error>;
fn encode_literal(&mut self, literal: &Literal) -> Result<EncodedTerm> { fn encode_literal(&mut self, literal: &Literal) -> Result<EncodedTerm, Self::Error> {
self.encode_rio_literal(literal.into()) self.encode_rio_literal(literal.into())
} }
fn encode_named_or_blank_node(&mut self, term: &NamedOrBlankNode) -> Result<EncodedTerm> { fn encode_named_or_blank_node(
&mut self,
term: &NamedOrBlankNode,
) -> Result<EncodedTerm, Self::Error> {
match term { match term {
NamedOrBlankNode::NamedNode(named_node) => self.encode_named_node(named_node), NamedOrBlankNode::NamedNode(named_node) => self.encode_named_node(named_node),
NamedOrBlankNode::BlankNode(blank_node) => self.encode_blank_node(blank_node), NamedOrBlankNode::BlankNode(blank_node) => self.encode_blank_node(blank_node),
} }
} }
fn encode_term(&mut self, term: &Term) -> Result<EncodedTerm> { fn encode_term(&mut self, term: &Term) -> Result<EncodedTerm, Self::Error> {
match term { match term {
Term::NamedNode(named_node) => self.encode_named_node(named_node), Term::NamedNode(named_node) => self.encode_named_node(named_node),
Term::BlankNode(blank_node) => self.encode_blank_node(blank_node), Term::BlankNode(blank_node) => self.encode_blank_node(blank_node),
@ -1006,7 +1021,7 @@ pub trait Encoder {
} }
} }
fn encode_graph_name(&mut self, name: &GraphName) -> Result<EncodedTerm> { fn encode_graph_name(&mut self, name: &GraphName) -> Result<EncodedTerm, Self::Error> {
match name { match name {
GraphName::NamedNode(named_node) => self.encode_named_node(named_node), GraphName::NamedNode(named_node) => self.encode_named_node(named_node),
GraphName::BlankNode(blank_node) => self.encode_blank_node(blank_node), GraphName::BlankNode(blank_node) => self.encode_blank_node(blank_node),
@ -1014,7 +1029,7 @@ pub trait Encoder {
} }
} }
fn encode_quad(&mut self, quad: &Quad) -> Result<EncodedQuad> { fn encode_quad(&mut self, quad: &Quad) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(&quad.subject)?, subject: self.encode_named_or_blank_node(&quad.subject)?,
predicate: self.encode_named_node(&quad.predicate)?, predicate: self.encode_named_node(&quad.predicate)?,
@ -1027,7 +1042,7 @@ pub trait Encoder {
&mut self, &mut self,
triple: &Triple, triple: &Triple,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<EncodedQuad> { ) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(&triple.subject)?, subject: self.encode_named_or_blank_node(&triple.subject)?,
predicate: self.encode_named_node(&triple.predicate)?, predicate: self.encode_named_node(&triple.predicate)?,
@ -1036,21 +1051,25 @@ pub trait Encoder {
}) })
} }
fn encode_rio_named_node(&mut self, named_node: rio::NamedNode<'_>) -> Result<EncodedTerm>; fn encode_rio_named_node(
&mut self,
named_node: rio::NamedNode<'_>,
) -> Result<EncodedTerm, Self::Error>;
fn encode_rio_blank_node( fn encode_rio_blank_node(
&mut self, &mut self,
blank_node: rio::BlankNode<'_>, blank_node: rio::BlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm>; ) -> Result<EncodedTerm, Self::Error>;
fn encode_rio_literal(&mut self, literal: rio::Literal<'_>) -> Result<EncodedTerm>; fn encode_rio_literal(&mut self, literal: rio::Literal<'_>)
-> Result<EncodedTerm, Self::Error>;
fn encode_rio_named_or_blank_node( fn encode_rio_named_or_blank_node(
&mut self, &mut self,
term: rio::NamedOrBlankNode<'_>, term: rio::NamedOrBlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm> { ) -> Result<EncodedTerm, Self::Error> {
match term { match term {
rio::NamedOrBlankNode::NamedNode(named_node) => self.encode_rio_named_node(named_node), rio::NamedOrBlankNode::NamedNode(named_node) => self.encode_rio_named_node(named_node),
rio::NamedOrBlankNode::BlankNode(blank_node) => { rio::NamedOrBlankNode::BlankNode(blank_node) => {
@ -1063,7 +1082,7 @@ pub trait Encoder {
&mut self, &mut self,
term: rio::Term<'_>, term: rio::Term<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm> { ) -> Result<EncodedTerm, Self::Error> {
match term { match term {
rio::Term::NamedNode(named_node) => self.encode_rio_named_node(named_node), rio::Term::NamedNode(named_node) => self.encode_rio_named_node(named_node),
rio::Term::BlankNode(blank_node) => self.encode_rio_blank_node(blank_node, bnodes_map), rio::Term::BlankNode(blank_node) => self.encode_rio_blank_node(blank_node, bnodes_map),
@ -1075,7 +1094,7 @@ pub trait Encoder {
&mut self, &mut self,
quad: rio::Quad<'_>, quad: rio::Quad<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedQuad> { ) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_rio_named_or_blank_node(quad.subject, bnodes_map)?, subject: self.encode_rio_named_or_blank_node(quad.subject, bnodes_map)?,
predicate: self.encode_rio_named_node(quad.predicate)?, predicate: self.encode_rio_named_node(quad.predicate)?,
@ -1092,7 +1111,7 @@ pub trait Encoder {
triple: rio::Triple<'_>, triple: rio::Triple<'_>,
graph_name: EncodedTerm, graph_name: EncodedTerm,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedQuad> { ) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_rio_named_or_blank_node(triple.subject, bnodes_map)?, subject: self.encode_rio_named_or_blank_node(triple.subject, bnodes_map)?,
predicate: self.encode_rio_named_node(triple.predicate)?, predicate: self.encode_rio_named_node(triple.predicate)?,
@ -1103,13 +1122,18 @@ pub trait Encoder {
} }
impl<S: StrContainer> Encoder for S { impl<S: StrContainer> Encoder for S {
fn encode_rio_named_node(&mut self, named_node: rio::NamedNode<'_>) -> Result<EncodedTerm> { type Error = S::Error;
fn encode_rio_named_node(
&mut self,
named_node: rio::NamedNode<'_>,
) -> Result<EncodedTerm, Self::Error> {
let iri_id = StrHash::new(named_node.iri); let iri_id = StrHash::new(named_node.iri);
self.insert_str(iri_id, named_node.iri)?; self.insert_str(iri_id, named_node.iri)?;
Ok(EncodedTerm::NamedNode { iri_id }) Ok(EncodedTerm::NamedNode { iri_id })
} }
fn encode_blank_node(&mut self, blank_node: &BlankNode) -> Result<EncodedTerm> { fn encode_blank_node(&mut self, blank_node: &BlankNode) -> Result<EncodedTerm, Self::Error> {
if let Some(id) = blank_node.id() { if let Some(id) = blank_node.id() {
Ok(EncodedTerm::InlineBlankNode { id }) Ok(EncodedTerm::InlineBlankNode { id })
} else { } else {
@ -1124,7 +1148,7 @@ impl<S: StrContainer> Encoder for S {
&mut self, &mut self,
blank_node: rio::BlankNode<'_>, blank_node: rio::BlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm> { ) -> Result<EncodedTerm, Self::Error> {
Ok(if let Some(id) = bnodes_map.get(blank_node.id) { Ok(if let Some(id) = bnodes_map.get(blank_node.id) {
EncodedTerm::InlineBlankNode { id: *id } EncodedTerm::InlineBlankNode { id: *id }
} else { } else {
@ -1134,7 +1158,10 @@ impl<S: StrContainer> Encoder for S {
}) })
} }
fn encode_rio_literal(&mut self, literal: rio::Literal<'_>) -> Result<EncodedTerm> { fn encode_rio_literal(
&mut self,
literal: rio::Literal<'_>,
) -> Result<EncodedTerm, Self::Error> {
Ok(match literal { Ok(match literal {
rio::Literal::Simple { value } => { rio::Literal::Simple { value } => {
let value_id = StrHash::new(value); let value_id = StrHash::new(value);
@ -1261,31 +1288,31 @@ pub fn parse_day_time_duration_str(value: &str) -> Option<EncodedTerm> {
} }
pub trait Decoder { pub trait Decoder {
fn decode_term(&self, encoded: EncodedTerm) -> Result<Term>; fn decode_term(&self, encoded: EncodedTerm) -> OxResult<Term>;
fn decode_named_or_blank_node(&self, encoded: EncodedTerm) -> Result<NamedOrBlankNode> { fn decode_named_or_blank_node(&self, encoded: EncodedTerm) -> OxResult<NamedOrBlankNode> {
match self.decode_term(encoded)? { match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node.into()), Term::NamedNode(named_node) => Ok(named_node.into()),
Term::BlankNode(blank_node) => Ok(blank_node.into()), Term::BlankNode(blank_node) => Ok(blank_node.into()),
Term::Literal(_) => Err(Error::msg( Term::Literal(_) => Err(OxError::msg(
"A literal has ben found instead of a named node", "A literal has ben found instead of a named node",
)), )),
} }
} }
fn decode_named_node(&self, encoded: EncodedTerm) -> Result<NamedNode> { fn decode_named_node(&self, encoded: EncodedTerm) -> OxResult<NamedNode> {
match self.decode_term(encoded)? { match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node), Term::NamedNode(named_node) => Ok(named_node),
Term::BlankNode(_) => Err(Error::msg( Term::BlankNode(_) => Err(OxError::msg(
"A blank node has been found instead of a named node", "A blank node has been found instead of a named node",
)), )),
Term::Literal(_) => Err(Error::msg( Term::Literal(_) => Err(OxError::msg(
"A literal has ben found instead of a named node", "A literal has ben found instead of a named node",
)), )),
} }
} }
fn decode_triple(&self, encoded: &EncodedQuad) -> Result<Triple> { fn decode_triple(&self, encoded: &EncodedQuad) -> OxResult<Triple> {
Ok(Triple::new( Ok(Triple::new(
self.decode_named_or_blank_node(encoded.subject)?, self.decode_named_or_blank_node(encoded.subject)?,
self.decode_named_node(encoded.predicate)?, self.decode_named_node(encoded.predicate)?,
@ -1293,7 +1320,7 @@ pub trait Decoder {
)) ))
} }
fn decode_quad(&self, encoded: &EncodedQuad) -> Result<Quad> { fn decode_quad(&self, encoded: &EncodedQuad) -> OxResult<Quad> {
Ok(Quad::new( Ok(Quad::new(
self.decode_named_or_blank_node(encoded.subject)?, self.decode_named_or_blank_node(encoded.subject)?,
self.decode_named_node(encoded.predicate)?, self.decode_named_node(encoded.predicate)?,
@ -1307,10 +1334,10 @@ pub trait Decoder {
} }
impl<S: StrLookup> Decoder for S { impl<S: StrLookup> Decoder for S {
fn decode_term(&self, encoded: EncodedTerm) -> Result<Term> { fn decode_term(&self, encoded: EncodedTerm) -> OxResult<Term> {
match encoded { match encoded {
EncodedTerm::DefaultGraph => { EncodedTerm::DefaultGraph => {
Err(Error::msg("The default graph tag is not a valid term")) Err(OxError::msg("The default graph tag is not a valid term"))
} }
EncodedTerm::NamedNode { iri_id } => { EncodedTerm::NamedNode { iri_id } => {
Ok(NamedNode::new_unchecked(get_required_str(self, iri_id)?).into()) Ok(NamedNode::new_unchecked(get_required_str(self, iri_id)?).into())
@ -1353,9 +1380,9 @@ impl<S: StrLookup> Decoder for S {
} }
} }
fn get_required_str(lookup: &impl StrLookup, id: StrHash) -> Result<String> { fn get_required_str(lookup: &impl StrLookup, id: StrHash) -> OxResult<String> {
lookup.get_str(id)?.ok_or_else(|| { lookup.get_str(id).map_err(|e| e.into())?.ok_or_else(|| {
Error::msg(format!( OxError::msg(format!(
"Not able to find the string with id {:?} in the string store", "Not able to find the string with id {:?} in the string store",
id id
)) ))

@ -260,6 +260,8 @@ impl fmt::Display for RocksDbStore {
} }
impl StrLookup for RocksDbStore { impl StrLookup for RocksDbStore {
type Error = crate::Error;
fn get_str(&self, id: StrHash) -> Result<Option<String>> { fn get_str(&self, id: StrHash) -> Result<Option<String>> {
Ok(self Ok(self
.db .db
@ -534,6 +536,8 @@ pub struct RocksDbTransaction<'a> {
} }
impl StrContainer for RocksDbTransaction<'_> { impl StrContainer for RocksDbTransaction<'_> {
type Error = crate::Error;
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> {
self.inner.insert_str(key, value); self.inner.insert_str(key, value);
Ok(()) Ok(())
@ -541,6 +545,8 @@ impl StrContainer for RocksDbTransaction<'_> {
} }
impl WritableEncodedStore for RocksDbTransaction<'_> { impl WritableEncodedStore for RocksDbTransaction<'_> {
type Error = crate::Error;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> {
self.inner.insert(quad) self.inner.insert(quad)
} }
@ -606,6 +612,8 @@ struct RocksDbAutoTransaction<'a> {
} }
impl StrContainer for RocksDbAutoTransaction<'_> { impl StrContainer for RocksDbAutoTransaction<'_> {
type Error = crate::Error;
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> {
self.inner.insert_str(key, value); self.inner.insert_str(key, value);
Ok(()) Ok(())
@ -613,6 +621,8 @@ impl StrContainer for RocksDbAutoTransaction<'_> {
} }
impl WritableEncodedStore for RocksDbAutoTransaction<'_> { impl WritableEncodedStore for RocksDbAutoTransaction<'_> {
type Error = crate::Error;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> {
self.inner.insert(quad)?; self.inner.insert(quad)?;
self.commit_if_big() self.commit_if_big()

@ -414,6 +414,8 @@ impl fmt::Display for SledStore {
} }
impl StrLookup for SledStore { impl StrLookup for SledStore {
type Error = Error;
fn get_str(&self, id: StrHash) -> Result<Option<String>> { fn get_str(&self, id: StrHash) -> Result<Option<String>> {
Ok(self Ok(self
.id2str .id2str
@ -436,6 +438,8 @@ impl ReadableEncodedStore for SledStore {
} }
impl<'a> StrContainer for &'a SledStore { impl<'a> StrContainer for &'a SledStore {
type Error = Error;
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> { fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> {
self.id2str.insert(key.to_be_bytes(), value)?; self.id2str.insert(key.to_be_bytes(), value)?;
Ok(()) Ok(())
@ -443,6 +447,8 @@ impl<'a> StrContainer for &'a SledStore {
} }
impl<'a> WritableEncodedStore for &'a SledStore { impl<'a> WritableEncodedStore for &'a SledStore {
type Error = Error;
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> { fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()> {
//TODO: atomicity //TODO: atomicity
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE); let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE);

Loading…
Cancel
Save