Allows to upgrades to the latest versions of RocksDB and avoid some behaviors that could cause unexpected crashespull/10/head
parent
b9bd6e66d3
commit
21ad76c7cf
@ -1,46 +1,50 @@ |
|||||||
//! This crate is a work in progress of implementation of an RDF and SPARQL software stack in Rust.
|
//! Rudf is a work in progress graph database implementing the [SPARQL](https://www.w3.org/TR/sparql11-overview/) standard.
|
||||||
//!
|
//!
|
||||||
//! Its goal is to provide a compliant, safe and fast implementation of W3C specifications.
|
//! Its goal is to provide a compliant, safe and fast graph database.
|
||||||
//!
|
//!
|
||||||
//! It currently provides:
|
//! It currently provides two `Repository` implementation providing [SPARQL 1.0 query](https://www.w3.org/TR/rdf-sparql-query/) capability:
|
||||||
//! * Basic RDF data structures in the `model` package
|
//! * `MemoryRepository`: a simple in memory implementation.
|
||||||
//! * Parsers for XML, Turtle and N-Triples syntaxes in the `rio` package
|
//! * `RocksDbRepository`: a file system implementation based on the [RocksDB](https://rocksdb.org/) key-value store.
|
||||||
//! * A memory based and a disk based stores in the `store` package
|
//!
|
||||||
//! * A work in progress SPARQL implementation in the `sparql` package
|
//! Usage example with the `MemoryRepository`:
|
||||||
|
//!
|
||||||
#![warn(
|
//! ```
|
||||||
clippy::cast_possible_wrap, |
//! use rudf::model::*;
|
||||||
clippy::cast_precision_loss, |
//! use rudf::{Repository, RepositoryConnection, MemoryRepository, Result};
|
||||||
clippy::cast_sign_loss, |
//! use crate::rudf::sparql::PreparedQuery;
|
||||||
clippy::default_trait_access, |
//! use std::str::FromStr;
|
||||||
clippy::empty_enum, |
//! use rudf::sparql::algebra::QueryResult;
|
||||||
clippy::enum_glob_use, |
//!
|
||||||
clippy::expl_impl_clone_on_copy, |
//! let repository = MemoryRepository::default();
|
||||||
clippy::explicit_into_iter_loop, |
//! let connection = repository.connection().unwrap();
|
||||||
clippy::filter_map, |
//!
|
||||||
clippy::if_not_else, |
//! // insertion
|
||||||
clippy::inline_always, |
//! let ex = NamedNode::from_str("http://example.com").unwrap();
|
||||||
clippy::invalid_upcast_comparisons, |
//! let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), None);
|
||||||
clippy::items_after_statements, |
//! connection.insert(&quad);
|
||||||
clippy::linkedlist, |
//!
|
||||||
//TODO match_same_arms,
|
//! // quad filter
|
||||||
clippy::maybe_infinite_iter, |
//! let results: Result<Vec<Quad>> = connection.quads_for_pattern(None, None, None, None).collect();
|
||||||
clippy::mut_mut, |
//! assert_eq!(vec![quad], results.unwrap());
|
||||||
clippy::needless_continue, |
//!
|
||||||
clippy::option_map_unwrap_or, |
//! // SPARQL query
|
||||||
//TODO option_map_unwrap_or_else,
|
//! let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
|
||||||
clippy::pub_enum_variant_names, |
//! let results = prepared_query.exec().unwrap();
|
||||||
clippy::replace_consts, |
//! if let QueryResult::Bindings(results) = results {
|
||||||
clippy::result_map_unwrap_or_else, |
//! assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));
|
||||||
//TODO single_match_else,
|
//! }
|
||||||
clippy::string_add_assign, |
//! ```
|
||||||
clippy::unicode_not_nfc |
|
||||||
)] |
|
||||||
|
|
||||||
pub mod model; |
pub mod model; |
||||||
|
mod repository; |
||||||
pub mod rio; |
pub mod rio; |
||||||
pub mod sparql; |
pub mod sparql; |
||||||
pub mod store; |
pub(crate) mod store; |
||||||
|
|
||||||
pub use failure::Error; |
pub use failure::Error; |
||||||
pub type Result<T> = ::std::result::Result<T, failure::Error>; |
pub type Result<T> = ::std::result::Result<T, failure::Error>; |
||||||
|
pub use crate::store::MemoryRepository; |
||||||
|
#[cfg(feature = "rocksdb")] |
||||||
|
pub use crate::store::RocksDbRepository; |
||||||
|
pub use repository::Repository; |
||||||
|
pub use repository::RepositoryConnection; |
||||||
|
@ -1,212 +0,0 @@ |
|||||||
use crate::model::*; |
|
||||||
use crate::Result; |
|
||||||
|
|
||||||
/// Trait for [RDF graphs](https://www.w3.org/TR/rdf11-concepts/#dfn-graph)
|
|
||||||
///
|
|
||||||
/// This crate currently provides a simple stand-alone in memory implementation of the `Graph` trait.
|
|
||||||
///
|
|
||||||
/// Usage example:
|
|
||||||
/// ```
|
|
||||||
/// use rudf::model::*;
|
|
||||||
/// use rudf::store::MemoryGraph;
|
|
||||||
/// use std::str::FromStr;
|
|
||||||
///
|
|
||||||
/// let graph = MemoryGraph::default();
|
|
||||||
/// let ex = NamedNode::from_str("http://example.com").unwrap();
|
|
||||||
/// let triple = Triple::new(ex.clone(), ex.clone(), ex.clone());
|
|
||||||
/// graph.insert(&triple);
|
|
||||||
/// let results: Vec<Triple> = graph.triples_for_subject(&ex.into()).unwrap().map(|t| t.unwrap()).collect();
|
|
||||||
/// assert_eq!(vec![triple], results);
|
|
||||||
/// ```
|
|
||||||
pub trait Graph { |
|
||||||
type TriplesIterator: Iterator<Item = Result<Triple>>; |
|
||||||
type TriplesForSubjectIterator: Iterator<Item = Result<Triple>>; |
|
||||||
type ObjectsForSubjectPredicateIterator: Iterator<Item = Result<Term>>; |
|
||||||
type PredicatesForSubjectObjectIterator: Iterator<Item = Result<NamedNode>>; |
|
||||||
type TriplesForPredicateIterator: Iterator<Item = Result<Triple>>; |
|
||||||
type SubjectsForPredicateObjectIterator: Iterator<Item = Result<NamedOrBlankNode>>; |
|
||||||
type TriplesForObjectIterator: Iterator<Item = Result<Triple>>; |
|
||||||
|
|
||||||
/// Returns all triples contained by the graph
|
|
||||||
fn iter(&self) -> Result<Self::TriplesIterator> { |
|
||||||
self.triples() |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns all triples contained by the graph
|
|
||||||
fn triples(&self) -> Result<Self::TriplesIterator>; |
|
||||||
|
|
||||||
fn triples_for_subject( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
) -> Result<Self::TriplesForSubjectIterator>; |
|
||||||
|
|
||||||
fn objects_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<Self::ObjectsForSubjectPredicateIterator>; |
|
||||||
|
|
||||||
fn object_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<Option<Term>> { |
|
||||||
//TODO use transpose when stable
|
|
||||||
match self |
|
||||||
.objects_for_subject_predicate(subject, predicate)? |
|
||||||
.nth(0) |
|
||||||
{ |
|
||||||
Some(object) => Ok(Some(object?)), |
|
||||||
None => Ok(None), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn predicates_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<Self::PredicatesForSubjectObjectIterator>; |
|
||||||
|
|
||||||
fn triples_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<Self::TriplesForPredicateIterator>; |
|
||||||
|
|
||||||
fn subjects_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<Self::SubjectsForPredicateObjectIterator>; |
|
||||||
|
|
||||||
fn triples_for_object(&self, object: &Term) -> Result<Self::TriplesForObjectIterator>; |
|
||||||
|
|
||||||
/// Checks if the graph contains the given triple
|
|
||||||
fn contains(&self, triple: &Triple) -> Result<bool>; |
|
||||||
|
|
||||||
/// Adds a triple to the graph
|
|
||||||
fn insert(&self, triple: &Triple) -> Result<()>; |
|
||||||
|
|
||||||
/// Removes a concrete triple from the graph
|
|
||||||
fn remove(&self, triple: &Triple) -> Result<()>; |
|
||||||
|
|
||||||
/// Returns the number of triples in this graph
|
|
||||||
fn len(&self) -> Result<usize>; |
|
||||||
|
|
||||||
/// Checks if this graph contains a triple
|
|
||||||
fn is_empty(&self) -> Result<bool>; |
|
||||||
} |
|
||||||
|
|
||||||
/// Trait for [RDF named graphs](https://www.w3.org/TR/rdf11-concepts/#dfn-named-graph) i.e. RDF graphs identified by an IRI
|
|
||||||
pub trait NamedGraph: Graph { |
|
||||||
fn name(&self) -> &NamedOrBlankNode; |
|
||||||
} |
|
||||||
|
|
||||||
/// Trait for [RDF datasets](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
|
|
||||||
///
|
|
||||||
/// This crate currently provides two implementation of the `Dataset` traits:
|
|
||||||
/// * One in memory: `rudf::store::MemoryDataset`
|
|
||||||
/// * One disk-based using [RocksDB](https://rocksdb.org/): `rudf::store::RocksDbDataset`
|
|
||||||
///
|
|
||||||
/// Usage example with `rudf::store::MemoryDataset`:
|
|
||||||
/// ```
|
|
||||||
/// use rudf::model::*;
|
|
||||||
/// use rudf::store::MemoryDataset;
|
|
||||||
/// use std::str::FromStr;
|
|
||||||
///
|
|
||||||
/// let dataset = MemoryDataset::default();
|
|
||||||
/// let default_graph = dataset.default_graph();
|
|
||||||
/// let ex = NamedNode::from_str("http://example.com").unwrap();
|
|
||||||
/// let triple = Triple::new(ex.clone(), ex.clone(), ex.clone());
|
|
||||||
/// default_graph.insert(&triple);
|
|
||||||
/// let results: Vec<Quad> = dataset.quads_for_subject(&ex.into()).unwrap().map(|t| t.unwrap()).collect();
|
|
||||||
/// assert_eq!(vec![triple.in_graph(None)], results);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The implementation backed by RocksDB if disabled by default and requires the `"rocksdb"` feature to be activated.
|
|
||||||
/// A `RocksDbDataset` could be built using `RocksDbDataset::open` and works just like its in-memory equivalent:
|
|
||||||
/// ```ignore
|
|
||||||
/// use rudf::store::RocksDbDataset;
|
|
||||||
/// let dataset = RocksDbDataset::open("foo.db");
|
|
||||||
/// ```
|
|
||||||
pub trait Dataset { |
|
||||||
type NamedGraph: NamedGraph; |
|
||||||
type DefaultGraph: Graph; |
|
||||||
type UnionGraph: Graph; |
|
||||||
type QuadsIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForSubjectIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForSubjectPredicateIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForSubjectPredicateObjectIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForSubjectObjectIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForPredicateIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForPredicateObjectIterator: Iterator<Item = Result<Quad>>; |
|
||||||
type QuadsForObjectIterator: Iterator<Item = Result<Quad>>; |
|
||||||
|
|
||||||
/// Returns an object for a [named graph](https://www.w3.org/TR/rdf11-concepts/#dfn-named-graph) of this dataset.
|
|
||||||
///
|
|
||||||
/// This named graph may be empty if no triple is in the graph yet.
|
|
||||||
fn named_graph(&self, name: &NamedOrBlankNode) -> Result<Self::NamedGraph>; |
|
||||||
|
|
||||||
/// Returns an object for the [default graph](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph) of this dataset
|
|
||||||
fn default_graph(&self) -> Self::DefaultGraph; |
|
||||||
|
|
||||||
/// Returns a graph that is the union of all graphs contained in this dataset, including the default graph
|
|
||||||
fn union_graph(&self) -> Self::UnionGraph; |
|
||||||
|
|
||||||
/// Returns all quads contained by the graph
|
|
||||||
fn iter(&self) -> Result<Self::QuadsIterator> { |
|
||||||
self.quads() |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns all quads contained by the graph
|
|
||||||
fn quads(&self) -> Result<Self::QuadsIterator>; |
|
||||||
|
|
||||||
fn quads_for_subject( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
) -> Result<Self::QuadsForSubjectIterator>; |
|
||||||
|
|
||||||
fn quads_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<Self::QuadsForSubjectPredicateIterator>; |
|
||||||
|
|
||||||
fn quads_for_subject_predicate_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<Self::QuadsForSubjectPredicateObjectIterator>; |
|
||||||
|
|
||||||
fn quads_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<Self::QuadsForSubjectObjectIterator>; |
|
||||||
|
|
||||||
fn quads_for_predicate(&self, predicate: &NamedNode) |
|
||||||
-> Result<Self::QuadsForPredicateIterator>; |
|
||||||
|
|
||||||
fn quads_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<Self::QuadsForPredicateObjectIterator>; |
|
||||||
|
|
||||||
fn quads_for_object(&self, object: &Term) -> Result<Self::QuadsForObjectIterator>; |
|
||||||
|
|
||||||
/// Checks if this dataset contains a given quad
|
|
||||||
fn contains(&self, quad: &Quad) -> Result<bool>; |
|
||||||
|
|
||||||
/// Adds a quad to this dataset
|
|
||||||
fn insert(&self, quad: &Quad) -> Result<()>; |
|
||||||
|
|
||||||
/// Removes a quad from this dataset
|
|
||||||
fn remove(&self, quad: &Quad) -> Result<()>; |
|
||||||
|
|
||||||
/// Returns the number of quads in this dataset
|
|
||||||
fn len(&self) -> Result<usize>; |
|
||||||
|
|
||||||
/// Checks if this dataset contains a quad
|
|
||||||
fn is_empty(&self) -> Result<bool>; |
|
||||||
} |
|
@ -0,0 +1,126 @@ |
|||||||
|
use crate::model::*; |
||||||
|
use crate::sparql::PreparedQuery; |
||||||
|
use crate::Result; |
||||||
|
use std::io::Read; |
||||||
|
|
||||||
|
/// A `Repository` stores a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
|
||||||
|
/// and allows to query and update it using SPARQL.
|
||||||
|
///
|
||||||
|
/// This crate currently provides two implementation of the `Repository` traits:
|
||||||
|
/// * One in memory: `MemoryRepository`
|
||||||
|
/// * One disk-based using [RocksDB](https://rocksdb.org/): `RocksDbRepository`
|
||||||
|
///
|
||||||
|
/// Usage example with `MemoryRepository`:
|
||||||
|
/// ```
|
||||||
|
/// use rudf::model::*;
|
||||||
|
/// use rudf::{Repository, RepositoryConnection, MemoryRepository, Result};
|
||||||
|
/// use crate::rudf::sparql::PreparedQuery;
|
||||||
|
/// use std::str::FromStr;
|
||||||
|
/// use rudf::sparql::algebra::QueryResult;
|
||||||
|
///
|
||||||
|
/// let repository = MemoryRepository::default();
|
||||||
|
/// let connection = repository.connection().unwrap();
|
||||||
|
///
|
||||||
|
/// // insertion
|
||||||
|
/// let ex = NamedNode::from_str("http://example.com").unwrap();
|
||||||
|
/// let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), None);
|
||||||
|
/// connection.insert(&quad);
|
||||||
|
///
|
||||||
|
/// // quad filter
|
||||||
|
/// let results: Result<Vec<Quad>> = connection.quads_for_pattern(None, None, None, None).collect();
|
||||||
|
/// assert_eq!(vec![quad], results.unwrap());
|
||||||
|
///
|
||||||
|
/// // SPARQL query
|
||||||
|
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
|
||||||
|
/// let results = prepared_query.exec().unwrap();
|
||||||
|
/// if let QueryResult::Bindings(results) = results {
|
||||||
|
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The implementation based on RocksDB if disabled by default and requires the `"rocksdb"` feature to be activated.
|
||||||
|
/// A `RocksDbRepository` could be built using `RocksDbRepository::open` and works just like its in-memory equivalent:
|
||||||
|
/// ```ignore
|
||||||
|
/// use rudf::RocksDbRepository;
|
||||||
|
/// let dataset = RocksDbRepository::open("example.db").unwrap();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Quads insertion and deletion should respect [ACID](https://en.wikipedia.org/wiki/ACID) properties for all implementation.
|
||||||
|
/// No complex transaction support is provided yet.
|
||||||
|
pub trait Repository { |
||||||
|
type Connection: RepositoryConnection; |
||||||
|
|
||||||
|
fn connection(self) -> Result<Self::Connection>; |
||||||
|
} |
||||||
|
|
||||||
|
/// A connection to a `Repository`
|
||||||
|
pub trait RepositoryConnection: Clone { |
||||||
|
type PreparedQuery: PreparedQuery; |
||||||
|
|
||||||
|
/// Prepares a [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/) query and returns an object that could be used to execute it.
|
||||||
|
///
|
||||||
|
/// The implementation is a work in progress, SPARQL 1.1 specific features are not implemented yet.
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// ```
|
||||||
|
/// use rudf::model::*;
|
||||||
|
/// use rudf::{Repository, RepositoryConnection, MemoryRepository};
|
||||||
|
/// use rudf::sparql::PreparedQuery;
|
||||||
|
/// use rudf::sparql::algebra::QueryResult;
|
||||||
|
/// use std::str::FromStr;
|
||||||
|
///
|
||||||
|
/// let repository = MemoryRepository::default();
|
||||||
|
/// let connection = repository.connection().unwrap();
|
||||||
|
///
|
||||||
|
/// // insertions
|
||||||
|
/// let ex = NamedNode::from_str("http://example.com").unwrap();
|
||||||
|
/// connection.insert(&Quad::new(ex.clone(), ex.clone(), ex.clone(), None));
|
||||||
|
///
|
||||||
|
/// // SPARQL query
|
||||||
|
/// let prepared_query = connection.prepare_query("SELECT ?s WHERE { ?s ?p ?o }".as_bytes()).unwrap();
|
||||||
|
/// let results = prepared_query.exec().unwrap();
|
||||||
|
/// if let QueryResult::Bindings(results) = results {
|
||||||
|
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
fn prepare_query(&self, query: impl Read) -> Result<Self::PreparedQuery>; |
||||||
|
|
||||||
|
/// Retrieves quads with a filter on each quad component
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// ```
|
||||||
|
/// use rudf::model::*;
|
||||||
|
/// use rudf::{Repository, RepositoryConnection, MemoryRepository, Result};
|
||||||
|
/// use std::str::FromStr;
|
||||||
|
///
|
||||||
|
/// let repository = MemoryRepository::default();
|
||||||
|
/// let connection = repository.connection().unwrap();
|
||||||
|
///
|
||||||
|
/// // insertion
|
||||||
|
/// let ex = NamedNode::from_str("http://example.com").unwrap();
|
||||||
|
/// let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), None);
|
||||||
|
/// connection.insert(&quad);
|
||||||
|
///
|
||||||
|
/// // quad filter
|
||||||
|
/// let results: Result<Vec<Quad>> = connection.quads_for_pattern(None, None, None, None).collect();
|
||||||
|
/// assert_eq!(vec![quad], results.unwrap());
|
||||||
|
/// ```
|
||||||
|
fn quads_for_pattern<'a>( |
||||||
|
&'a self, |
||||||
|
subject: Option<&NamedOrBlankNode>, |
||||||
|
predicate: Option<&NamedNode>, |
||||||
|
object: Option<&Term>, |
||||||
|
graph_name: Option<&NamedOrBlankNode>, |
||||||
|
) -> Box<dyn Iterator<Item = Result<Quad>> + 'a> |
||||||
|
where |
||||||
|
Self: 'a; |
||||||
|
|
||||||
|
/// Checks if this dataset contains a given quad
|
||||||
|
fn contains(&self, quad: &Quad) -> Result<bool>; |
||||||
|
|
||||||
|
/// Adds a quad to this dataset
|
||||||
|
fn insert(&self, quad: &Quad) -> Result<()>; |
||||||
|
|
||||||
|
/// Removes a quad from this dataset
|
||||||
|
fn remove(&self, quad: &Quad) -> Result<()>; |
||||||
|
} |
@ -1,966 +0,0 @@ |
|||||||
use crate::model::*; |
|
||||||
use crate::store::numeric_encoder::*; |
|
||||||
use crate::Result; |
|
||||||
use failure::format_err; |
|
||||||
use std::fmt; |
|
||||||
use std::iter::empty; |
|
||||||
use std::iter::once; |
|
||||||
use std::iter::FromIterator; |
|
||||||
use std::iter::Iterator; |
|
||||||
use std::sync::Arc; |
|
||||||
|
|
||||||
/// Defines the Store traits that is used to have efficient binary storage
|
|
||||||
|
|
||||||
pub trait EncodedQuadsStore: StringStore + Sized + 'static { |
|
||||||
type QuadsIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectPredicateIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectPredicateObjectIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectObjectIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForPredicateIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForPredicateObjectIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForObjectIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectPredicateGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForSubjectObjectGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForPredicateGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForPredicateObjectGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
type QuadsForObjectGraphIterator: Iterator<Item = Result<EncodedQuad>> + 'static; |
|
||||||
|
|
||||||
fn encoder(&self) -> Encoder<&Self> { |
|
||||||
Encoder::new(&self) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads(&self) -> Result<Self::QuadsIterator>; |
|
||||||
fn quads_for_subject(&self, subject: EncodedTerm) -> Result<Self::QuadsForSubjectIterator>; |
|
||||||
fn quads_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: EncodedTerm, |
|
||||||
predicate: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForSubjectPredicateIterator>; |
|
||||||
fn quads_for_subject_predicate_object( |
|
||||||
&self, |
|
||||||
subject: EncodedTerm, |
|
||||||
predicate: EncodedTerm, |
|
||||||
object: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForSubjectPredicateObjectIterator>; |
|
||||||
fn quads_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: EncodedTerm, |
|
||||||
object: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForSubjectObjectIterator>; |
|
||||||
fn quads_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForPredicateIterator>; |
|
||||||
fn quads_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: EncodedTerm, |
|
||||||
object: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForPredicateObjectIterator>; |
|
||||||
fn quads_for_object(&self, object: EncodedTerm) -> Result<Self::QuadsForObjectIterator>; |
|
||||||
fn quads_for_graph(&self, graph_name: EncodedTerm) -> Result<Self::QuadsForGraphIterator>; |
|
||||||
fn quads_for_subject_graph( |
|
||||||
&self, |
|
||||||
subject: EncodedTerm, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForSubjectGraphIterator>; |
|
||||||
fn quads_for_subject_predicate_graph( |
|
||||||
&self, |
|
||||||
subject: EncodedTerm, |
|
||||||
predicate: EncodedTerm, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForSubjectPredicateGraphIterator>; |
|
||||||
fn quads_for_subject_object_graph( |
|
||||||
&self, |
|
||||||
subject: EncodedTerm, |
|
||||||
object: EncodedTerm, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForSubjectObjectGraphIterator>; |
|
||||||
fn quads_for_predicate_graph( |
|
||||||
&self, |
|
||||||
predicate: EncodedTerm, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForPredicateGraphIterator>; |
|
||||||
fn quads_for_predicate_object_graph( |
|
||||||
&self, |
|
||||||
predicate: EncodedTerm, |
|
||||||
object: EncodedTerm, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForPredicateObjectGraphIterator>; |
|
||||||
fn quads_for_object_graph( |
|
||||||
&self, |
|
||||||
object: EncodedTerm, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
) -> Result<Self::QuadsForObjectGraphIterator>; |
|
||||||
fn contains(&self, quad: &EncodedQuad) -> Result<bool>; |
|
||||||
fn insert(&self, quad: &EncodedQuad) -> Result<()>; |
|
||||||
fn remove(&self, quad: &EncodedQuad) -> Result<()>; |
|
||||||
fn quads_for_pattern( |
|
||||||
&self, |
|
||||||
subject: Option<EncodedTerm>, |
|
||||||
predicate: Option<EncodedTerm>, |
|
||||||
object: Option<EncodedTerm>, |
|
||||||
graph_name: Option<EncodedTerm>, |
|
||||||
) -> Box<dyn Iterator<Item = Result<EncodedQuad>>> { |
|
||||||
match subject { |
|
||||||
Some(subject) => match predicate { |
|
||||||
Some(predicate) => match object { |
|
||||||
Some(object) => match graph_name { |
|
||||||
Some(graph_name) => { |
|
||||||
let quad = EncodedQuad::new(subject, predicate, object, graph_name); |
|
||||||
match self.contains(&quad) { |
|
||||||
Ok(true) => Box::new(once(Ok(quad))), |
|
||||||
Ok(false) => Box::new(empty()), |
|
||||||
Err(error) => Box::new(once(Err(error))), |
|
||||||
} |
|
||||||
} |
|
||||||
None => wrap_error( |
|
||||||
self.quads_for_subject_predicate_object(subject, predicate, object), |
|
||||||
), |
|
||||||
}, |
|
||||||
None => match graph_name { |
|
||||||
Some(graph_name) => wrap_error( |
|
||||||
self.quads_for_subject_predicate_graph(subject, predicate, graph_name), |
|
||||||
), |
|
||||||
None => wrap_error(self.quads_for_subject_predicate(subject, predicate)), |
|
||||||
}, |
|
||||||
}, |
|
||||||
None => match object { |
|
||||||
Some(object) => match graph_name { |
|
||||||
Some(graph_name) => wrap_error( |
|
||||||
self.quads_for_subject_object_graph(subject, object, graph_name), |
|
||||||
), |
|
||||||
None => wrap_error(self.quads_for_subject_object(subject, object)), |
|
||||||
}, |
|
||||||
None => match graph_name { |
|
||||||
Some(graph_name) => { |
|
||||||
wrap_error(self.quads_for_subject_graph(subject, graph_name)) |
|
||||||
} |
|
||||||
None => wrap_error(self.quads_for_subject(subject)), |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
None => match predicate { |
|
||||||
Some(predicate) => match object { |
|
||||||
Some(object) => match graph_name { |
|
||||||
Some(graph_name) => wrap_error( |
|
||||||
self.quads_for_predicate_object_graph(predicate, object, graph_name), |
|
||||||
), |
|
||||||
None => wrap_error(self.quads_for_predicate_object(predicate, object)), |
|
||||||
}, |
|
||||||
None => match graph_name { |
|
||||||
Some(graph_name) => { |
|
||||||
wrap_error(self.quads_for_predicate_graph(predicate, graph_name)) |
|
||||||
} |
|
||||||
None => wrap_error(self.quads_for_predicate(predicate)), |
|
||||||
}, |
|
||||||
}, |
|
||||||
None => match object { |
|
||||||
Some(object) => match graph_name { |
|
||||||
Some(graph_name) => { |
|
||||||
wrap_error(self.quads_for_object_graph(object, graph_name)) |
|
||||||
} |
|
||||||
None => wrap_error(self.quads_for_object(object)), |
|
||||||
}, |
|
||||||
None => match graph_name { |
|
||||||
Some(graph_name) => wrap_error(self.quads_for_graph(graph_name)), |
|
||||||
None => wrap_error(self.quads()), |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn wrap_error<E: 'static, I: Iterator<Item = Result<E>> + 'static>( |
|
||||||
iter: Result<I>, |
|
||||||
) -> Box<dyn Iterator<Item = Result<E>>> { |
|
||||||
match iter { |
|
||||||
Ok(iter) => Box::new(iter), |
|
||||||
Err(error) => Box::new(once(Err(error))), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct StoreDataset<S: EncodedQuadsStore> { |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> StoreDataset<S> { |
|
||||||
pub fn new_from_store(store: S) -> Self { |
|
||||||
Self { |
|
||||||
store: Arc::new(store), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub(crate) fn encoded(&self) -> Arc<S> { |
|
||||||
self.store.clone() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> Dataset for StoreDataset<S> { |
|
||||||
type NamedGraph = StoreNamedGraph<S>; |
|
||||||
type DefaultGraph = StoreDefaultGraph<S>; |
|
||||||
type UnionGraph = StoreUnionGraph<S>; |
|
||||||
type QuadsIterator = QuadsIterator<S::QuadsIterator, S>; |
|
||||||
type QuadsForSubjectIterator = QuadsIterator<S::QuadsForSubjectIterator, S>; |
|
||||||
type QuadsForSubjectPredicateIterator = QuadsIterator<S::QuadsForSubjectPredicateIterator, S>; |
|
||||||
type QuadsForSubjectPredicateObjectIterator = |
|
||||||
QuadsIterator<S::QuadsForSubjectPredicateObjectIterator, S>; |
|
||||||
type QuadsForSubjectObjectIterator = QuadsIterator<S::QuadsForSubjectObjectIterator, S>; |
|
||||||
type QuadsForPredicateIterator = QuadsIterator<S::QuadsForPredicateIterator, S>; |
|
||||||
type QuadsForPredicateObjectIterator = QuadsIterator<S::QuadsForPredicateObjectIterator, S>; |
|
||||||
type QuadsForObjectIterator = QuadsIterator<S::QuadsForObjectIterator, S>; |
|
||||||
|
|
||||||
fn named_graph(&self, name: &NamedOrBlankNode) -> Result<StoreNamedGraph<S>> { |
|
||||||
Ok(StoreNamedGraph { |
|
||||||
store: self.store.clone(), |
|
||||||
name: name.clone(), |
|
||||||
encoded_name: self.store.encoder().encode_named_or_blank_node(name)?, |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn default_graph(&self) -> StoreDefaultGraph<S> { |
|
||||||
StoreDefaultGraph { |
|
||||||
store: self.store.clone(), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn union_graph(&self) -> StoreUnionGraph<S> { |
|
||||||
StoreUnionGraph { |
|
||||||
store: self.store.clone(), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn quads(&self) -> Result<QuadsIterator<S::QuadsIterator, S>> { |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self.store.quads()?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForSubjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self |
|
||||||
.store |
|
||||||
.quads_for_subject(encoder.encode_named_or_blank_node(subject)?)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForSubjectPredicateIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self.store.quads_for_subject_predicate( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_predicate_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForSubjectPredicateObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self.store.quads_for_subject_predicate_object( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForSubjectObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self.store.quads_for_subject_object( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForPredicateIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self |
|
||||||
.store |
|
||||||
.quads_for_predicate(encoder.encode_named_node(predicate)?)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForPredicateObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self.store.quads_for_predicate_object( |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_object( |
|
||||||
&self, |
|
||||||
object: &Term, |
|
||||||
) -> Result<QuadsIterator<S::QuadsForObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(QuadsIterator { |
|
||||||
iter: self.store.quads_for_object(encoder.encode_term(object)?)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn contains(&self, quad: &Quad) -> Result<bool> { |
|
||||||
self.store |
|
||||||
.contains(&self.store.encoder().encode_quad(quad)?) |
|
||||||
} |
|
||||||
|
|
||||||
fn insert(&self, quad: &Quad) -> Result<()> { |
|
||||||
self.store.insert(&self.store.encoder().encode_quad(quad)?) |
|
||||||
} |
|
||||||
|
|
||||||
fn remove(&self, quad: &Quad) -> Result<()> { |
|
||||||
self.store.remove(&self.store.encoder().encode_quad(quad)?) |
|
||||||
} |
|
||||||
|
|
||||||
fn len(&self) -> Result<usize> { |
|
||||||
Ok(self.store.quads()?.count()) |
|
||||||
} |
|
||||||
|
|
||||||
fn is_empty(&self) -> Result<bool> { |
|
||||||
Ok(self.store.quads()?.any(|_| true)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> fmt::Display for StoreDataset<S> { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
||||||
for quad in self.iter().map_err(|_| fmt::Error)? { |
|
||||||
writeln!(fmt, "{}", quad.map_err(|_| fmt::Error)?)?; |
|
||||||
} |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore + Default> Default for StoreDataset<S> { |
|
||||||
fn default() -> Self { |
|
||||||
Self::new_from_store(S::default()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore + Default> FromIterator<Quad> for StoreDataset<S> { |
|
||||||
fn from_iter<I: IntoIterator<Item = Quad>>(iter: I) -> Self { |
|
||||||
let dataset = Self::default(); |
|
||||||
for quad in iter { |
|
||||||
dataset.insert(&quad).unwrap(); |
|
||||||
} |
|
||||||
dataset |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<'a, S: EncodedQuadsStore + Default> FromIterator<&'a Quad> for StoreDataset<S> { |
|
||||||
fn from_iter<I: IntoIterator<Item = &'a Quad>>(iter: I) -> Self { |
|
||||||
let dataset = Self::default(); |
|
||||||
for quad in iter { |
|
||||||
dataset.insert(quad).unwrap(); |
|
||||||
} |
|
||||||
dataset |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct StoreNamedGraph<S: EncodedQuadsStore> { |
|
||||||
store: Arc<S>, |
|
||||||
name: NamedOrBlankNode, |
|
||||||
encoded_name: EncodedTerm, |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> Graph for StoreNamedGraph<S> { |
|
||||||
type TriplesIterator = TriplesIterator<S::QuadsForGraphIterator, S>; |
|
||||||
type TriplesForSubjectIterator = TriplesIterator<S::QuadsForSubjectGraphIterator, S>; |
|
||||||
type ObjectsForSubjectPredicateIterator = |
|
||||||
ObjectsIterator<S::QuadsForSubjectPredicateGraphIterator, S>; |
|
||||||
type PredicatesForSubjectObjectIterator = |
|
||||||
PredicatesIterator<S::QuadsForSubjectObjectGraphIterator, S>; |
|
||||||
type TriplesForPredicateIterator = TriplesIterator<S::QuadsForPredicateGraphIterator, S>; |
|
||||||
type SubjectsForPredicateObjectIterator = |
|
||||||
SubjectsIterator<S::QuadsForPredicateObjectGraphIterator, S>; |
|
||||||
type TriplesForObjectIterator = TriplesIterator<S::QuadsForObjectGraphIterator, S>; |
|
||||||
|
|
||||||
fn triples(&self) -> Result<TriplesIterator<S::QuadsForGraphIterator, S>> { |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_graph(self.encoded_name)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn triples_for_subject( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForSubjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_subject_graph( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
self.encoded_name, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn objects_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<ObjectsIterator<S::QuadsForSubjectPredicateGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(ObjectsIterator { |
|
||||||
iter: self.store.quads_for_subject_predicate_graph( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
self.encoded_name, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn predicates_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<PredicatesIterator<S::QuadsForSubjectObjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(PredicatesIterator { |
|
||||||
iter: self.store.quads_for_subject_object_graph( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
self.encoded_name, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn triples_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForPredicateGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_predicate_graph( |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
self.encoded_name, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn subjects_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<SubjectsIterator<S::QuadsForPredicateObjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(SubjectsIterator { |
|
||||||
iter: self.store.quads_for_predicate_object_graph( |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
self.encoded_name, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn triples_for_object( |
|
||||||
&self, |
|
||||||
object: &Term, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForObjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self |
|
||||||
.store |
|
||||||
.quads_for_object_graph(encoder.encode_term(object)?, self.encoded_name)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn contains(&self, triple: &Triple) -> Result<bool> { |
|
||||||
self.store.contains( |
|
||||||
&self |
|
||||||
.store |
|
||||||
.encoder() |
|
||||||
.encode_triple_in_graph(triple, self.encoded_name)?, |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
fn insert(&self, triple: &Triple) -> Result<()> { |
|
||||||
self.store.insert( |
|
||||||
&self |
|
||||||
.store |
|
||||||
.encoder() |
|
||||||
.encode_triple_in_graph(triple, self.encoded_name)?, |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
fn remove(&self, triple: &Triple) -> Result<()> { |
|
||||||
self.store.remove( |
|
||||||
&self |
|
||||||
.store |
|
||||||
.encoder() |
|
||||||
.encode_triple_in_graph(triple, self.encoded_name)?, |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
fn len(&self) -> Result<usize> { |
|
||||||
Ok(self.store.quads_for_graph(self.encoded_name)?.count()) |
|
||||||
} |
|
||||||
|
|
||||||
fn is_empty(&self) -> Result<bool> { |
|
||||||
Ok(self.store.quads_for_graph(self.encoded_name)?.any(|_| true)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> NamedGraph for StoreNamedGraph<S> { |
|
||||||
fn name(&self) -> &NamedOrBlankNode { |
|
||||||
&self.name |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> fmt::Display for StoreNamedGraph<S> { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
||||||
for triple in self.iter().map_err(|_| fmt::Error)? { |
|
||||||
writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?; |
|
||||||
} |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct StoreDefaultGraph<S: EncodedQuadsStore> { |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> Graph for StoreDefaultGraph<S> { |
|
||||||
type TriplesIterator = TriplesIterator<S::QuadsForGraphIterator, S>; |
|
||||||
type TriplesForSubjectIterator = TriplesIterator<S::QuadsForSubjectGraphIterator, S>; |
|
||||||
type ObjectsForSubjectPredicateIterator = |
|
||||||
ObjectsIterator<S::QuadsForSubjectPredicateGraphIterator, S>; |
|
||||||
type PredicatesForSubjectObjectIterator = |
|
||||||
PredicatesIterator<S::QuadsForSubjectObjectGraphIterator, S>; |
|
||||||
type TriplesForPredicateIterator = TriplesIterator<S::QuadsForPredicateGraphIterator, S>; |
|
||||||
type SubjectsForPredicateObjectIterator = |
|
||||||
SubjectsIterator<S::QuadsForPredicateObjectGraphIterator, S>; |
|
||||||
type TriplesForObjectIterator = TriplesIterator<S::QuadsForObjectGraphIterator, S>; |
|
||||||
|
|
||||||
fn triples(&self) -> Result<TriplesIterator<S::QuadsForGraphIterator, S>> { |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_graph(ENCODED_DEFAULT_GRAPH)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn triples_for_subject( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForSubjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_subject_graph( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
ENCODED_DEFAULT_GRAPH, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn objects_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<ObjectsIterator<S::QuadsForSubjectPredicateGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(ObjectsIterator { |
|
||||||
iter: self.store.quads_for_subject_predicate_graph( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
ENCODED_DEFAULT_GRAPH, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn predicates_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<PredicatesIterator<S::QuadsForSubjectObjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(PredicatesIterator { |
|
||||||
iter: self.store.quads_for_subject_object_graph( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
ENCODED_DEFAULT_GRAPH, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn triples_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForPredicateGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_predicate_graph( |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
ENCODED_DEFAULT_GRAPH, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn subjects_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<SubjectsIterator<S::QuadsForPredicateObjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(SubjectsIterator { |
|
||||||
iter: self.store.quads_for_predicate_object_graph( |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
ENCODED_DEFAULT_GRAPH, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn triples_for_object( |
|
||||||
&self, |
|
||||||
object: &Term, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForObjectGraphIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self |
|
||||||
.store |
|
||||||
.quads_for_object_graph(encoder.encode_term(object)?, ENCODED_DEFAULT_GRAPH)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn contains(&self, triple: &Triple) -> Result<bool> { |
|
||||||
self.store.contains( |
|
||||||
&self |
|
||||||
.store |
|
||||||
.encoder() |
|
||||||
.encode_triple_in_graph(triple, ENCODED_DEFAULT_GRAPH)?, |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
fn insert(&self, triple: &Triple) -> Result<()> { |
|
||||||
self.store.insert( |
|
||||||
&self |
|
||||||
.store |
|
||||||
.encoder() |
|
||||||
.encode_triple_in_graph(triple, ENCODED_DEFAULT_GRAPH)?, |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
fn remove(&self, triple: &Triple) -> Result<()> { |
|
||||||
self.store.remove( |
|
||||||
&self |
|
||||||
.store |
|
||||||
.encoder() |
|
||||||
.encode_triple_in_graph(triple, ENCODED_DEFAULT_GRAPH)?, |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
fn len(&self) -> Result<usize> { |
|
||||||
Ok(self.store.quads_for_graph(ENCODED_DEFAULT_GRAPH)?.count()) |
|
||||||
} |
|
||||||
|
|
||||||
fn is_empty(&self) -> Result<bool> { |
|
||||||
Ok(self |
|
||||||
.store |
|
||||||
.quads_for_graph(ENCODED_DEFAULT_GRAPH)? |
|
||||||
.any(|_| true)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> fmt::Display for StoreDefaultGraph<S> { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
||||||
for triple in self.iter().map_err(|_| fmt::Error)? { |
|
||||||
writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?; |
|
||||||
} |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore + Default> Default for StoreDefaultGraph<S> { |
|
||||||
fn default() -> Self { |
|
||||||
StoreDataset::default().default_graph() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore + Default> FromIterator<Triple> for StoreDefaultGraph<S> { |
|
||||||
fn from_iter<I: IntoIterator<Item = Triple>>(iter: I) -> Self { |
|
||||||
let graph = Self::default(); |
|
||||||
for triple in iter { |
|
||||||
graph.insert(&triple).unwrap(); |
|
||||||
} |
|
||||||
graph |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<'a, S: EncodedQuadsStore + Default> FromIterator<&'a Triple> for StoreDefaultGraph<S> { |
|
||||||
fn from_iter<I: IntoIterator<Item = &'a Triple>>(iter: I) -> Self { |
|
||||||
let graph = Self::default(); |
|
||||||
for triple in iter { |
|
||||||
graph.insert(triple).unwrap(); |
|
||||||
} |
|
||||||
graph |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct StoreUnionGraph<S: EncodedQuadsStore> { |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> Graph for StoreUnionGraph<S> { |
|
||||||
type TriplesIterator = TriplesIterator<S::QuadsIterator, S>; |
|
||||||
type TriplesForSubjectIterator = TriplesIterator<S::QuadsForSubjectIterator, S>; |
|
||||||
type ObjectsForSubjectPredicateIterator = |
|
||||||
ObjectsIterator<S::QuadsForSubjectPredicateIterator, S>; |
|
||||||
type PredicatesForSubjectObjectIterator = |
|
||||||
PredicatesIterator<S::QuadsForSubjectObjectIterator, S>; |
|
||||||
type TriplesForPredicateIterator = TriplesIterator<S::QuadsForPredicateIterator, S>; |
|
||||||
type SubjectsForPredicateObjectIterator = |
|
||||||
SubjectsIterator<S::QuadsForPredicateObjectIterator, S>; |
|
||||||
type TriplesForObjectIterator = TriplesIterator<S::QuadsForObjectIterator, S>; |
|
||||||
|
|
||||||
fn triples(&self) -> Result<TriplesIterator<S::QuadsIterator, S>> { |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads()?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn triples_for_subject( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForSubjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self |
|
||||||
.store |
|
||||||
.quads_for_subject(encoder.encode_named_or_blank_node(subject)?)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn objects_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<ObjectsIterator<S::QuadsForSubjectPredicateIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(ObjectsIterator { |
|
||||||
iter: self.store.quads_for_subject_predicate( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn predicates_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &NamedOrBlankNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<PredicatesIterator<S::QuadsForSubjectObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(PredicatesIterator { |
|
||||||
iter: self.store.quads_for_subject_object( |
|
||||||
encoder.encode_named_or_blank_node(subject)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn triples_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForPredicateIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self |
|
||||||
.store |
|
||||||
.quads_for_predicate(encoder.encode_named_node(predicate)?)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
fn subjects_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &NamedNode, |
|
||||||
object: &Term, |
|
||||||
) -> Result<SubjectsIterator<S::QuadsForPredicateObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(SubjectsIterator { |
|
||||||
iter: self.store.quads_for_predicate_object( |
|
||||||
encoder.encode_named_node(predicate)?, |
|
||||||
encoder.encode_term(object)?, |
|
||||||
)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn triples_for_object( |
|
||||||
&self, |
|
||||||
object: &Term, |
|
||||||
) -> Result<TriplesIterator<S::QuadsForObjectIterator, S>> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(TriplesIterator { |
|
||||||
iter: self.store.quads_for_object(encoder.encode_term(object)?)?, |
|
||||||
store: self.store.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn contains(&self, triple: &Triple) -> Result<bool> { |
|
||||||
let encoder = self.store.encoder(); |
|
||||||
Ok(self |
|
||||||
.store |
|
||||||
.quads_for_subject_predicate_object( |
|
||||||
encoder.encode_named_or_blank_node(triple.subject())?, |
|
||||||
encoder.encode_named_node(triple.predicate())?, |
|
||||||
encoder.encode_term(triple.object())?, |
|
||||||
)? |
|
||||||
.any(|_| true)) |
|
||||||
} |
|
||||||
|
|
||||||
fn insert(&self, _triple: &Triple) -> Result<()> { |
|
||||||
Err(format_err!("Union graph is not writable")) |
|
||||||
} |
|
||||||
|
|
||||||
fn remove(&self, _triple: &Triple) -> Result<()> { |
|
||||||
Err(format_err!("Union graph is not writable")) |
|
||||||
} |
|
||||||
|
|
||||||
fn len(&self) -> Result<usize> { |
|
||||||
Ok(self.store.quads()?.count()) |
|
||||||
} |
|
||||||
|
|
||||||
fn is_empty(&self) -> Result<bool> { |
|
||||||
Ok(self.store.quads()?.any(|_| true)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<S: EncodedQuadsStore> fmt::Display for StoreUnionGraph<S> { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
||||||
for triple in self.iter().map_err(|_| fmt::Error)? { |
|
||||||
writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?; |
|
||||||
} |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct QuadsIterator<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> { |
|
||||||
iter: I, |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> Iterator |
|
||||||
for QuadsIterator<I, S> |
|
||||||
{ |
|
||||||
type Item = Result<Quad>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<Quad>> { |
|
||||||
self.iter |
|
||||||
.next() |
|
||||||
.map(|k| k.and_then(|quad| self.store.encoder().decode_quad(&quad))) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct TriplesIterator<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> { |
|
||||||
iter: I, |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> Iterator |
|
||||||
for TriplesIterator<I, S> |
|
||||||
{ |
|
||||||
type Item = Result<Triple>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<Triple>> { |
|
||||||
self.iter |
|
||||||
.next() |
|
||||||
.map(|k| k.and_then(|quad| self.store.encoder().decode_triple(&quad))) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct SubjectsIterator<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> { |
|
||||||
iter: I, |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> Iterator |
|
||||||
for SubjectsIterator<I, S> |
|
||||||
{ |
|
||||||
type Item = Result<NamedOrBlankNode>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<NamedOrBlankNode>> { |
|
||||||
self.iter.next().map(|k| { |
|
||||||
k.and_then(|quad| { |
|
||||||
self.store |
|
||||||
.encoder() |
|
||||||
.decode_named_or_blank_node(quad.subject) |
|
||||||
}) |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct PredicatesIterator<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> { |
|
||||||
iter: I, |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> Iterator |
|
||||||
for PredicatesIterator<I, S> |
|
||||||
{ |
|
||||||
type Item = Result<NamedNode>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<NamedNode>> { |
|
||||||
self.iter |
|
||||||
.next() |
|
||||||
.map(|k| k.and_then(|quad| self.store.encoder().decode_named_node(quad.predicate))) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct ObjectsIterator<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> { |
|
||||||
iter: I, |
|
||||||
store: Arc<S>, |
|
||||||
} |
|
||||||
|
|
||||||
impl<I: Iterator<Item = Result<EncodedQuad>>, S: EncodedQuadsStore> Iterator |
|
||||||
for ObjectsIterator<I, S> |
|
||||||
{ |
|
||||||
type Item = Result<Term>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<Term>> { |
|
||||||
self.iter |
|
||||||
.next() |
|
||||||
.map(|k| k.and_then(|quad| self.store.encoder().decode_term(quad.object))) |
|
||||||
} |
|
||||||
} |
|
@ -1,12 +1,125 @@ |
|||||||
//! Provides implementations of the `rudf::model::Graph` and `rudf::model::Dataset` traits.
|
//! Provides implementations of the `rudf::Repository` trait.
|
||||||
|
|
||||||
pub(crate) mod encoded; |
|
||||||
mod memory; |
mod memory; |
||||||
pub(crate) mod numeric_encoder; |
pub(crate) mod numeric_encoder; |
||||||
#[cfg(feature = "rocksdb")] |
#[cfg(feature = "rocksdb")] |
||||||
mod rocksdb; |
mod rocksdb; |
||||||
|
|
||||||
pub use crate::store::memory::MemoryDataset; |
pub use crate::store::memory::MemoryRepository; |
||||||
pub use crate::store::memory::MemoryGraph; |
|
||||||
#[cfg(feature = "rocksdb")] |
#[cfg(feature = "rocksdb")] |
||||||
pub use crate::store::rocksdb::RocksDbDataset; |
pub use crate::store::rocksdb::RocksDbRepository; |
||||||
|
|
||||||
|
use crate::model::*; |
||||||
|
use crate::sparql::SimplePreparedQuery; |
||||||
|
use crate::store::numeric_encoder::*; |
||||||
|
use crate::{RepositoryConnection, Result}; |
||||||
|
use std::io::Read; |
||||||
|
use std::iter::{once, Iterator}; |
||||||
|
|
||||||
|
/// Defines the `Store` traits that is used to have efficient binary storage
|
||||||
|
pub trait Store { |
||||||
|
type Connection: StoreConnection; |
||||||
|
|
||||||
|
fn connection(self) -> Result<Self::Connection>; |
||||||
|
} |
||||||
|
|
||||||
|
/// A connection to a `Store`
|
||||||
|
pub trait StoreConnection: StringStore + Sized + Clone { |
||||||
|
fn contains(&self, quad: &EncodedQuad) -> Result<bool>; |
||||||
|
fn insert(&self, quad: &EncodedQuad) -> Result<()>; |
||||||
|
fn remove(&self, quad: &EncodedQuad) -> Result<()>; |
||||||
|
fn quads_for_pattern<'a>( |
||||||
|
&'a self, |
||||||
|
subject: Option<EncodedTerm>, |
||||||
|
predicate: Option<EncodedTerm>, |
||||||
|
object: Option<EncodedTerm>, |
||||||
|
graph_name: Option<EncodedTerm>, |
||||||
|
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a>; |
||||||
|
fn encoder(&self) -> Encoder<&Self> { |
||||||
|
Encoder::new(&self) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// A `RepositoryConnection` from a `StoreConnection`
|
||||||
|
#[derive(Clone)] |
||||||
|
pub struct StoreRepositoryConnection<S: StoreConnection> { |
||||||
|
inner: S, |
||||||
|
} |
||||||
|
|
||||||
|
impl<S: StoreConnection> From<S> for StoreRepositoryConnection<S> { |
||||||
|
fn from(inner: S) -> Self { |
||||||
|
Self { inner } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl<S: StoreConnection> RepositoryConnection for StoreRepositoryConnection<S> { |
||||||
|
type PreparedQuery = SimplePreparedQuery<S>; |
||||||
|
|
||||||
|
fn prepare_query(&self, query: impl Read) -> Result<SimplePreparedQuery<S>> { |
||||||
|
SimplePreparedQuery::new(self.inner.clone(), query) //TODO: avoid clone
|
||||||
|
} |
||||||
|
|
||||||
|
fn quads_for_pattern<'a>( |
||||||
|
&'a self, |
||||||
|
subject: Option<&NamedOrBlankNode>, |
||||||
|
predicate: Option<&NamedNode>, |
||||||
|
object: Option<&Term>, |
||||||
|
graph_name: Option<&NamedOrBlankNode>, |
||||||
|
) -> Box<dyn Iterator<Item = Result<Quad>> + 'a> |
||||||
|
where |
||||||
|
Self: 'a, |
||||||
|
{ |
||||||
|
let encoder = self.inner.encoder(); |
||||||
|
let subject = if let Some(subject) = subject { |
||||||
|
match encoder.encode_named_or_blank_node(subject) { |
||||||
|
Ok(subject) => Some(subject), |
||||||
|
Err(error) => return Box::new(once(Err(error))), |
||||||
|
} |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
let predicate = if let Some(predicate) = predicate { |
||||||
|
match encoder.encode_named_node(predicate) { |
||||||
|
Ok(predicate) => Some(predicate), |
||||||
|
Err(error) => return Box::new(once(Err(error))), |
||||||
|
} |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
let object = if let Some(object) = object { |
||||||
|
match encoder.encode_term(object) { |
||||||
|
Ok(object) => Some(object), |
||||||
|
Err(error) => return Box::new(once(Err(error))), |
||||||
|
} |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
let graph_name = if let Some(graph_name) = graph_name { |
||||||
|
match encoder.encode_named_or_blank_node(graph_name) { |
||||||
|
Ok(subject) => Some(subject), |
||||||
|
Err(error) => return Box::new(once(Err(error))), |
||||||
|
} |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
|
||||||
|
Box::new( |
||||||
|
self.inner |
||||||
|
.quads_for_pattern(subject, predicate, object, graph_name) |
||||||
|
.map(move |quad| self.inner.encoder().decode_quad(&quad?)), |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
fn contains(&self, quad: &Quad) -> Result<bool> { |
||||||
|
self.inner |
||||||
|
.contains(&self.inner.encoder().encode_quad(quad)?) |
||||||
|
} |
||||||
|
|
||||||
|
fn insert(&self, quad: &Quad) -> Result<()> { |
||||||
|
self.inner.insert(&self.inner.encoder().encode_quad(quad)?) |
||||||
|
} |
||||||
|
|
||||||
|
fn remove(&self, quad: &Quad) -> Result<()> { |
||||||
|
self.inner.remove(&self.inner.encoder().encode_quad(quad)?) |
||||||
|
} |
||||||
|
} |
||||||
|
Loading…
Reference in new issue