diff --git a/lib/src/sparql/dataset.rs b/lib/src/sparql/dataset.rs index 5b8fafa4..f8e7e3c1 100644 --- a/lib/src/sparql/dataset.rs +++ b/lib/src/sparql/dataset.rs @@ -4,10 +4,9 @@ use crate::store::numeric_encoder::{ EncodedQuad, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, StrLookup, }; use crate::store::storage::Storage; -use crate::store::ReadableEncodedStore; use std::cell::RefCell; use std::collections::HashMap; -use std::iter::{empty, once, Once}; +use std::iter::empty; pub(crate) struct DatasetView { storage: Storage, @@ -59,37 +58,9 @@ impl DatasetView { .quads_for_pattern(subject, predicate, object, graph_name) .map(|t| t.map_err(|e| e.into())) } -} - -impl StrEncodingAware for DatasetView { - type Error = EvaluationError; -} - -impl StrLookup for DatasetView { - fn get_str(&self, id: StrHash) -> Result, EvaluationError> { - Ok(if let Some(value) = self.extra.borrow().get(&id) { - Some(value.clone()) - } else { - self.storage.get_str(id)? - }) - } - - fn get_str_id(&self, value: &str) -> Result, EvaluationError> { - let id = StrHash::new(value); - Ok(if self.extra.borrow().contains_key(&id) { - Some(id) - } else { - self.storage.get_str_id(value)? - }) - } -} - -impl ReadableEncodedStore for DatasetView { - type QuadsIter = Box>>; - type GraphsIter = Once>; #[allow(clippy::needless_collect)] - fn encoded_quads_for_pattern( + pub fn encoded_quads_for_pattern( &self, subject: Option, predicate: Option, @@ -181,17 +152,28 @@ impl ReadableEncodedStore for DatasetView { ) } } +} - fn encoded_named_graphs(&self) -> Self::GraphsIter { - once(Err(EvaluationError::msg( - "Graphs lookup is not implemented by DatasetView", - ))) +impl StrEncodingAware for DatasetView { + type Error = EvaluationError; +} + +impl StrLookup for DatasetView { + fn get_str(&self, id: StrHash) -> Result, EvaluationError> { + Ok(if let Some(value) = self.extra.borrow().get(&id) { + Some(value.clone()) + } else { + self.storage.get_str(id)? + }) } - fn contains_encoded_named_graph(&self, _: EncodedTerm) -> Result { - Err(EvaluationError::msg( - "Graphs lookup is not implemented by DatasetView", - )) + fn get_str_id(&self, value: &str) -> Result, EvaluationError> { + let id = StrHash::new(value); + Ok(if self.extra.borrow().contains_key(&id) { + Some(id) + } else { + self.storage.get_str_id(value)? + }) } } diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index 7a6b2b21..71202780 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -10,7 +10,6 @@ use crate::sparql::plan::*; use crate::sparql::service::ServiceHandler; use crate::store::numeric_encoder::*; use crate::store::small_string::SmallString; -use crate::store::ReadableEncodedStore; use digest::Digest; use md5::Md5; use oxilangtag::LanguageTag; diff --git a/lib/src/sparql/update.rs b/lib/src/sparql/update.rs index 964dc118..41678a5f 100644 --- a/lib/src/sparql/update.rs +++ b/lib/src/sparql/update.rs @@ -8,7 +8,7 @@ use crate::sparql::http::Client; use crate::sparql::plan::EncodedTuple; use crate::sparql::plan_builder::PlanBuilder; use crate::sparql::{EvaluationError, UpdateOptions}; -use crate::store::load_graph; +use crate::store::io::load_graph; use crate::store::numeric_encoder::{ EncodedQuad, EncodedTerm, ReadEncoder, StrLookup, WriteEncoder, }; diff --git a/lib/src/store/io.rs b/lib/src/store/io.rs new file mode 100644 index 00000000..331addc0 --- /dev/null +++ b/lib/src/store/io.rs @@ -0,0 +1,150 @@ +//! Utilities for I/O from the store + +use crate::error::invalid_input_error; +use crate::io::{DatasetFormat, DatasetSerializer, GraphFormat, GraphSerializer}; +use crate::model::{GraphNameRef, Quad, Triple}; +use crate::store::numeric_encoder::WriteEncoder; +use crate::store::storage::StorageLike; +use oxiri::Iri; +use rio_api::parser::{QuadsParser, TriplesParser}; +use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleError, TurtleParser}; +use rio_xml::{RdfXmlError, RdfXmlParser}; +use std::collections::HashMap; +use std::io; +use std::io::{BufRead, Write}; + +pub(crate) fn load_graph( + storage: &S, + reader: impl BufRead, + format: GraphFormat, + to_graph_name: GraphNameRef<'_>, + base_iri: Option<&str>, +) -> Result<(), StoreOrParseError> { + let base_iri = if let Some(base_iri) = base_iri { + Some(Iri::parse(base_iri.into()).map_err(invalid_input_error)?) + } else { + None + }; + match format { + GraphFormat::NTriples => { + load_from_triple_parser(storage, NTriplesParser::new(reader), to_graph_name) + } + GraphFormat::Turtle => { + load_from_triple_parser(storage, TurtleParser::new(reader, base_iri), to_graph_name) + } + GraphFormat::RdfXml => { + load_from_triple_parser(storage, RdfXmlParser::new(reader, base_iri), to_graph_name) + } + } +} + +fn load_from_triple_parser( + storage: &S, + mut parser: P, + to_graph_name: GraphNameRef<'_>, +) -> Result<(), StoreOrParseError> +where + StoreOrParseError: From, +{ + let mut bnode_map = HashMap::default(); + let to_graph_name = storage + .encode_graph_name(to_graph_name) + .map_err(StoreOrParseError::Store)?; + parser.parse_all(&mut move |t| { + let quad = storage + .encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map) + .map_err(StoreOrParseError::Store)?; + storage.insert(&quad).map_err(StoreOrParseError::Store)?; + Ok(()) + }) +} + +pub fn dump_graph( + triples: impl Iterator>, + writer: impl Write, + format: GraphFormat, +) -> Result<(), io::Error> { + let mut writer = GraphSerializer::from_format(format).triple_writer(writer)?; + for triple in triples { + writer.write(&triple?)?; + } + writer.finish() +} + +pub(crate) fn load_dataset( + store: &S, + reader: impl BufRead, + format: DatasetFormat, + base_iri: Option<&str>, +) -> Result<(), StoreOrParseError> { + let base_iri = if let Some(base_iri) = base_iri { + Some(Iri::parse(base_iri.into()).map_err(invalid_input_error)?) + } else { + None + }; + match format { + DatasetFormat::NQuads => load_from_quad_parser(store, NQuadsParser::new(reader)), + DatasetFormat::TriG => load_from_quad_parser(store, TriGParser::new(reader, base_iri)), + } +} + +fn load_from_quad_parser( + store: &S, + mut parser: P, +) -> Result<(), StoreOrParseError> +where + StoreOrParseError: From, +{ + let mut bnode_map = HashMap::default(); + parser.parse_all(&mut move |q| { + let quad = store + .encode_rio_quad(q, &mut bnode_map) + .map_err(StoreOrParseError::Store)?; + store.insert(&quad).map_err(StoreOrParseError::Store)?; + Ok(()) + }) +} + +pub fn dump_dataset( + quads: impl Iterator>, + writer: impl Write, + format: DatasetFormat, +) -> Result<(), io::Error> { + let mut writer = DatasetSerializer::from_format(format).quad_writer(writer)?; + for quad in quads { + writer.write(&quad?)?; + } + writer.finish() +} + +pub(crate) enum StoreOrParseError { + Store(S), + Parse(io::Error), +} + +impl From for StoreOrParseError { + fn from(error: TurtleError) -> Self { + Self::Parse(error.into()) + } +} + +impl From for StoreOrParseError { + fn from(error: RdfXmlError) -> Self { + Self::Parse(error.into()) + } +} + +impl From for StoreOrParseError { + fn from(error: io::Error) -> Self { + Self::Parse(error) + } +} + +impl From> for io::Error { + fn from(error: StoreOrParseError) -> Self { + match error { + StoreOrParseError::Store(error) => error, + StoreOrParseError::Parse(error) => error, + } + } +} diff --git a/lib/src/store/mod.rs b/lib/src/store/mod.rs index 3a243922..58286034 100644 --- a/lib/src/store/mod.rs +++ b/lib/src/store/mod.rs @@ -1,262 +1,12 @@ //! RDF [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) storage implementations. +pub use crate::store::sled::SledStore; + mod binary_encoder; +pub(crate) mod io; pub(crate) mod numeric_encoder; pub mod sled; pub(crate) mod small_string; #[cfg(feature = "sophia")] mod sophia; pub(crate) mod storage; - -pub use crate::store::sled::SledStore; - -use crate::error::invalid_input_error; -use crate::io::{DatasetFormat, DatasetSerializer, GraphFormat, GraphSerializer}; -use crate::model::*; -use crate::store::numeric_encoder::*; -use crate::store::storage::StorageLike; -use oxiri::Iri; -use rio_api::parser::{QuadsParser, TriplesParser}; -use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleError, TurtleParser}; -use rio_xml::{RdfXmlError, RdfXmlParser}; -use std::collections::HashMap; -use std::convert::Infallible; -use std::io; -use std::io::{BufRead, Write}; -use std::iter::Iterator; - -pub(crate) trait ReadableEncodedStore: StrLookup { - type QuadsIter: Iterator> + 'static; - type GraphsIter: Iterator> + 'static; - - fn encoded_quads_for_pattern( - &self, - subject: Option, - predicate: Option, - object: Option, - graph_name: Option, - ) -> Self::QuadsIter; - - fn encoded_named_graphs(&self) -> Self::GraphsIter; - - fn contains_encoded_named_graph(&self, graph_name: EncodedTerm) -> Result; -} - -pub(crate) trait WritableEncodedStore: StrEncodingAware { - fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<(), Self::Error>; - - fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<(), Self::Error>; - - fn insert_encoded_named_graph(&mut self, graph_name: EncodedTerm) -> Result<(), Self::Error>; - - fn clear_encoded_graph(&mut self, graph_name: EncodedTerm) -> Result<(), Self::Error>; - - fn remove_encoded_named_graph(&mut self, graph_name: EncodedTerm) -> Result<(), Self::Error>; - - fn clear(&mut self) -> Result<(), Self::Error>; -} - -pub(crate) fn load_graph( - storage: &S, - reader: impl BufRead, - format: GraphFormat, - to_graph_name: GraphNameRef<'_>, - base_iri: Option<&str>, -) -> Result<(), StoreOrParseError> { - let base_iri = if let Some(base_iri) = base_iri { - Some(Iri::parse(base_iri.into()).map_err(invalid_input_error)?) - } else { - None - }; - match format { - GraphFormat::NTriples => { - load_from_triple_parser(storage, NTriplesParser::new(reader), to_graph_name) - } - GraphFormat::Turtle => { - load_from_triple_parser(storage, TurtleParser::new(reader, base_iri), to_graph_name) - } - GraphFormat::RdfXml => { - load_from_triple_parser(storage, RdfXmlParser::new(reader, base_iri), to_graph_name) - } - } -} - -fn load_from_triple_parser( - storage: &S, - mut parser: P, - to_graph_name: GraphNameRef<'_>, -) -> Result<(), StoreOrParseError> -where - StoreOrParseError: From, -{ - let mut bnode_map = HashMap::default(); - let to_graph_name = storage - .encode_graph_name(to_graph_name) - .map_err(StoreOrParseError::Store)?; - parser.parse_all(&mut move |t| { - let quad = storage - .encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map) - .map_err(StoreOrParseError::Store)?; - storage.insert(&quad).map_err(StoreOrParseError::Store)?; - Ok(()) - }) -} - -fn dump_graph( - triples: impl Iterator>, - writer: impl Write, - format: GraphFormat, -) -> Result<(), io::Error> { - let mut writer = GraphSerializer::from_format(format).triple_writer(writer)?; - for triple in triples { - writer.write(&triple?)?; - } - writer.finish() -} - -fn load_dataset( - store: &mut S, - reader: impl BufRead, - format: DatasetFormat, - base_iri: Option<&str>, -) -> Result<(), StoreOrParseError> { - let base_iri = if let Some(base_iri) = base_iri { - Some(Iri::parse(base_iri.into()).map_err(invalid_input_error)?) - } else { - None - }; - match format { - DatasetFormat::NQuads => load_from_quad_parser(store, NQuadsParser::new(reader)), - DatasetFormat::TriG => load_from_quad_parser(store, TriGParser::new(reader, base_iri)), - } -} - -fn load_from_quad_parser( - store: &mut S, - mut parser: P, -) -> Result<(), StoreOrParseError> -where - StoreOrParseError: From, -{ - let mut bnode_map = HashMap::default(); - parser.parse_all(&mut move |q| { - let quad = store - .encode_rio_quad(q, &mut bnode_map) - .map_err(StoreOrParseError::Store)?; - store - .insert_encoded(&quad) - .map_err(StoreOrParseError::Store)?; - Ok(()) - }) -} - -fn dump_dataset( - quads: impl Iterator>, - writer: impl Write, - format: DatasetFormat, -) -> Result<(), io::Error> { - let mut writer = DatasetSerializer::from_format(format).quad_writer(writer)?; - for quad in quads { - writer.write(&quad?)?; - } - writer.finish() -} - -pub(crate) enum StoreOrParseError { - Store(S), - Parse(io::Error), -} - -impl From for StoreOrParseError { - fn from(error: TurtleError) -> Self { - Self::Parse(error.into()) - } -} - -impl From for StoreOrParseError { - fn from(error: RdfXmlError) -> Self { - Self::Parse(error.into()) - } -} - -impl From for StoreOrParseError { - fn from(error: io::Error) -> Self { - Self::Parse(error) - } -} - -impl From> for io::Error { - fn from(error: StoreOrParseError) -> Self { - match error { - StoreOrParseError::Store(error) => error, - StoreOrParseError::Parse(error) => error, - } - } -} - -impl From> for io::Error { - fn from(error: StoreOrParseError) -> Self { - match error { - StoreOrParseError::Store(error) => match error {}, - StoreOrParseError::Parse(error) => error, - } - } -} - -type QuadPattern = ( - Option, - Option, - Option, - Option, -); - -fn get_encoded_quad_pattern( - encoder: &E, - subject: Option>, - predicate: Option>, - object: Option>, - graph_name: Option>, -) -> Result, E::Error> { - Ok(Some(( - if let Some(subject) = transpose( - subject - .map(|t| encoder.get_encoded_named_or_blank_node(t)) - .transpose()?, - ) { - subject - } else { - return Ok(None); - }, - if let Some(predicate) = transpose( - predicate - .map(|t| encoder.get_encoded_named_node(t)) - .transpose()?, - ) { - predicate - } else { - return Ok(None); - }, - if let Some(object) = transpose(object.map(|t| encoder.get_encoded_term(t)).transpose()?) { - object - } else { - return Ok(None); - }, - if let Some(graph_name) = transpose( - graph_name - .map(|t| encoder.get_encoded_graph_name(t)) - .transpose()?, - ) { - graph_name - } else { - return Ok(None); - }, - ))) -} - -fn transpose(o: Option>) -> Option> { - match o { - Some(Some(v)) => Some(Some(v)), - Some(None) => None, - None => Some(None), - } -} diff --git a/lib/src/store/sled.rs b/lib/src/store/sled.rs index a25facd8..c79e8c3b 100644 --- a/lib/src/store/sled.rs +++ b/lib/src/store/sled.rs @@ -1,28 +1,26 @@ //! Store based on the [Sled](https://sled.rs/) key-value database. +use std::convert::TryInto; +use std::io::{BufRead, Write}; +use std::iter::{once, Once}; +use std::path::Path; +use std::{fmt, io, str}; + use crate::io::{DatasetFormat, GraphFormat}; use crate::model::*; use crate::sparql::{ evaluate_query, evaluate_update, EvaluationError, Query, QueryOptions, QueryResults, Update, UpdateOptions, }; +use crate::store::io::{dump_dataset, dump_graph, load_dataset, load_graph}; use crate::store::numeric_encoder::{ - Decoder, EncodedQuad, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, - StrLookup, WriteEncoder, + Decoder, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, StrLookup, + WriteEncoder, }; use crate::store::storage::*; pub use crate::store::storage::{ SledConflictableTransactionError, SledTransactionError, SledUnabortableTransactionError, }; -use crate::store::{ - dump_dataset, dump_graph, get_encoded_quad_pattern, load_dataset, load_graph, - ReadableEncodedStore, WritableEncodedStore, -}; -use std::convert::TryInto; -use std::io::{BufRead, Write}; -use std::iter::{once, Once}; -use std::path::Path; -use std::{fmt, io, str}; /// Store based on the [Sled](https://sled.rs/) key-value database. /// It encodes a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) and allows to query it using SPARQL. @@ -142,9 +140,11 @@ impl SledStore { graph_name: Option>, ) -> SledQuadIter { SledQuadIter { - inner: match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) { + inner: match self.get_encoded_quad_pattern(subject, predicate, object, graph_name) { Ok(Some((subject, predicate, object, graph_name))) => QuadIterInner::Quads { - iter: self.encoded_quads_for_pattern(subject, predicate, object, graph_name), + iter: self + .storage + .quads_for_pattern(subject, predicate, object, graph_name), store: self.clone(), }, Ok(None) => QuadIterInner::Empty, @@ -153,6 +153,61 @@ impl SledStore { } } + fn get_encoded_quad_pattern( + &self, + subject: Option>, + predicate: Option>, + object: Option>, + graph_name: Option>, + ) -> Result< + Option<( + Option, + Option, + Option, + Option, + )>, + io::Error, + > { + Ok(Some(( + if let Some(subject) = transpose( + subject + .map(|t| self.storage.get_encoded_named_or_blank_node(t)) + .transpose()?, + ) { + subject + } else { + return Ok(None); + }, + if let Some(predicate) = transpose( + predicate + .map(|t| self.storage.get_encoded_named_node(t)) + .transpose()?, + ) { + predicate + } else { + return Ok(None); + }, + if let Some(object) = transpose( + object + .map(|t| self.storage.get_encoded_term(t)) + .transpose()?, + ) { + object + } else { + return Ok(None); + }, + if let Some(graph_name) = transpose( + graph_name + .map(|t| self.storage.get_encoded_graph_name(t)) + .transpose()?, + ) { + graph_name + } else { + return Ok(None); + }, + ))) + } + /// Returns all the quads contained in the store pub fn iter(&self) -> SledQuadIter { self.quads_for_pattern(None, None, None, None) @@ -333,8 +388,7 @@ impl SledStore { format: DatasetFormat, base_iri: Option<&str>, ) -> Result<(), io::Error> { - let mut this = self; - load_dataset(&mut this, reader, format, base_iri)?; + load_dataset(&self.storage, reader, format, base_iri)?; Ok(()) } @@ -433,7 +487,7 @@ impl SledStore { /// ``` pub fn named_graphs(&self) -> SledGraphNameIter { SledGraphNameIter { - iter: self.encoded_named_graphs(), + iter: self.storage.named_graphs(), store: self.clone(), } } @@ -456,7 +510,7 @@ impl SledStore { graph_name: impl Into>, ) -> Result { if let Some(graph_name) = self.get_encoded_named_or_blank_node(graph_name.into())? { - self.contains_encoded_named_graph(graph_name) + self.storage.contains_named_graph(graph_name) } else { Ok(false) } @@ -508,8 +562,7 @@ impl SledStore { graph_name: impl Into>, ) -> Result<(), io::Error> { if let Some(graph_name) = self.get_encoded_graph_name(graph_name.into())? { - let mut this = self; - this.clear_encoded_graph(graph_name) + self.storage.clear_graph(graph_name) } else { Ok(()) } @@ -564,8 +617,7 @@ impl SledStore { /// # Result::<_,Box>::Ok(()) /// ``` pub fn clear(&self) -> Result<(), io::Error> { - let mut this = self; - (&mut this).clear() + self.storage.clear() } } @@ -592,30 +644,6 @@ impl StrLookup for SledStore { } } -impl ReadableEncodedStore for SledStore { - type QuadsIter = ChainedDecodingQuadIterator; - type GraphsIter = DecodingGraphIterator; - - fn encoded_quads_for_pattern( - &self, - subject: Option, - predicate: Option, - object: Option, - graph_name: Option, - ) -> ChainedDecodingQuadIterator { - self.storage - .quads_for_pattern(subject, predicate, object, graph_name) - } - - fn encoded_named_graphs(&self) -> DecodingGraphIterator { - self.storage.named_graphs() - } - - fn contains_encoded_named_graph(&self, graph_name: EncodedTerm) -> Result { - self.storage.contains_named_graph(graph_name) - } -} - impl<'a> StrContainer for &'a SledStore { fn insert_str(&self, value: &str) -> Result { let key = StrHash::new(value); @@ -624,36 +652,6 @@ impl<'a> StrContainer for &'a SledStore { } } -impl<'a> WritableEncodedStore for &'a SledStore { - fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<(), io::Error> { - self.storage.insert(quad)?; - Ok(()) - } - - fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<(), io::Error> { - self.storage.remove(quad)?; - Ok(()) - } - - fn insert_encoded_named_graph(&mut self, graph_name: EncodedTerm) -> Result<(), io::Error> { - self.storage.insert_named_graph(graph_name)?; - Ok(()) - } - - fn clear_encoded_graph(&mut self, graph_name: EncodedTerm) -> Result<(), io::Error> { - self.storage.clear_graph(graph_name) - } - - fn remove_encoded_named_graph(&mut self, graph_name: EncodedTerm) -> Result<(), io::Error> { - self.storage.remove_named_graph(graph_name)?; - Ok(()) - } - - fn clear(&mut self) -> Result<(), io::Error> { - self.storage.clear() - } -} - /// Allows inserting and deleting quads during an ACID transaction with the [`SledStore`]. pub struct SledTransaction<'a> { storage: StorageTransaction<'a>, @@ -753,9 +751,7 @@ impl SledTransaction<'_> { format: DatasetFormat, base_iri: Option<&str>, ) -> Result<(), SledUnabortableTransactionError> { - let mut this = self; - load_dataset(&mut this, reader, format, base_iri)?; - Ok(()) + Ok(load_dataset(&self.storage, reader, format, base_iri)?) } /// Adds a quad to this store during the transaction. @@ -782,6 +778,17 @@ impl SledTransaction<'_> { Ok(false) } } + + /// Inserts a graph into this store during the transaction + /// + /// Returns `true` if the graph was not already in the store. + pub fn insert_named_graph<'a>( + &self, + graph_name: impl Into>, + ) -> Result { + let graph_name = self.encode_named_or_blank_node(graph_name.into())?; + self.storage.insert_named_graph(graph_name) + } } impl<'a> StrEncodingAware for &'a SledTransaction<'a> { @@ -806,59 +813,6 @@ impl<'a> StrContainer for &'a SledTransaction<'a> { } } -impl<'a> WritableEncodedStore for &'a SledTransaction<'a> { - fn insert_encoded( - &mut self, - quad: &EncodedQuad, - ) -> Result<(), SledUnabortableTransactionError> { - self.storage.insert(quad)?; - Ok(()) - } - - fn remove_encoded( - &mut self, - quad: &EncodedQuad, - ) -> Result<(), SledUnabortableTransactionError> { - self.storage.remove(quad)?; - Ok(()) - } - - fn insert_encoded_named_graph( - &mut self, - graph_name: EncodedTerm, - ) -> Result<(), SledUnabortableTransactionError> { - self.storage.insert_named_graph(graph_name)?; - Ok(()) - } - - fn clear_encoded_graph( - &mut self, - _: EncodedTerm, - ) -> Result<(), SledUnabortableTransactionError> { - Err(SledUnabortableTransactionError::Storage(io::Error::new( - io::ErrorKind::Other, - "CLEAR is not implemented in Sled transactions", - ))) - } - - fn remove_encoded_named_graph( - &mut self, - _: EncodedTerm, - ) -> Result<(), SledUnabortableTransactionError> { - Err(SledUnabortableTransactionError::Storage(io::Error::new( - io::ErrorKind::Other, - "DROP is not implemented in Sled transactions", - ))) - } - - fn clear(&mut self) -> Result<(), SledUnabortableTransactionError> { - Err(SledUnabortableTransactionError::Storage(io::Error::new( - io::ErrorKind::Other, - "CLEAR ALL is not implemented in Sled transactions", - ))) - } -} - /// An iterator returning the quads contained in a [`SledStore`]. pub struct SledQuadIter { inner: QuadIterInner, @@ -910,6 +864,14 @@ impl Iterator for SledGraphNameIter { } } +fn transpose(o: Option>) -> Option> { + match o { + Some(Some(v)) => Some(Some(v)), + Some(None) => None, + None => Some(None), + } +} + #[test] fn store() -> Result<(), io::Error> { use crate::model::*; diff --git a/lib/src/store/storage.rs b/lib/src/store/storage.rs index 0fbd593c..1df781ed 100644 --- a/lib/src/store/storage.rs +++ b/lib/src/store/storage.rs @@ -1,17 +1,19 @@ -use crate::error::invalid_data_error; -use crate::sparql::EvaluationError; -use crate::store::binary_encoder::*; -use crate::store::numeric_encoder::*; -use crate::store::StoreOrParseError; -use sled::transaction::{ - ConflictableTransactionError, TransactionError, TransactionalTree, UnabortableTransactionError, -}; -use sled::{Config, Db, Iter, Transactional, Tree}; use std::error::Error; use std::fmt; use std::io; use std::path::Path; +use sled::transaction::{ + ConflictableTransactionError, TransactionError, TransactionalTree, UnabortableTransactionError, +}; +use sled::{Config, Db, Iter, Transactional, Tree}; + +use crate::error::invalid_data_error; +use crate::sparql::EvaluationError; +use crate::store::binary_encoder::*; +use crate::store::io::StoreOrParseError; +use crate::store::numeric_encoder::*; + /// Low level storage primitives #[derive(Clone)] pub struct Storage {