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 rio_turtle::TurtleError;
use rio_xml::RdfXmlError;
use std::convert::Infallible;
use std::error;
use std::fmt;
use std::io;
@ -71,6 +72,12 @@ enum ErrorKind {
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 {
fn from(error: io::Error) -> Self {
Self {
@ -148,3 +155,21 @@ impl From<sled::Error> for 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(
variable,
variables,
encoder.encode_term(term)?,
encoder.encode_term(term).map_err(|e| e.into())?,
&mut encoded_terms,
)
}

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

@ -238,9 +238,9 @@ impl<E: Encoder> PlanBuilder<E> {
fn build_for_path(&mut self, path: &PropertyPath) -> Result<PlanPropertyPath> {
Ok(match path {
PropertyPath::PredicatePath(p) => {
PlanPropertyPath::PredicatePath(self.encoder.encode_named_node(p)?)
}
PropertyPath::PredicatePath(p) => PlanPropertyPath::PredicatePath(
self.encoder.encode_named_node(p).map_err(|e| e.into())?,
),
PropertyPath::InversePath(p) => {
PlanPropertyPath::InversePath(Box::new(self.build_for_path(p)?))
}
@ -263,7 +263,7 @@ impl<E: Encoder> PlanBuilder<E> {
}
PropertyPath::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet(
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<_>>>()?,
),
})
@ -276,10 +276,12 @@ impl<E: Encoder> PlanBuilder<E> {
graph_name: PatternValue,
) -> Result<PlanExpression> {
Ok(match expression {
Expression::NamedNode(node) => {
PlanExpression::Constant(self.encoder.encode_named_node(node)?)
Expression::NamedNode(node) => PlanExpression::Constant(
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::Or(a, b) => PlanExpression::Or(
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())))
//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>,
) -> Result<PatternValue> {
Ok(match named_node_or_variable {
NamedNodeOrVariable::NamedNode(named_node) => {
PatternValue::Constant(self.encoder.encode_named_node(named_node)?)
}
NamedNodeOrVariable::NamedNode(named_node) => PatternValue::Constant(
self.encoder
.encode_named_node(named_node)
.map_err(|e| e.into())?,
),
NamedNodeOrVariable::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable))
}
@ -765,7 +771,7 @@ impl<E: Encoder> PlanBuilder<E> {
if let Some(term) = value {
result.set(
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))
}
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) => {
TripleTemplateValue::Variable(variable_key(variables, variable))
}
NamedNodeOrVariable::NamedNode(term) => {
TripleTemplateValue::Constant(self.encoder.encode_named_node(term)?)
}
NamedNodeOrVariable::NamedNode(term) => TripleTemplateValue::Constant(
self.encoder.encode_named_node(term).map_err(|e| e.into())?,
),
})
}

@ -1,12 +1,15 @@
//! In-memory store.
use crate::error::UnwrapInfallible;
use crate::model::*;
use crate::sparql::{QueryOptions, QueryResult, SimplePreparedQuery};
use crate::store::numeric_encoder::*;
use crate::store::*;
use crate::{DatasetSyntax, GraphSyntax, Result};
use crate::Result;
use crate::{DatasetSyntax, GraphSyntax};
use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet};
use std::convert::Infallible;
use std::fmt;
use std::hash::{BuildHasherDefault, Hash, Hasher};
use std::io::BufRead;
@ -75,7 +78,7 @@ impl MemoryStore {
let mut new = Self {
indexes: Arc::new(RwLock::default()),
};
new.set_first_strings().unwrap();
new.set_first_strings().unwrap_infallible();
new
}
@ -288,15 +291,15 @@ impl MemoryStore {
#[allow(clippy::needless_pass_by_value)]
pub fn insert(&self, quad: Quad) {
let mut store = self;
let quad = store.encode_quad(&quad).unwrap(); // Could never fail
store.insert_encoded(&quad).unwrap(); // Could never fail
let quad = store.encode_quad(&quad).unwrap_infallible();
store.insert_encoded(&quad).unwrap_infallible();
}
/// Removes a quad from this store.
pub fn remove(&self, quad: &Quad) {
let mut store = self;
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.
@ -595,33 +598,43 @@ impl 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
self.indexes().get_str(id)
}
}
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
Ok(self.id2str.get(&id).cloned())
}
}
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)
}
}
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)
}
}
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());
Ok(())
}
@ -644,27 +657,33 @@ impl<'a> ReadableEncodedStore 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)
}
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)
}
}
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)
}
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)
}
}
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(
&mut self.gosp,
quad.graph_name,
@ -710,7 +729,7 @@ impl WritableEncodedStore for MemoryStoreIndexes {
Ok(())
}
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()> {
fn remove_encoded(&mut self, quad: &EncodedQuad) -> std::result::Result<(), Infallible> {
remove_from_quad_map(
&mut self.gosp,
&quad.graph_name,
@ -921,14 +940,14 @@ impl<'a> MemoryTransaction<'a> {
/// Adds a quad to this store during the transaction.
#[allow(clippy::needless_pass_by_value)]
pub fn insert(&mut self, quad: Quad) {
let quad = self.encode_quad(&quad).unwrap(); // Could never fail
self.insert_encoded(&quad).unwrap(); // Could never fail
let quad = self.encode_quad(&quad).unwrap_infallible();
self.insert_encoded(&quad).unwrap_infallible();
}
/// Removes a quad from this store during the transaction.
pub fn remove(&mut self, quad: &Quad) {
let quad = quad.into();
self.remove_encoded(&quad).unwrap(); // Could never fail
self.remove_encoded(&quad).unwrap_infallible();
}
fn commit(self) -> Result<()> {
@ -945,19 +964,23 @@ impl<'a> MemoryTransaction<'a> {
}
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()));
Ok(())
}
}
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));
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));
Ok(())
}

@ -38,9 +38,17 @@ pub(crate) trait ReadableEncodedStore: StrLookup {
}
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>(
@ -73,10 +81,14 @@ where
Error: From<P::Error>,
{
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| {
let quad = store.encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map)?;
store.insert_encoded(&quad)
let quad = store
.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();
parser.parse_all(&mut move |q| {
let quad = store.encode_rio_quad(q, &mut bnode_map)?;
store.insert_encoded(&quad)
let quad = store
.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)]
use crate::error::UnwrapInfallible;
use crate::model::vocab::rdf;
use crate::model::vocab::xsd;
use crate::model::xsd::*;
use crate::model::*;
use crate::Error;
use crate::Result;
use crate::{Error as OxError, Result as OxResult};
use rand::random;
use rio_api::model as rio;
use siphasher::sip128::{Hasher128, SipHasher24};
use std::collections::HashMap;
use std::convert::Infallible;
use std::error::Error;
use std::hash::Hash;
use std::hash::Hasher;
use std::io::{Cursor, Error as IoError, ErrorKind, Read, Result as IoResult};
@ -923,14 +925,18 @@ impl QuadEncoding {
}
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 {
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
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(RDF_LANG_STRING_ID, rdf::LANG_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 {
id2str: HashMap::default(),
};
new.set_first_strings().unwrap();
new.set_first_strings().unwrap_infallible();
new
}
}
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
Ok(self.id2str.get(&id).cloned())
}
}
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());
Ok(())
}
}
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())
}
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())
}
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 {
NamedOrBlankNode::NamedNode(named_node) => self.encode_named_node(named_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 {
Term::NamedNode(named_node) => self.encode_named_node(named_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 {
GraphName::NamedNode(named_node) => self.encode_named_node(named_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 {
subject: self.encode_named_or_blank_node(&quad.subject)?,
predicate: self.encode_named_node(&quad.predicate)?,
@ -1027,7 +1042,7 @@ pub trait Encoder {
&mut self,
triple: &Triple,
graph_name: EncodedTerm,
) -> Result<EncodedQuad> {
) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(&triple.subject)?,
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(
&mut self,
blank_node: rio::BlankNode<'_>,
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(
&mut self,
term: rio::NamedOrBlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm> {
) -> Result<EncodedTerm, Self::Error> {
match term {
rio::NamedOrBlankNode::NamedNode(named_node) => self.encode_rio_named_node(named_node),
rio::NamedOrBlankNode::BlankNode(blank_node) => {
@ -1063,7 +1082,7 @@ pub trait Encoder {
&mut self,
term: rio::Term<'_>,
bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm> {
) -> Result<EncodedTerm, Self::Error> {
match term {
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),
@ -1075,7 +1094,7 @@ pub trait Encoder {
&mut self,
quad: rio::Quad<'_>,
bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedQuad> {
) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad {
subject: self.encode_rio_named_or_blank_node(quad.subject, bnodes_map)?,
predicate: self.encode_rio_named_node(quad.predicate)?,
@ -1092,7 +1111,7 @@ pub trait Encoder {
triple: rio::Triple<'_>,
graph_name: EncodedTerm,
bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedQuad> {
) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad {
subject: self.encode_rio_named_or_blank_node(triple.subject, bnodes_map)?,
predicate: self.encode_rio_named_node(triple.predicate)?,
@ -1103,13 +1122,18 @@ pub trait Encoder {
}
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);
self.insert_str(iri_id, named_node.iri)?;
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() {
Ok(EncodedTerm::InlineBlankNode { id })
} else {
@ -1124,7 +1148,7 @@ impl<S: StrContainer> Encoder for S {
&mut self,
blank_node: rio::BlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm> {
) -> Result<EncodedTerm, Self::Error> {
Ok(if let Some(id) = bnodes_map.get(blank_node.id) {
EncodedTerm::InlineBlankNode { id: *id }
} 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 {
rio::Literal::Simple { 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 {
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)? {
Term::NamedNode(named_node) => Ok(named_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",
)),
}
}
fn decode_named_node(&self, encoded: EncodedTerm) -> Result<NamedNode> {
fn decode_named_node(&self, encoded: EncodedTerm) -> OxResult<NamedNode> {
match self.decode_term(encoded)? {
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",
)),
Term::Literal(_) => Err(Error::msg(
Term::Literal(_) => Err(OxError::msg(
"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(
self.decode_named_or_blank_node(encoded.subject)?,
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(
self.decode_named_or_blank_node(encoded.subject)?,
self.decode_named_node(encoded.predicate)?,
@ -1307,10 +1334,10 @@ pub trait Decoder {
}
impl<S: StrLookup> Decoder for S {
fn decode_term(&self, encoded: EncodedTerm) -> Result<Term> {
fn decode_term(&self, encoded: EncodedTerm) -> OxResult<Term> {
match encoded {
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 } => {
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> {
lookup.get_str(id)?.ok_or_else(|| {
Error::msg(format!(
fn get_required_str(lookup: &impl StrLookup, id: StrHash) -> OxResult<String> {
lookup.get_str(id).map_err(|e| e.into())?.ok_or_else(|| {
OxError::msg(format!(
"Not able to find the string with id {:?} in the string store",
id
))

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

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

Loading…
Cancel
Save