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:
|
||||
//! * Basic RDF data structures in the `model` package
|
||||
//! * Parsers for XML, Turtle and N-Triples syntaxes in the `rio` package
|
||||
//! * A memory based and a disk based stores in the `store` package
|
||||
//! * A work in progress SPARQL implementation in the `sparql` package
|
||||
|
||||
#![warn(
|
||||
clippy::cast_possible_wrap, |
||||
clippy::cast_precision_loss, |
||||
clippy::cast_sign_loss, |
||||
clippy::default_trait_access, |
||||
clippy::empty_enum, |
||||
clippy::enum_glob_use, |
||||
clippy::expl_impl_clone_on_copy, |
||||
clippy::explicit_into_iter_loop, |
||||
clippy::filter_map, |
||||
clippy::if_not_else, |
||||
clippy::inline_always, |
||||
clippy::invalid_upcast_comparisons, |
||||
clippy::items_after_statements, |
||||
clippy::linkedlist, |
||||
//TODO match_same_arms,
|
||||
clippy::maybe_infinite_iter, |
||||
clippy::mut_mut, |
||||
clippy::needless_continue, |
||||
clippy::option_map_unwrap_or, |
||||
//TODO option_map_unwrap_or_else,
|
||||
clippy::pub_enum_variant_names, |
||||
clippy::replace_consts, |
||||
clippy::result_map_unwrap_or_else, |
||||
//TODO single_match_else,
|
||||
clippy::string_add_assign, |
||||
clippy::unicode_not_nfc |
||||
)] |
||||
//! It currently provides two `Repository` implementation providing [SPARQL 1.0 query](https://www.w3.org/TR/rdf-sparql-query/) capability:
|
||||
//! * `MemoryRepository`: a simple in memory implementation.
|
||||
//! * `RocksDbRepository`: a file system implementation based on the [RocksDB](https://rocksdb.org/) key-value store.
|
||||
//!
|
||||
//! Usage example with the `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()));
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
pub mod model; |
||||
mod repository; |
||||
pub mod rio; |
||||
pub mod sparql; |
||||
pub mod store; |
||||
pub(crate) mod store; |
||||
|
||||
pub use 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; |
||||
pub(crate) mod numeric_encoder; |
||||
#[cfg(feature = "rocksdb")] |
||||
mod rocksdb; |
||||
|
||||
pub use crate::store::memory::MemoryDataset; |
||||
pub use crate::store::memory::MemoryGraph; |
||||
pub use crate::store::memory::MemoryRepository; |
||||
#[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