Renames SledStore to Store and cleans up files hierarchy

pull/171/head
Tpt 4 years ago
parent a5c49a73b1
commit 0efc5b4654
  1. 16
      lib/README.md
  2. 4
      lib/benches/store.rs
  3. 12
      lib/src/lib.rs
  4. 18
      lib/src/sophia.rs
  5. 4
      lib/src/sparql/dataset.rs
  6. 2
      lib/src/sparql/error.rs
  7. 4
      lib/src/sparql/eval.rs
  8. 4
      lib/src/sparql/mod.rs
  9. 20
      lib/src/sparql/model.rs
  10. 2
      lib/src/sparql/plan.rs
  11. 2
      lib/src/sparql/plan_builder.rs
  12. 8
      lib/src/sparql/service.rs
  13. 6
      lib/src/sparql/update.rs
  14. 6
      lib/src/storage/binary_encoder.rs
  15. 4
      lib/src/storage/io.rs
  16. 181
      lib/src/storage/mod.rs
  17. 2
      lib/src/storage/numeric_encoder.rs
  18. 0
      lib/src/storage/small_string.rs
  19. 217
      lib/src/store.rs
  20. 12
      lib/src/store/mod.rs
  21. 22
      lib/tests/store.rs
  22. 12
      python/src/store.rs
  23. 2
      server/src/main.rs
  24. 4
      testsuite/src/files.rs
  25. 14
      testsuite/src/sparql_evaluator.rs
  26. 6
      wikibase/src/loader.rs
  27. 10
      wikibase/src/main.rs

@ -29,11 +29,11 @@ A preliminary benchmark [is provided](../bench/README.md).
Usage example:
```rust
use oxigraph::SledStore;
use oxigraph::model::*;
use oxigraph::store::Store;
use oxigraph::sparql::QueryResults;
use oxigraph::model::*;
let store = SledStore::new()?;
let store = Store::open("example.db")?;
// insertion
let ex = NamedNode::new("http://example.com")?;
@ -41,13 +41,13 @@ let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), None);
store.insert(&quad)?;
// quad filter
let results = store.quads_for_pattern(Some(ex.as_ref().into()), None, None, None).collect::<Result<Vec<Quad>,_>>()?;
assert_eq!(vec![quad], results);
let results: Result<Vec<Quad>,_> = store.quads_for_pattern(None, None, None, None).collect();
assert_eq!(vec![quad], results?);
// SPARQL query
if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }")? {
assert_eq!(solutions.next().unwrap()?.get("s"), Some(&ex.into()));
}
if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }")? {
assert_eq!(solutions.next().unwrap()?.get("s"), Some(&ex.into()));
};
```
## License

@ -1,6 +1,6 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use oxigraph::model::{Dataset, Graph, NamedNode, Quad, Triple};
use oxigraph::SledStore;
use oxigraph::store::Store;
use rand::random;
use std::iter::FromIterator;
@ -54,7 +54,7 @@ fn sled_load_bench(c: &mut Criterion) {
let quads = create_quads(*size);
group.bench_function(BenchmarkId::from_parameter(size), |b| {
b.iter(|| {
let store = SledStore::new().unwrap();
let store = Store::new().unwrap();
for quad in &quads {
store.insert(quad).unwrap();
}

@ -9,12 +9,15 @@
//!
//! Oxigraph also provides [a standalone HTTP server](https://crates.io/crates/oxigraph_server) based on this library.
//!
//!
//! The main entry point of Oxigraph is the [`Store`](store::Store) struct:
//!
//! ```
//! use oxigraph::SledStore;
//! use oxigraph::store::Store;
//! use oxigraph::model::*;
//! use oxigraph::sparql::QueryResults;
//!
//! let store = SledStore::new()?;
//! let store = Store::new()?;
//!
//! // insertion
//! let ex = NamedNode::new("http://example.com")?;
@ -112,7 +115,8 @@
mod error;
pub mod io;
pub mod model;
#[cfg(feature = "sophia")]
mod sophia;
pub mod sparql;
mod storage;
pub mod store;
pub use crate::store::sled::SledStore;

@ -5,7 +5,7 @@ use crate::model::{
TermRef,
};
use crate::sparql::{EvaluationError, QueryResults};
use crate::store::SledStore;
use crate::store::Store;
use sophia_api::dataset::{
CollectibleDataset, DQuadSource, DResultTermSet, DTerm, Dataset, MDResult, MutableDataset,
};
@ -20,7 +20,7 @@ use std::iter::empty;
type SophiaQuad = ([Term; 3], Option<Term>);
type StreamedSophiaQuad<'a> = StreamedQuad<'a, ByValue<SophiaQuad>>;
impl Dataset for SledStore {
impl Dataset for Store {
type Quad = ByValue<SophiaQuad>;
type Error = Error;
@ -373,7 +373,7 @@ impl Dataset for SledStore {
}
}
impl MutableDataset for SledStore {
impl MutableDataset for Store {
type MutationError = Error;
fn insert<TS, TP, TO, TG>(
&mut self,
@ -397,7 +397,7 @@ impl MutableDataset for SledStore {
Some(quad) => quad,
None => return Ok(false),
};
SledStore::insert(self, quadref).map(|_| true)
Store::insert(self, quadref).map(|_| true)
}
fn remove<TS, TP, TO, TG>(
@ -422,13 +422,13 @@ impl MutableDataset for SledStore {
Some(quad) => quad,
None => return Ok(false),
};
SledStore::remove(self, quadref).map(|_| true)
Store::remove(self, quadref).map(|_| true)
}
}
impl CollectibleDataset for SledStore {
impl CollectibleDataset for Store {
fn from_quad_source<QS: QuadSource>(quads: QS) -> StreamResult<Self, QS::Error, Self::Error> {
let mut d = SledStore::new().map_err(sophia_api::quad::stream::StreamError::SinkError)?;
let mut d = Store::new().map_err(sophia_api::quad::stream::StreamError::SinkError)?;
d.insert_all(quads)?;
Ok(d)
}
@ -576,7 +576,7 @@ where
/// # Precondition
/// + the query must be a SELECT query with a single selected variable
/// + it must not produce NULL results
fn sparql_to_hashset(store: &SledStore, sparql: &str) -> Result<HashSet<Term>, Error> {
fn sparql_to_hashset(store: &Store, sparql: &str) -> Result<HashSet<Term>, Error> {
if let QueryResults::Solutions(solutions) = store.query(sparql).map_err(io_err_map)? {
solutions
.map(|r| r.map(|v| v.get(0).unwrap().clone()))
@ -588,4 +588,4 @@ fn sparql_to_hashset(store: &SledStore, sparql: &str) -> Result<HashSet<Term>, E
}
#[cfg(test)]
sophia_api::test_dataset_impl!(test, SledStore, false, false);
sophia_api::test_dataset_impl!(test, Store, false, false);

@ -1,9 +1,9 @@
use crate::sparql::algebra::QueryDataset;
use crate::sparql::EvaluationError;
use crate::store::numeric_encoder::{
use crate::storage::numeric_encoder::{
EncodedQuad, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, StrLookup,
};
use crate::store::storage::Storage;
use crate::storage::Storage;
use std::cell::RefCell;
use std::collections::HashMap;
use std::iter::empty;

@ -1,6 +1,6 @@
use crate::error::invalid_data_error;
use crate::sparql::ParseError;
use crate::store::numeric_encoder::DecoderError;
use crate::storage::numeric_encoder::DecoderError;
use std::convert::Infallible;
use std::error;
use std::fmt;

@ -8,8 +8,8 @@ use crate::sparql::error::EvaluationError;
use crate::sparql::model::*;
use crate::sparql::plan::*;
use crate::sparql::service::ServiceHandler;
use crate::store::numeric_encoder::*;
use crate::store::small_string::SmallString;
use crate::storage::numeric_encoder::*;
use crate::storage::small_string::SmallString;
use digest::Digest;
use md5::Md5;
use oxilangtag::LanguageTag;

@ -1,6 +1,6 @@
//! [SPARQL](https://www.w3.org/TR/sparql11-overview/) implementation.
//!
//! Stores execute SPARQL. See [`SledStore`](super::store::sled::SledStore::query()) for an example.
//! Stores execute SPARQL. See [`Store`](crate::store::Store::query()) for an example.
mod algebra;
mod csv_results;
@ -30,7 +30,7 @@ use crate::sparql::plan_builder::PlanBuilder;
pub use crate::sparql::service::ServiceHandler;
use crate::sparql::service::{EmptyServiceHandler, ErrorConversionServiceHandler};
use crate::sparql::update::SimpleUpdateEvaluator;
use crate::store::storage::Storage;
use crate::storage::Storage;
pub use spargebra::ParseError;
use std::convert::TryInto;
use std::rc::Rc;

@ -44,11 +44,11 @@ impl QueryResults {
/// This method fails if it is called on the `Graph` results
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::*;
/// use oxigraph::sparql::QueryResultsFormat;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// let ex = NamedNodeRef::new("http://example.com")?;
/// store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?;
///
@ -75,14 +75,14 @@ impl QueryResults {
/// This method fails if it is called on the `Solution` or `Boolean` results
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::io::GraphFormat;
/// use oxigraph::model::*;
/// use std::io::Cursor;
///
/// let graph = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.load_graph(Cursor::new(graph), GraphFormat::NTriples, &GraphName::DefaultGraph, None)?;
///
/// let mut results = Vec::new();
@ -216,10 +216,10 @@ impl QueryResultsFormat {
/// An iterator over [`QuerySolution`]s
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::sparql::QueryResults;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// if let QueryResults::Solutions(solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }")? {
/// for solution in solutions {
/// println!("{:?}", solution?.get("s"));
@ -243,10 +243,10 @@ impl QuerySolutionIter {
/// The variables used in the solutions
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::sparql::{QueryResults, Variable};
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// if let QueryResults::Solutions(solutions) = store.query("SELECT ?s ?o WHERE { ?s ?p ?o }")? {
/// assert_eq!(solutions.variables(), &[Variable::new("s")?, Variable::new("o")?]);
/// }
@ -359,10 +359,10 @@ impl VariableSolutionIndex for Variable {
/// An iterator over the triples that compose a graph solution
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::sparql::QueryResults;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// if let QueryResults::Graph(triples) = store.query("CONSTRUCT WHERE { ?s ?p ?o }")? {
/// for triple in triples {
/// println!("{}", triple?);

@ -1,5 +1,5 @@
use crate::sparql::model::Variable;
use crate::store::numeric_encoder::EncodedTerm;
use crate::storage::numeric_encoder::EncodedTerm;
use spargebra::algebra::GraphPattern;
use std::collections::BTreeSet;
use std::rc::Rc;

@ -3,7 +3,7 @@ use crate::sparql::dataset::DatasetView;
use crate::sparql::error::EvaluationError;
use crate::sparql::model::Variable as OxVariable;
use crate::sparql::plan::*;
use crate::store::numeric_encoder::{EncodedTerm, WriteEncoder};
use crate::storage::numeric_encoder::{EncodedTerm, WriteEncoder};
use rand::random;
use spargebra::algebra::*;
use spargebra::term::*;

@ -15,12 +15,12 @@ use std::error::Error;
/// before evaluating a SPARQL query that uses SERVICE calls.
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::*;
/// use oxigraph::sparql::{QueryOptions, QueryResults, ServiceHandler, Query, EvaluationError};
///
/// struct TestServiceHandler {
/// store: SledStore
/// store: Store
/// }
///
/// impl ServiceHandler for TestServiceHandler {
@ -35,9 +35,9 @@ use std::error::Error;
/// }
/// }
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// let service = TestServiceHandler {
/// store: SledStore::new()?
/// store: Store::new()?
/// };
/// let ex = NamedNodeRef::new("http://example.com")?;
/// service.store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?;

@ -8,11 +8,11 @@ use crate::sparql::http::Client;
use crate::sparql::plan::EncodedTuple;
use crate::sparql::plan_builder::PlanBuilder;
use crate::sparql::{EvaluationError, UpdateOptions};
use crate::store::io::load_graph;
use crate::store::numeric_encoder::{
use crate::storage::io::load_graph;
use crate::storage::numeric_encoder::{
EncodedQuad, EncodedTerm, ReadEncoder, StrLookup, WriteEncoder,
};
use crate::store::storage::Storage;
use crate::storage::Storage;
use http::header::{ACCEPT, CONTENT_TYPE, USER_AGENT};
use http::{Method, Request, StatusCode};
use oxiri::Iri;

@ -1,7 +1,7 @@
use crate::error::invalid_data_error;
use crate::model::xsd::*;
use crate::store::numeric_encoder::{EncodedQuad, EncodedTerm, StrHash};
use crate::store::small_string::SmallString;
use crate::storage::numeric_encoder::{EncodedQuad, EncodedTerm, StrHash};
use crate::storage::small_string::SmallString;
use std::io;
use std::io::{Cursor, Read};
use std::mem::size_of;
@ -627,7 +627,7 @@ pub fn write_term(sink: &mut Vec<u8>, term: EncodedTerm) {
#[cfg(test)]
mod tests {
use super::*;
use crate::store::numeric_encoder::*;
use crate::storage::numeric_encoder::*;
use std::collections::HashMap;
use std::convert::Infallible;
use std::sync::RwLock;

@ -3,8 +3,8 @@
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 crate::storage::numeric_encoder::WriteEncoder;
use crate::storage::StorageLike;
use oxiri::Iri;
use rio_api::parser::{QuadsParser, TriplesParser};
use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleError, TurtleParser};

@ -1,18 +1,31 @@
use std::error::Error;
use std::fmt;
use std::io;
use std::path::Path;
use sled::transaction::{
ConflictableTransactionError, TransactionError, TransactionalTree, UnabortableTransactionError,
ConflictableTransactionError as Sled2ConflictableTransactionError,
TransactionError as Sled2TransactionError, TransactionalTree,
UnabortableTransactionError as Sled2UnabortableTransactionError,
};
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::*;
use crate::storage::binary_encoder::{
decode_term, encode_term, encode_term_pair, encode_term_quad, encode_term_triple,
write_gosp_quad, write_gpos_quad, write_gspo_quad, write_osp_quad, write_ospg_quad,
write_pos_quad, write_posg_quad, write_spo_quad, write_spog_quad, write_term, QuadEncoding,
LATEST_STORAGE_VERSION, WRITTEN_TERM_MAX_SIZE,
};
use crate::storage::io::StoreOrParseError;
use crate::storage::numeric_encoder::{
EncodedQuad, EncodedTerm, StrContainer, StrEncodingAware, StrHash, StrLookup,
};
mod binary_encoder;
pub(crate) mod io;
pub(crate) mod numeric_encoder;
pub(crate) mod small_string;
/// Low level storage primitives
#[derive(Clone)]
@ -32,15 +45,15 @@ pub struct Storage {
}
impl Storage {
pub fn new() -> Result<Self, io::Error> {
pub fn new() -> Result<Self, std::io::Error> {
Self::do_open(&Config::new().temporary(true))
}
pub fn open(path: &Path) -> Result<Self, io::Error> {
pub fn open(path: &Path) -> Result<Self, std::io::Error> {
Self::do_open(&Config::new().path(path))
}
fn do_open(config: &Config) -> Result<Self, io::Error> {
fn do_open(config: &Config) -> Result<Self, std::io::Error> {
let db = config.open()?;
let this = Self {
default: db.clone(),
@ -84,7 +97,7 @@ impl Storage {
}
}
fn ensure_version(&self) -> Result<u64, io::Error> {
fn ensure_version(&self) -> Result<u64, std::io::Error> {
Ok(if let Some(version) = self.default.get("oxversion")? {
let mut buffer = [0; 8];
buffer.copy_from_slice(&version);
@ -95,15 +108,15 @@ impl Storage {
})
}
fn set_version(&self, version: u64) -> Result<(), io::Error> {
fn set_version(&self, version: u64) -> Result<(), std::io::Error> {
self.default.insert("oxversion", &version.to_be_bytes())?;
Ok(())
}
pub fn transaction<T, E>(
&self,
f: impl Fn(StorageTransaction<'_>) -> Result<T, SledConflictableTransactionError<E>>,
) -> Result<T, SledTransactionError<E>> {
f: impl Fn(StorageTransaction<'_>) -> Result<T, ConflictableTransactionError<E>>,
) -> Result<T, TransactionError<E>> {
Ok((
&self.id2str,
&self.spog,
@ -144,7 +157,7 @@ impl Storage {
self.gspo.is_empty() && self.dspo.is_empty()
}
pub fn contains(&self, quad: &EncodedQuad) -> Result<bool, io::Error> {
pub fn contains(&self, quad: &EncodedQuad) -> Result<bool, std::io::Error> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE);
if quad.graph_name.is_default_graph() {
write_spo_quad(&mut buffer, quad);
@ -394,7 +407,7 @@ impl Storage {
}
}
pub fn contains_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, io::Error> {
pub fn contains_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, std::io::Error> {
Ok(self.graphs.contains_key(&encode_term(graph_name))?)
}
@ -446,7 +459,7 @@ impl Storage {
}
}
pub fn insert(&self, quad: &EncodedQuad) -> Result<bool, io::Error> {
pub fn insert(&self, quad: &EncodedQuad) -> Result<bool, std::io::Error> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE + 1);
if quad.graph_name.is_default_graph() {
@ -501,7 +514,7 @@ impl Storage {
}
}
pub fn remove(&self, quad: &EncodedQuad) -> Result<bool, io::Error> {
pub fn remove(&self, quad: &EncodedQuad) -> Result<bool, std::io::Error> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE + 1);
if quad.graph_name.is_default_graph() {
@ -553,11 +566,11 @@ impl Storage {
}
}
pub fn insert_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, io::Error> {
pub fn insert_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, std::io::Error> {
Ok(self.graphs.insert(&encode_term(graph_name), &[])?.is_none())
}
pub fn clear_graph(&self, graph_name: EncodedTerm) -> Result<(), io::Error> {
pub fn clear_graph(&self, graph_name: EncodedTerm) -> Result<(), std::io::Error> {
if graph_name.is_default_graph() {
self.dspo.clear()?;
self.dpos.clear()?;
@ -570,14 +583,14 @@ impl Storage {
Ok(())
}
pub fn remove_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, io::Error> {
pub fn remove_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, std::io::Error> {
for quad in self.quads_for_graph(graph_name) {
self.remove(&quad?)?;
}
Ok(self.graphs.remove(&encode_term(graph_name))?.is_some())
}
pub fn clear(&self) -> Result<(), io::Error> {
pub fn clear(&self) -> Result<(), std::io::Error> {
self.dspo.clear()?;
self.dpos.clear()?;
self.dosp.clear()?;
@ -592,7 +605,7 @@ impl Storage {
Ok(())
}
pub fn get_str(&self, key: StrHash) -> Result<Option<String>, io::Error> {
pub fn get_str(&self, key: StrHash) -> Result<Option<String>, std::io::Error> {
self.id2str
.get(key.to_be_bytes())?
.map(|v| String::from_utf8(v.to_vec()))
@ -600,11 +613,11 @@ impl Storage {
.map_err(invalid_data_error)
}
pub fn contains_str(&self, key: StrHash) -> Result<bool, io::Error> {
pub fn contains_str(&self, key: StrHash) -> Result<bool, std::io::Error> {
Ok(self.id2str.contains_key(key.to_be_bytes())?)
}
pub fn insert_str(&self, key: StrHash, value: &str) -> Result<bool, io::Error> {
pub fn insert_str(&self, key: StrHash, value: &str) -> Result<bool, std::io::Error> {
Ok(self.id2str.insert(key.to_be_bytes(), value)?.is_none())
}
}
@ -631,9 +644,9 @@ impl ChainedDecodingQuadIterator {
}
impl Iterator for ChainedDecodingQuadIterator {
type Item = Result<EncodedQuad, io::Error>;
type Item = Result<EncodedQuad, std::io::Error>;
fn next(&mut self) -> Option<Result<EncodedQuad, io::Error>> {
fn next(&mut self) -> Option<Result<EncodedQuad, std::io::Error>> {
if let Some(result) = self.first.next() {
Some(result)
} else if let Some(second) = self.second.as_mut() {
@ -650,9 +663,9 @@ pub struct DecodingQuadIterator {
}
impl Iterator for DecodingQuadIterator {
type Item = Result<EncodedQuad, io::Error>;
type Item = Result<EncodedQuad, std::io::Error>;
fn next(&mut self) -> Option<Result<EncodedQuad, io::Error>> {
fn next(&mut self) -> Option<Result<EncodedQuad, std::io::Error>> {
Some(match self.iter.next()? {
Ok((encoded, _)) => self.encoding.decode(&encoded),
Err(error) => Err(error.into()),
@ -665,9 +678,9 @@ pub struct DecodingGraphIterator {
}
impl Iterator for DecodingGraphIterator {
type Item = Result<EncodedTerm, io::Error>;
type Item = Result<EncodedTerm, std::io::Error>;
fn next(&mut self) -> Option<Result<EncodedTerm, io::Error>> {
fn next(&mut self) -> Option<Result<EncodedTerm, std::io::Error>> {
Some(match self.iter.next()? {
Ok((encoded, _)) => decode_term(&encoded),
Err(error) => Err(error.into()),
@ -690,7 +703,7 @@ pub struct StorageTransaction<'a> {
}
impl<'a> StorageTransaction<'a> {
pub fn insert(&self, quad: &EncodedQuad) -> Result<bool, SledUnabortableTransactionError> {
pub fn insert(&self, quad: &EncodedQuad) -> Result<bool, UnabortableTransactionError> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE + 1);
if quad.graph_name.is_default_graph() {
@ -746,7 +759,7 @@ impl<'a> StorageTransaction<'a> {
}
}
pub fn remove(&self, quad: &EncodedQuad) -> Result<bool, SledUnabortableTransactionError> {
pub fn remove(&self, quad: &EncodedQuad) -> Result<bool, UnabortableTransactionError> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE + 1);
if quad.graph_name.is_default_graph() {
@ -801,19 +814,19 @@ impl<'a> StorageTransaction<'a> {
pub fn insert_named_graph(
&self,
graph_name: EncodedTerm,
) -> Result<bool, SledUnabortableTransactionError> {
) -> Result<bool, UnabortableTransactionError> {
Ok(self.graphs.insert(encode_term(graph_name), &[])?.is_none())
}
pub fn get_str(&self, key: StrHash) -> Result<Option<String>, SledUnabortableTransactionError> {
pub fn get_str(&self, key: StrHash) -> Result<Option<String>, UnabortableTransactionError> {
self.id2str
.get(key.to_be_bytes())?
.map(|v| String::from_utf8(v.to_vec()))
.transpose()
.map_err(|e| SledUnabortableTransactionError::Storage(invalid_data_error(e)))
.map_err(|e| UnabortableTransactionError::Storage(invalid_data_error(e)))
}
pub fn contains_str(&self, key: StrHash) -> Result<bool, SledUnabortableTransactionError> {
pub fn contains_str(&self, key: StrHash) -> Result<bool, UnabortableTransactionError> {
Ok(self.id2str.get(key.to_be_bytes())?.is_some())
}
@ -821,21 +834,21 @@ impl<'a> StorageTransaction<'a> {
&self,
key: StrHash,
value: &str,
) -> Result<bool, SledUnabortableTransactionError> {
) -> Result<bool, UnabortableTransactionError> {
Ok(self.id2str.insert(&key.to_be_bytes(), value)?.is_none())
}
}
/// Error returned by a Sled transaction
#[derive(Debug)]
pub enum SledTransactionError<T> {
pub enum TransactionError<T> {
/// A failure returned by the API user that have aborted the transaction
Abort(T),
/// A storage related error
Storage(io::Error),
Storage(std::io::Error),
}
impl<T: fmt::Display> fmt::Display for SledTransactionError<T> {
impl<T: fmt::Display> fmt::Display for TransactionError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Abort(e) => e.fmt(f),
@ -844,7 +857,7 @@ impl<T: fmt::Display> fmt::Display for SledTransactionError<T> {
}
}
impl<T: Error + 'static> Error for SledTransactionError<T> {
impl<T: Error + 'static> Error for TransactionError<T> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Abort(e) => Some(e),
@ -853,20 +866,20 @@ impl<T: Error + 'static> Error for SledTransactionError<T> {
}
}
impl<T> From<TransactionError<T>> for SledTransactionError<T> {
fn from(e: TransactionError<T>) -> Self {
impl<T> From<Sled2TransactionError<T>> for TransactionError<T> {
fn from(e: Sled2TransactionError<T>) -> Self {
match e {
TransactionError::Abort(e) => Self::Abort(e),
TransactionError::Storage(e) => Self::Storage(e.into()),
Sled2TransactionError::Abort(e) => Self::Abort(e),
Sled2TransactionError::Storage(e) => Self::Storage(e.into()),
}
}
}
impl<T: Into<io::Error>> From<SledTransactionError<T>> for io::Error {
fn from(e: SledTransactionError<T>) -> Self {
impl<T: Into<std::io::Error>> From<TransactionError<T>> for std::io::Error {
fn from(e: TransactionError<T>) -> Self {
match e {
SledTransactionError::Abort(e) => e.into(),
SledTransactionError::Storage(e) => e,
TransactionError::Abort(e) => e.into(),
TransactionError::Storage(e) => e,
}
}
}
@ -874,14 +887,14 @@ impl<T: Into<io::Error>> From<SledTransactionError<T>> for io::Error {
/// An error returned from the transaction methods.
/// Should be returned as it is
#[derive(Debug)]
pub enum SledUnabortableTransactionError {
pub enum UnabortableTransactionError {
#[doc(hidden)]
Conflict,
/// A regular error
Storage(io::Error),
Storage(std::io::Error),
}
impl fmt::Display for SledUnabortableTransactionError {
impl fmt::Display for UnabortableTransactionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Conflict => write!(f, "Transaction conflict"),
@ -890,7 +903,7 @@ impl fmt::Display for SledUnabortableTransactionError {
}
}
impl Error for SledUnabortableTransactionError {
impl Error for UnabortableTransactionError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Storage(e) => Some(e),
@ -899,17 +912,17 @@ impl Error for SledUnabortableTransactionError {
}
}
impl From<SledUnabortableTransactionError> for EvaluationError {
fn from(e: SledUnabortableTransactionError) -> Self {
impl From<UnabortableTransactionError> for EvaluationError {
fn from(e: UnabortableTransactionError) -> Self {
match e {
SledUnabortableTransactionError::Storage(e) => Self::Io(e),
SledUnabortableTransactionError::Conflict => Self::Conflict,
UnabortableTransactionError::Storage(e) => Self::Io(e),
UnabortableTransactionError::Conflict => Self::Conflict,
}
}
}
impl From<StoreOrParseError<SledUnabortableTransactionError>> for SledUnabortableTransactionError {
fn from(e: StoreOrParseError<SledUnabortableTransactionError>) -> Self {
impl From<StoreOrParseError<UnabortableTransactionError>> for UnabortableTransactionError {
fn from(e: StoreOrParseError<UnabortableTransactionError>) -> Self {
match e {
StoreOrParseError::Store(e) => e,
StoreOrParseError::Parse(e) => Self::Storage(e),
@ -917,27 +930,27 @@ impl From<StoreOrParseError<SledUnabortableTransactionError>> for SledUnabortabl
}
}
impl From<UnabortableTransactionError> for SledUnabortableTransactionError {
fn from(e: UnabortableTransactionError) -> Self {
impl From<Sled2UnabortableTransactionError> for UnabortableTransactionError {
fn from(e: Sled2UnabortableTransactionError) -> Self {
match e {
UnabortableTransactionError::Storage(e) => Self::Storage(e.into()),
UnabortableTransactionError::Conflict => Self::Conflict,
Sled2UnabortableTransactionError::Storage(e) => Self::Storage(e.into()),
Sled2UnabortableTransactionError::Conflict => Self::Conflict,
}
}
}
/// An error returned from the transaction closure
#[derive(Debug)]
pub enum SledConflictableTransactionError<T> {
pub enum ConflictableTransactionError<T> {
/// A failure returned by the user that will abort the transaction
Abort(T),
#[doc(hidden)]
Conflict,
/// A storage related error
Storage(io::Error),
Storage(std::io::Error),
}
impl<T: fmt::Display> fmt::Display for SledConflictableTransactionError<T> {
impl<T: fmt::Display> fmt::Display for ConflictableTransactionError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Conflict => write!(f, "Transaction conflict"),
@ -947,7 +960,7 @@ impl<T: fmt::Display> fmt::Display for SledConflictableTransactionError<T> {
}
}
impl<T: Error + 'static> Error for SledConflictableTransactionError<T> {
impl<T: Error + 'static> Error for ConflictableTransactionError<T> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Abort(e) => Some(e),
@ -957,37 +970,37 @@ impl<T: Error + 'static> Error for SledConflictableTransactionError<T> {
}
}
impl<T> From<SledUnabortableTransactionError> for SledConflictableTransactionError<T> {
fn from(e: SledUnabortableTransactionError) -> Self {
impl<T> From<UnabortableTransactionError> for ConflictableTransactionError<T> {
fn from(e: UnabortableTransactionError) -> Self {
match e {
SledUnabortableTransactionError::Storage(e) => Self::Storage(e),
SledUnabortableTransactionError::Conflict => Self::Conflict,
UnabortableTransactionError::Storage(e) => Self::Storage(e),
UnabortableTransactionError::Conflict => Self::Conflict,
}
}
}
impl<T> From<SledConflictableTransactionError<T>> for ConflictableTransactionError<T> {
fn from(e: SledConflictableTransactionError<T>) -> Self {
impl<T> From<ConflictableTransactionError<T>> for Sled2ConflictableTransactionError<T> {
fn from(e: ConflictableTransactionError<T>) -> Self {
match e {
SledConflictableTransactionError::Abort(e) => ConflictableTransactionError::Abort(e),
SledConflictableTransactionError::Conflict => ConflictableTransactionError::Conflict,
SledConflictableTransactionError::Storage(e) => {
ConflictableTransactionError::Storage(e.into())
ConflictableTransactionError::Abort(e) => Sled2ConflictableTransactionError::Abort(e),
ConflictableTransactionError::Conflict => Sled2ConflictableTransactionError::Conflict,
ConflictableTransactionError::Storage(e) => {
Sled2ConflictableTransactionError::Storage(e.into())
}
}
}
}
impl StrEncodingAware for Storage {
type Error = io::Error;
type Error = std::io::Error;
}
impl StrLookup for Storage {
fn get_str(&self, id: StrHash) -> Result<Option<String>, io::Error> {
fn get_str(&self, id: StrHash) -> Result<Option<String>, std::io::Error> {
self.get_str(id)
}
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, io::Error> {
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, std::io::Error> {
let key = StrHash::new(value);
Ok(if self.contains_str(key)? {
Some(key)
@ -998,7 +1011,7 @@ impl StrLookup for Storage {
}
impl StrContainer for Storage {
fn insert_str(&self, value: &str) -> Result<StrHash, io::Error> {
fn insert_str(&self, value: &str) -> Result<StrHash, std::io::Error> {
let key = StrHash::new(value);
self.insert_str(key, value)?;
Ok(key)
@ -1006,15 +1019,15 @@ impl StrContainer for Storage {
}
impl<'a> StrEncodingAware for StorageTransaction<'a> {
type Error = SledUnabortableTransactionError;
type Error = UnabortableTransactionError;
}
impl<'a> StrLookup for StorageTransaction<'a> {
fn get_str(&self, id: StrHash) -> Result<Option<String>, SledUnabortableTransactionError> {
fn get_str(&self, id: StrHash) -> Result<Option<String>, UnabortableTransactionError> {
self.get_str(id)
}
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, SledUnabortableTransactionError> {
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, UnabortableTransactionError> {
let key = StrHash::new(value);
Ok(if self.contains_str(key)? {
Some(key)
@ -1025,7 +1038,7 @@ impl<'a> StrLookup for StorageTransaction<'a> {
}
impl<'a> StrContainer for StorageTransaction<'a> {
fn insert_str(&self, value: &str) -> Result<StrHash, SledUnabortableTransactionError> {
fn insert_str(&self, value: &str) -> Result<StrHash, UnabortableTransactionError> {
let key = StrHash::new(value);
self.insert_str(key, value)?;
Ok(key)

@ -4,7 +4,7 @@ use crate::error::invalid_data_error;
use crate::model::xsd::*;
use crate::model::*;
use crate::sparql::EvaluationError;
use crate::store::small_string::SmallString;
use crate::storage::small_string::SmallString;
use rand::random;
use rio_api::model as rio;
use siphasher::sip128::{Hasher128, SipHasher24};

@ -1,4 +1,33 @@
//! Store based on the [Sled](https://sled.rs/) key-value database.
//! API to access an on-on disk [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
//!
//! Usage example:
//! ```
//! use oxigraph::store::Store;
//! use oxigraph::sparql::QueryResults;
//! use oxigraph::model::*;
//! # use std::fs::remove_dir_all;
//!
//! # {
//! let store = Store::open("example.db")?;
//!
//! // insertion
//! let ex = NamedNode::new("http://example.com")?;
//! let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), None);
//! store.insert(&quad)?;
//!
//! // quad filter
//! let results: Result<Vec<Quad>,_> = store.quads_for_pattern(None, None, None, None).collect();
//! assert_eq!(vec![quad], results?);
//!
//! // SPARQL query
//! if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }")? {
//! assert_eq!(solutions.next().unwrap()?.get("s"), Some(&ex.into()));
//! };
//! #
//! # };
//! # remove_dir_all("example.db")?;
//! # Result::<_,Box<dyn std::error::Error>>::Ok(())
//! ```
use std::convert::TryInto;
use std::io::{BufRead, Write};
@ -12,30 +41,33 @@ 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::{
use crate::storage::io::{dump_dataset, dump_graph, load_dataset, load_graph};
use crate::storage::numeric_encoder::{
Decoder, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, StrLookup,
WriteEncoder,
};
use crate::store::storage::*;
pub use crate::store::storage::{
SledConflictableTransactionError, SledTransactionError, SledUnabortableTransactionError,
pub use crate::storage::ConflictableTransactionError;
pub use crate::storage::TransactionError;
pub use crate::storage::UnabortableTransactionError;
use crate::storage::{
ChainedDecodingQuadIterator, DecodingGraphIterator, Storage, StorageTransaction,
};
/// 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.
/// An on-on disk [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
/// Allows to query and update it using SPARQL.
/// It is based on the [Sled](https://sled.rs/) key-value database.
///
/// Warning: Sled is not stable yet and might break its storage format.
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::sparql::QueryResults;
/// use oxigraph::model::*;
/// # use std::fs::remove_dir_all;
///
/// # {
/// let store = SledStore::open("example.db")?;
/// let store = Store::open("example.db")?;
///
/// // insertion
/// let ex = NamedNode::new("http://example.com")?;
@ -56,21 +88,21 @@ pub use crate::store::storage::{
/// # Result::<_,Box<dyn std::error::Error>>::Ok(())
/// ```
#[derive(Clone)]
pub struct SledStore {
pub struct Store {
storage: Storage,
}
//TODO: indexes for the default graph and indexes for the named graphs (no more Optional and space saving)
impl SledStore {
/// Creates a temporary [`SledStore`]() that will be deleted after drop.
impl Store {
/// Creates a temporary [`Store`]() that will be deleted after drop.
pub fn new() -> Result<Self, io::Error> {
Ok(Self {
storage: Storage::new()?,
})
}
/// Opens a [`SledStore`]() and creates it if it does not exist yet.
/// Opens a [`Store`]() and creates it if it does not exist yet.
pub fn open(path: impl AsRef<Path>) -> Result<Self, io::Error> {
Ok(Self {
storage: Storage::open(path.as_ref())?,
@ -81,11 +113,11 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::*;
/// use oxigraph::sparql::QueryResults;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertions
/// let ex = NamedNodeRef::new("http://example.com")?;
@ -117,10 +149,10 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::*;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertion
/// let ex = NamedNode::new("http://example.com")?;
@ -138,8 +170,8 @@ impl SledStore {
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> SledQuadIter {
SledQuadIter {
) -> QuadIter {
QuadIter {
inner: match self.get_encoded_quad_pattern(subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadIterInner::Quads {
iter: self
@ -209,7 +241,7 @@ impl SledStore {
}
/// Returns all the quads contained in the store
pub fn iter(&self) -> SledQuadIter {
pub fn iter(&self) -> QuadIter {
self.quads_for_pattern(None, None, None, None)
}
@ -241,10 +273,10 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::*;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertion
/// store.update("INSERT DATA { <http://example.com> <http://example.com> <http://example.com> }")?;
@ -281,12 +313,11 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::{ConflictableTransactionError, Store};
/// use oxigraph::model::*;
/// use oxigraph::store::sled::SledConflictableTransactionError;
/// use std::convert::Infallible;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// let ex = NamedNodeRef::new("http://example.com")?;
/// let quad = QuadRef::new(ex, ex, ex, ex);
@ -294,7 +325,7 @@ impl SledStore {
/// // transaction
/// store.transaction(|transaction| {
/// transaction.insert(quad)?;
/// Ok(()) as Result<(),SledConflictableTransactionError<Infallible>>
/// Ok(()) as Result<(),ConflictableTransactionError<Infallible>>
/// })?;
///
/// assert!(store.contains(quad)?);
@ -303,10 +334,10 @@ impl SledStore {
/// ```
pub fn transaction<T, E>(
&self,
f: impl Fn(SledTransaction<'_>) -> Result<T, SledConflictableTransactionError<E>>,
) -> Result<T, SledTransactionError<E>> {
f: impl Fn(Transaction<'_>) -> Result<T, ConflictableTransactionError<E>>,
) -> Result<T, TransactionError<E>> {
self.storage
.transaction(|storage| f(SledTransaction { storage }))
.transaction(|storage| f(Transaction { storage }))
}
/// Loads a graph file (i.e. triples) into the store
@ -314,15 +345,15 @@ impl SledStore {
/// Warning: This functions saves the triples in a not atomic way.
/// If the parsing fails in the middle of the file only a part of it may be written to the store.
/// It might leave the store in a bad state if a crash happens during a triple insertion.
/// Use a (memory greedy) [transaction](SledStore::transaction()) if you do not want that.
/// Use a (memory greedy) [transaction](Store::transaction()) if you do not want that.
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::io::GraphFormat;
/// use oxigraph::model::*;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertion
/// let file = b"<http://example.com> <http://example.com> <http://example.com> .";
@ -359,15 +390,15 @@ impl SledStore {
/// Warning: This functions saves the triples in a not atomic way.
/// If the parsing fails in the middle of the file, only a part of it may be written to the store.
/// It might leave the store in a bad state if a crash happens during a quad insertion.
/// Use a (memory greedy) [transaction](SledStore::transaction()) if you do not want that.
/// Use a (memory greedy) [transaction](Store::transaction()) if you do not want that.
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::io::DatasetFormat;
/// use oxigraph::model::*;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertion
/// let file = b"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .";
@ -398,7 +429,7 @@ impl SledStore {
///
/// This method is optimized for performances and is not atomic.
/// It might leave the store in a bad state if a crash happens during the insertion.
/// Use a (memory greedy) [transaction](SledStore::transaction()) if you do not want that.
/// Use a (memory greedy) [transaction](Store::transaction()) if you do not want that.
pub fn insert<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<bool, io::Error> {
let quad = self.encode_quad(quad.into())?;
self.storage.insert(&quad)
@ -410,7 +441,7 @@ impl SledStore {
///
/// This method is optimized for performances and is not atomic.
/// It might leave the store in a bad state if a crash happens during the removal.
/// Use a (memory greedy) [transaction](SledStore::transaction()) if you do not want that.
/// Use a (memory greedy) [transaction](Store::transaction()) if you do not want that.
pub fn remove<'a>(&self, quad: impl Into<QuadRef<'a>>) -> Result<bool, io::Error> {
if let Some(quad) = self.get_encoded_quad(quad.into())? {
self.storage.remove(&quad)
@ -423,13 +454,13 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::io::GraphFormat;
/// use oxigraph::model::GraphName;
///
/// let file = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.load_graph(file, GraphFormat::NTriples, &GraphName::DefaultGraph, None)?;
///
/// let mut buffer = Vec::new();
@ -454,12 +485,12 @@ impl SledStore {
/// Dumps the store into a file.
///
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::io::DatasetFormat;
///
/// let file = "<http://example.com> <http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.load_dataset(file, DatasetFormat::NQuads, None)?;
///
/// let mut buffer = Vec::new();
@ -475,18 +506,18 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::{NamedNode, QuadRef, NamedOrBlankNode};
///
/// let ex = NamedNode::new("http://example.com")?;
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?;
/// store.insert(QuadRef::new(&ex, &ex, &ex, None))?;
/// assert_eq!(vec![NamedOrBlankNode::from(ex)], store.named_graphs().collect::<Result<Vec<_>,_>>()?);
/// # Result::<_,Box<dyn std::error::Error>>::Ok(())
/// ```
pub fn named_graphs(&self) -> SledGraphNameIter {
SledGraphNameIter {
pub fn named_graphs(&self) -> GraphNameIter {
GraphNameIter {
iter: self.storage.named_graphs(),
store: self.clone(),
}
@ -496,11 +527,11 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::{NamedNode, QuadRef};
///
/// let ex = NamedNode::new("http://example.com")?;
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?;
/// assert!(store.contains_named_graph(&ex)?);
/// # Result::<_,Box<dyn std::error::Error>>::Ok(())
@ -522,11 +553,11 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::NamedNodeRef;
///
/// let ex = NamedNodeRef::new("http://example.com")?;
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.insert_named_graph(ex)?;
/// assert_eq!(store.named_graphs().count(), 1);
/// # Result::<_,Box<dyn std::error::Error>>::Ok(())
@ -543,12 +574,12 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::{NamedNodeRef, QuadRef};
///
/// let ex = NamedNodeRef::new("http://example.com")?;
/// let quad = QuadRef::new(ex, ex, ex, ex);
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.insert(quad)?;
/// assert_eq!(1, store.len());
///
@ -574,12 +605,12 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::{NamedNodeRef, QuadRef};
///
/// let ex = NamedNodeRef::new("http://example.com")?;
/// let quad = QuadRef::new(ex, ex, ex, ex);
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.insert(quad)?;
/// assert_eq!(1, store.len());
///
@ -603,11 +634,11 @@ impl SledStore {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::model::{NamedNodeRef, QuadRef};
///
/// let ex = NamedNodeRef::new("http://example.com")?;
/// let store = SledStore::new()?;
/// let store = Store::new()?;
/// store.insert(QuadRef::new(ex, ex, ex, ex))?;
/// store.insert(QuadRef::new(ex, ex, ex, None))?;
/// assert_eq!(2, store.len());
@ -621,7 +652,7 @@ impl SledStore {
}
}
impl fmt::Display for SledStore {
impl fmt::Display for Store {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for t in self.iter() {
writeln!(f, "{}", t.map_err(|_| fmt::Error)?)?;
@ -630,11 +661,11 @@ impl fmt::Display for SledStore {
}
}
impl StrEncodingAware for SledStore {
impl StrEncodingAware for Store {
type Error = io::Error;
}
impl StrLookup for SledStore {
impl StrLookup for Store {
fn get_str(&self, id: StrHash) -> Result<Option<String>, io::Error> {
self.storage.get_str(id)
}
@ -644,7 +675,7 @@ impl StrLookup for SledStore {
}
}
impl<'a> StrContainer for &'a SledStore {
impl<'a> StrContainer for &'a Store {
fn insert_str(&self, value: &str) -> Result<StrHash, io::Error> {
let key = StrHash::new(value);
self.storage.insert_str(key, value)?;
@ -652,12 +683,12 @@ impl<'a> StrContainer for &'a SledStore {
}
}
/// Allows inserting and deleting quads during an ACID transaction with the [`SledStore`].
pub struct SledTransaction<'a> {
/// Allows inserting and deleting quads during an ACID transaction with the [`Store`].
pub struct Transaction<'a> {
storage: StorageTransaction<'a>,
}
impl SledTransaction<'_> {
impl Transaction<'_> {
/// Loads a graph file (i.e. triples) into the store during the transaction.
///
/// Warning: Because the load happens during a transaction,
@ -666,18 +697,18 @@ impl SledTransaction<'_> {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::Store;
/// use oxigraph::io::GraphFormat;
/// use oxigraph::model::*;
/// use oxigraph::store::sled::SledConflictableTransactionError;
/// use oxigraph::store::ConflictableTransactionError;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertion
/// let file = b"<http://example.com> <http://example.com> <http://example.com> .";
/// store.transaction(|transaction| {
/// transaction.load_graph(file.as_ref(), GraphFormat::NTriples, &GraphName::DefaultGraph, None)?;
/// Ok(()) as Result<(),SledConflictableTransactionError<std::io::Error>>
/// Ok(()) as Result<(),ConflictableTransactionError<std::io::Error>>
/// })?;
///
/// // we inspect the store content
@ -699,7 +730,7 @@ impl SledTransaction<'_> {
format: GraphFormat,
to_graph_name: impl Into<GraphNameRef<'a>>,
base_iri: Option<&str>,
) -> Result<(), SledUnabortableTransactionError> {
) -> Result<(), UnabortableTransactionError> {
load_graph(
&self.storage,
reader,
@ -718,18 +749,18 @@ impl SledTransaction<'_> {
///
/// Usage example:
/// ```
/// use oxigraph::SledStore;
/// use oxigraph::store::{Store, ConflictableTransactionError};
/// use oxigraph::io::DatasetFormat;
/// use oxigraph::model::*;
/// use oxigraph::store::sled::SledConflictableTransactionError;
/// use oxigraph::store::ConflictableTransactionError;
///
/// let store = SledStore::new()?;
/// let store = Store::new()?;
///
/// // insertion
/// let file = b"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .";
/// store.transaction(|transaction| {
/// transaction.load_dataset(file.as_ref(), DatasetFormat::NQuads, None)?;
/// Ok(()) as Result<(),SledConflictableTransactionError<std::io::Error>>
/// Ok(()) as Result<(),ConflictableTransactionError<std::io::Error>>
/// })?;
///
/// // we inspect the store content
@ -750,7 +781,7 @@ impl SledTransaction<'_> {
reader: impl BufRead,
format: DatasetFormat,
base_iri: Option<&str>,
) -> Result<(), SledUnabortableTransactionError> {
) -> Result<(), UnabortableTransactionError> {
Ok(load_dataset(&self.storage, reader, format, base_iri)?)
}
@ -760,7 +791,7 @@ impl SledTransaction<'_> {
pub fn insert<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, SledUnabortableTransactionError> {
) -> Result<bool, UnabortableTransactionError> {
let quad = self.encode_quad(quad.into())?;
self.storage.insert(&quad)
}
@ -771,7 +802,7 @@ impl SledTransaction<'_> {
pub fn remove<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, SledUnabortableTransactionError> {
) -> Result<bool, UnabortableTransactionError> {
if let Some(quad) = self.get_encoded_quad(quad.into())? {
self.storage.remove(&quad)
} else {
@ -785,49 +816,49 @@ impl SledTransaction<'_> {
pub fn insert_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, SledUnabortableTransactionError> {
) -> Result<bool, UnabortableTransactionError> {
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> {
type Error = SledUnabortableTransactionError;
impl<'a> StrEncodingAware for &'a Transaction<'a> {
type Error = UnabortableTransactionError;
}
impl<'a> StrLookup for &'a SledTransaction<'a> {
fn get_str(&self, id: StrHash) -> Result<Option<String>, SledUnabortableTransactionError> {
impl<'a> StrLookup for &'a Transaction<'a> {
fn get_str(&self, id: StrHash) -> Result<Option<String>, UnabortableTransactionError> {
self.storage.get_str(id)
}
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, SledUnabortableTransactionError> {
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, UnabortableTransactionError> {
self.storage.get_str_id(value)
}
}
impl<'a> StrContainer for &'a SledTransaction<'a> {
fn insert_str(&self, value: &str) -> Result<StrHash, SledUnabortableTransactionError> {
impl<'a> StrContainer for &'a Transaction<'a> {
fn insert_str(&self, value: &str) -> Result<StrHash, UnabortableTransactionError> {
let key = StrHash::new(value);
self.storage.insert_str(key, value)?;
Ok(key)
}
}
/// An iterator returning the quads contained in a [`SledStore`].
pub struct SledQuadIter {
/// An iterator returning the quads contained in a [`Store`].
pub struct QuadIter {
inner: QuadIterInner,
}
enum QuadIterInner {
Quads {
iter: ChainedDecodingQuadIterator,
store: SledStore,
store: Store,
},
Error(Once<io::Error>),
Empty,
}
impl Iterator for SledQuadIter {
impl Iterator for QuadIter {
type Item = Result<Quad, io::Error>;
fn next(&mut self) -> Option<Result<Quad, io::Error>> {
@ -842,13 +873,13 @@ impl Iterator for SledQuadIter {
}
}
/// An iterator returning the graph names contained in a [`SledStore`].
pub struct SledGraphNameIter {
/// An iterator returning the graph names contained in a [`Store`].
pub struct GraphNameIter {
iter: DecodingGraphIterator,
store: SledStore,
store: Store,
}
impl Iterator for SledGraphNameIter {
impl Iterator for GraphNameIter {
type Item = Result<NamedOrBlankNode, io::Error>;
fn next(&mut self) -> Option<Result<NamedOrBlankNode, io::Error>> {
@ -910,12 +941,12 @@ fn store() -> Result<(), io::Error> {
named_quad.clone(),
];
let store = SledStore::new()?;
let store = Store::new()?;
for t in &default_quads {
assert!(store.insert(t)?);
}
let result: Result<_, SledTransactionError<io::Error>> = store.transaction(|t| {
let result: Result<_, TransactionError<io::Error>> = store.transaction(|t| {
assert!(t.remove(&default_quad)?);
assert_eq!(t.remove(&default_quad)?, false);
assert!(t.insert(&named_quad)?);

@ -1,12 +0,0 @@
//! 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;

@ -1,8 +1,8 @@
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::vocab::{rdf, xsd};
use oxigraph::model::*;
use oxigraph::store::sled::SledConflictableTransactionError;
use oxigraph::SledStore;
use oxigraph::store::ConflictableTransactionError;
use oxigraph::store::Store;
use std::io;
use std::io::Cursor;
use std::process::Command;
@ -77,7 +77,7 @@ fn quads(graph_name: impl Into<GraphNameRef<'static>>) -> Vec<QuadRef<'static>>
#[test]
fn test_load_graph() -> io::Result<()> {
let store = SledStore::new()?;
let store = Store::new()?;
store.load_graph(Cursor::new(DATA), GraphFormat::Turtle, None, None)?;
for q in quads(GraphNameRef::DefaultGraph) {
assert!(store.contains(q)?);
@ -87,7 +87,7 @@ fn test_load_graph() -> io::Result<()> {
#[test]
fn test_load_dataset() -> io::Result<()> {
let store = SledStore::new()?;
let store = Store::new()?;
store.load_dataset(Cursor::new(DATA), DatasetFormat::TriG, None)?;
for q in quads(GraphNameRef::DefaultGraph) {
assert!(store.contains(q)?);
@ -97,7 +97,7 @@ fn test_load_dataset() -> io::Result<()> {
#[test]
fn test_dump_graph() -> io::Result<()> {
let store = SledStore::new()?;
let store = Store::new()?;
for q in quads(GraphNameRef::DefaultGraph) {
store.insert(q)?;
}
@ -113,7 +113,7 @@ fn test_dump_graph() -> io::Result<()> {
#[test]
fn test_dump_dataset() -> io::Result<()> {
let store = SledStore::new()?;
let store = Store::new()?;
for q in quads(GraphNameRef::DefaultGraph) {
store.insert(q)?;
}
@ -129,10 +129,10 @@ fn test_dump_dataset() -> io::Result<()> {
#[test]
fn test_transaction_load_graph() -> io::Result<()> {
let store = SledStore::new()?;
let store = Store::new()?;
store.transaction(|t| {
t.load_graph(Cursor::new(DATA), GraphFormat::Turtle, None, None)?;
Ok(()) as Result<_, SledConflictableTransactionError<io::Error>>
Ok(()) as Result<_, ConflictableTransactionError<io::Error>>
})?;
for q in quads(GraphNameRef::DefaultGraph) {
assert!(store.contains(q)?);
@ -142,10 +142,10 @@ fn test_transaction_load_graph() -> io::Result<()> {
#[test]
fn test_transaction_load_dataset() -> io::Result<()> {
let store = SledStore::new()?;
let store = Store::new()?;
store.transaction(|t| {
t.load_dataset(Cursor::new(DATA), DatasetFormat::TriG, None)?;
Ok(()) as Result<_, SledConflictableTransactionError<io::Error>>
Ok(()) as Result<_, ConflictableTransactionError<io::Error>>
})?;
for q in quads(GraphNameRef::DefaultGraph) {
assert!(store.contains(q)?);
@ -156,7 +156,7 @@ fn test_transaction_load_dataset() -> io::Result<()> {
#[test]
fn test_backward_compatibility() -> io::Result<()> {
{
let store = SledStore::open("tests/sled_bc_data")?;
let store = Store::open("tests/sled_bc_data")?;
for q in quads(GraphNameRef::DefaultGraph) {
assert!(store.contains(q)?);
}

@ -3,7 +3,7 @@ use crate::model::*;
use crate::sparql::*;
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::GraphNameRef;
use oxigraph::store::sled::*;
use oxigraph::store::{self, Store};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::{
pyclass, pymethods, pyproto, Py, PyAny, PyObject, PyRef, PyRefMut, PyResult, Python,
@ -31,7 +31,7 @@ use std::io::BufReader;
#[text_signature = "(path = None)"]
#[derive(Clone)]
pub struct PyStore {
inner: SledStore,
inner: Store,
}
#[pymethods]
@ -40,9 +40,9 @@ impl PyStore {
fn new(path: Option<&str>) -> PyResult<Self> {
Ok(Self {
inner: if let Some(path) = path {
SledStore::open(path)
Store::open(path)
} else {
SledStore::new()
Store::new()
}
.map_err(map_io_err)?,
})
@ -459,7 +459,7 @@ impl PyIterProtocol for PyStore {
#[pyclass(unsendable, module = "oxigraph")]
pub struct QuadIter {
inner: SledQuadIter,
inner: store::QuadIter,
}
#[pyproto]
@ -478,7 +478,7 @@ impl PyIterProtocol for QuadIter {
#[pyclass(unsendable, module = "oxigraph")]
pub struct GraphNameIter {
inner: SledGraphNameIter,
inner: store::GraphNameIter,
}
#[pyproto]

@ -23,7 +23,7 @@ use http_types::{
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::{GraphName, GraphNameRef, NamedNode, NamedOrBlankNode};
use oxigraph::sparql::{Query, QueryResults, QueryResultsFormat, Update};
use oxigraph::SledStore as Store;
use oxigraph::store::Store;
use oxiri::Iri;
use rand::random;
use std::io::BufReader;

@ -1,7 +1,7 @@
use anyhow::{anyhow, Result};
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::{Dataset, Graph, GraphNameRef};
use oxigraph::SledStore;
use oxigraph::store::Store;
use std::fs::File;
use std::io::{BufRead, BufReader, Read};
use std::path::PathBuf;
@ -41,7 +41,7 @@ pub fn read_file_to_string(url: &str) -> Result<String> {
pub fn load_to_store<'a>(
url: &str,
store: &SledStore,
store: &Store,
to_graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<()> {
if url.ends_with(".nt") {

@ -7,7 +7,7 @@ use chrono::Utc;
use oxigraph::model::vocab::*;
use oxigraph::model::*;
use oxigraph::sparql::*;
use oxigraph::SledStore;
use oxigraph::store::Store;
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;
@ -70,7 +70,7 @@ fn evaluate_sparql_test(test: &Test) -> Result<()> {
} else if test.kind
== "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#QueryEvaluationTest"
{
let store = SledStore::new()?;
let store = Store::new()?;
if let Some(data) = &test.data {
load_to_store(data, &store, GraphNameRef::DefaultGraph)?;
}
@ -190,7 +190,7 @@ fn evaluate_sparql_test(test: &Test) -> Result<()> {
} else if test.kind
== "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#UpdateEvaluationTest"
{
let store = SledStore::new()?;
let store = Store::new()?;
if let Some(data) = &test.data {
load_to_store(data, &store, &GraphName::DefaultGraph)?;
}
@ -198,7 +198,7 @@ fn evaluate_sparql_test(test: &Test) -> Result<()> {
load_to_store(value, &store, name)?;
}
let result_store = SledStore::new()?;
let result_store = Store::new()?;
if let Some(data) = &test.result {
load_to_store(data, &result_store, &GraphName::DefaultGraph)?;
}
@ -270,7 +270,7 @@ fn load_sparql_query_result(url: &str) -> Result<StaticQueryResults> {
#[derive(Clone)]
struct StaticServiceHandler {
services: Arc<HashMap<NamedNode, SledStore>>,
services: Arc<HashMap<NamedNode, Store>>,
}
impl StaticServiceHandler {
@ -281,7 +281,7 @@ impl StaticServiceHandler {
.iter()
.map(|(name, data)| {
let name = NamedNode::new(name)?;
let store = SledStore::new()?;
let store = Store::new()?;
load_to_store(&data, &store, &GraphName::DefaultGraph)?;
Ok((name, store))
})
@ -467,7 +467,7 @@ impl StaticQueryResults {
fn from_graph(graph: Graph) -> StaticQueryResults {
// Hack to normalize literals
let store = SledStore::new().unwrap();
let store = Store::new().unwrap();
for t in graph.iter() {
store
.insert(t.in_graph(GraphNameRef::DefaultGraph))

@ -7,7 +7,7 @@ use http_client::HttpClient;
use http_types::{headers, Method, Request, Result};
use oxigraph::io::GraphFormat;
use oxigraph::model::NamedNodeRef;
use oxigraph::SledStore;
use oxigraph::store::Store;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
use std::io::{BufReader, Cursor, Read};
@ -16,7 +16,7 @@ use std::time::Duration;
use url::{form_urlencoded, Url};
pub struct WikibaseLoader {
store: SledStore,
store: Store,
client: H1Client,
api_url: Url,
entity_data_url: Url,
@ -28,7 +28,7 @@ pub struct WikibaseLoader {
impl WikibaseLoader {
pub fn new(
store: SledStore,
store: Store,
api_url: &str,
pages_base_url: &str,
namespaces: &[u32],

@ -23,7 +23,7 @@ use http_types::{
use oxigraph::io::GraphFormat;
use oxigraph::model::{GraphName, NamedNode, NamedOrBlankNode};
use oxigraph::sparql::{Query, QueryResults, QueryResultsFormat};
use oxigraph::SledStore;
use oxigraph::store::Store;
use std::str::FromStr;
use std::time::Duration;
use url::form_urlencoded;
@ -65,7 +65,7 @@ struct Args {
pub async fn main() -> Result<()> {
let args: Args = argh::from_env();
let store = SledStore::open(args.file)?;
let store = Store::open(args.file)?;
let mediawiki_api = args.mediawiki_api.clone();
let mediawiki_base_url = args.mediawiki_base_url.clone();
let namespaces = args
@ -106,7 +106,7 @@ pub async fn main() -> Result<()> {
.await
}
async fn handle_request(request: Request, store: SledStore) -> Result<Response> {
async fn handle_request(request: Request, store: Store) -> Result<Response> {
Ok(match (request.url().path(), request.method()) {
("/query", Method::Get) => {
configure_and_evaluate_sparql_query(store, url_query(&request), None, request)?
@ -159,7 +159,7 @@ fn url_query(request: &Request) -> Vec<u8> {
}
fn configure_and_evaluate_sparql_query(
store: SledStore,
store: Store,
encoded: Vec<u8>,
mut query: Option<String>,
request: Request,
@ -187,7 +187,7 @@ fn configure_and_evaluate_sparql_query(
}
fn evaluate_sparql_query(
store: SledStore,
store: Store,
query: String,
default_graph_uris: Vec<String>,
named_graph_uris: Vec<String>,

Loading…
Cancel
Save