Drops old Stotrage traits

pull/171/head
Tpt 4 years ago
parent 17a3ae728d
commit a5c49a73b1
  1. 60
      lib/src/sparql/dataset.rs
  2. 1
      lib/src/sparql/eval.rs
  3. 2
      lib/src/sparql/update.rs
  4. 150
      lib/src/store/io.rs
  5. 256
      lib/src/store/mod.rs
  6. 224
      lib/src/store/sled.rs
  7. 20
      lib/src/store/storage.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<Option<String>, 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<Option<StrHash>, 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<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>>;
type GraphsIter = Once<Result<EncodedTerm, EvaluationError>>;
#[allow(clippy::needless_collect)]
fn encoded_quads_for_pattern(
pub fn encoded_quads_for_pattern(
&self,
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
@ -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<Option<String>, 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<bool, EvaluationError> {
Err(EvaluationError::msg(
"Graphs lookup is not implemented by DatasetView",
))
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, EvaluationError> {
let id = StrHash::new(value);
Ok(if self.extra.borrow().contains_key(&id) {
Some(id)
} else {
self.storage.get_str_id(value)?
})
}
}

@ -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;

@ -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,
};

@ -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<S: StorageLike>(
storage: &S,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: GraphNameRef<'_>,
base_iri: Option<&str>,
) -> Result<(), StoreOrParseError<S::Error>> {
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<S: StorageLike, P: TriplesParser>(
storage: &S,
mut parser: P,
to_graph_name: GraphNameRef<'_>,
) -> Result<(), StoreOrParseError<S::Error>>
where
StoreOrParseError<S::Error>: From<P::Error>,
{
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<Item = Result<Triple, io::Error>>,
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<S: StorageLike>(
store: &S,
reader: impl BufRead,
format: DatasetFormat,
base_iri: Option<&str>,
) -> Result<(), StoreOrParseError<S::Error>> {
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<S: StorageLike, P: QuadsParser>(
store: &S,
mut parser: P,
) -> Result<(), StoreOrParseError<S::Error>>
where
StoreOrParseError<S::Error>: From<P::Error>,
{
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<Item = Result<Quad, io::Error>>,
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<S> {
Store(S),
Parse(io::Error),
}
impl<S> From<TurtleError> for StoreOrParseError<S> {
fn from(error: TurtleError) -> Self {
Self::Parse(error.into())
}
}
impl<S> From<RdfXmlError> for StoreOrParseError<S> {
fn from(error: RdfXmlError) -> Self {
Self::Parse(error.into())
}
}
impl<S> From<io::Error> for StoreOrParseError<S> {
fn from(error: io::Error) -> Self {
Self::Parse(error)
}
}
impl From<StoreOrParseError<io::Error>> for io::Error {
fn from(error: StoreOrParseError<io::Error>) -> Self {
match error {
StoreOrParseError::Store(error) => error,
StoreOrParseError::Parse(error) => error,
}
}
}

@ -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<Item = Result<EncodedQuad, Self::Error>> + 'static;
type GraphsIter: Iterator<Item = Result<EncodedTerm, Self::Error>> + 'static;
fn encoded_quads_for_pattern(
&self,
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> Self::QuadsIter;
fn encoded_named_graphs(&self) -> Self::GraphsIter;
fn contains_encoded_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, Self::Error>;
}
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<S: StorageLike>(
storage: &S,
reader: impl BufRead,
format: GraphFormat,
to_graph_name: GraphNameRef<'_>,
base_iri: Option<&str>,
) -> Result<(), StoreOrParseError<S::Error>> {
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<S: StorageLike, P: TriplesParser>(
storage: &S,
mut parser: P,
to_graph_name: GraphNameRef<'_>,
) -> Result<(), StoreOrParseError<S::Error>>
where
StoreOrParseError<S::Error>: From<P::Error>,
{
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<Item = Result<Triple, io::Error>>,
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<S: WritableEncodedStore + StrContainer>(
store: &mut S,
reader: impl BufRead,
format: DatasetFormat,
base_iri: Option<&str>,
) -> Result<(), StoreOrParseError<S::Error>> {
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<S: WritableEncodedStore + StrContainer, P: QuadsParser>(
store: &mut S,
mut parser: P,
) -> Result<(), StoreOrParseError<S::Error>>
where
StoreOrParseError<S::Error>: From<P::Error>,
{
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<Item = Result<Quad, io::Error>>,
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<S> {
Store(S),
Parse(io::Error),
}
impl<S> From<TurtleError> for StoreOrParseError<S> {
fn from(error: TurtleError) -> Self {
Self::Parse(error.into())
}
}
impl<S> From<RdfXmlError> for StoreOrParseError<S> {
fn from(error: RdfXmlError) -> Self {
Self::Parse(error.into())
}
}
impl<S> From<io::Error> for StoreOrParseError<S> {
fn from(error: io::Error) -> Self {
Self::Parse(error)
}
}
impl From<StoreOrParseError<io::Error>> for io::Error {
fn from(error: StoreOrParseError<io::Error>) -> Self {
match error {
StoreOrParseError::Store(error) => error,
StoreOrParseError::Parse(error) => error,
}
}
}
impl From<StoreOrParseError<Infallible>> for io::Error {
fn from(error: StoreOrParseError<Infallible>) -> Self {
match error {
StoreOrParseError::Store(error) => match error {},
StoreOrParseError::Parse(error) => error,
}
}
}
type QuadPattern = (
Option<EncodedTerm>,
Option<EncodedTerm>,
Option<EncodedTerm>,
Option<EncodedTerm>,
);
fn get_encoded_quad_pattern<E: ReadEncoder>(
encoder: &E,
subject: Option<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> Result<Option<QuadPattern>, 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<T>(o: Option<Option<T>>) -> Option<Option<T>> {
match o {
Some(Some(v)) => Some(Some(v)),
Some(None) => None,
None => Some(None),
}
}

@ -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<GraphNameRef<'_>>,
) -> 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<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> Result<
Option<(
Option<EncodedTerm>,
Option<EncodedTerm>,
Option<EncodedTerm>,
Option<EncodedTerm>,
)>,
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<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, io::Error> {
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<GraphNameRef<'a>>,
) -> 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<dyn std::error::Error>>::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<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> 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<bool, io::Error> {
self.storage.contains_named_graph(graph_name)
}
}
impl<'a> StrContainer for &'a SledStore {
fn insert_str(&self, value: &str) -> Result<StrHash, io::Error> {
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<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, SledUnabortableTransactionError> {
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<T>(o: Option<Option<T>>) -> Option<Option<T>> {
match o {
Some(Some(v)) => Some(Some(v)),
Some(None) => None,
None => Some(None),
}
}
#[test]
fn store() -> Result<(), io::Error> {
use crate::model::*;

@ -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 {

Loading…
Cancel
Save