pub struct Store { /* private fields */ }
Expand description
An RDF dataset store.
The store can be updated and queried using SPARQL.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::execution::results::QueryResults;
use rdf_fusion::store::Store;
use futures::StreamExt;
let store = Store::default();
// insertion
let ex = NamedNode::new("http://example.com")?;
let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), GraphName::DefaultGraph);
store.insert(&quad).await?;
// quad filter
let results = store.quads_for_pattern(None, None, None, None).await?.try_collect_to_vec().await?;
assert_eq!(vec![quad], results);
// SPARQL query
if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }").await? {
assert_eq!(solutions.next().await.unwrap()?.get("s"), Some(&ex.into()));
};
Result::<_, Box<dyn std::error::Error>>::Ok(())
Implementations§
Source§impl Store
impl Store
Sourcepub fn new(context: RdfFusionContext) -> Store
pub fn new(context: RdfFusionContext) -> Store
Creates a Store with the given RdfFusionContext.
Sourcepub fn new_with_datafusion_config(
config: SessionConfig,
runtime_env: Arc<RuntimeEnv>,
) -> Store
pub fn new_with_datafusion_config( config: SessionConfig, runtime_env: Arc<RuntimeEnv>, ) -> Store
Creates a Store with a MemQuadStorage as backing storage using the given config
and
runtime_env
.
Sourcepub fn context(&self) -> &RdfFusionContext
pub fn context(&self) -> &RdfFusionContext
Returns a reference to the underlying RdfFusionContext.
Sourcepub async fn query(
&self,
query: impl TryInto<Query, Error = impl Into<QueryEvaluationError> + Debug>,
) -> Result<QueryResults, QueryEvaluationError>
pub async fn query( &self, query: impl TryInto<Query, Error = impl Into<QueryEvaluationError> + Debug>, ) -> Result<QueryResults, QueryEvaluationError>
Executes a SPARQL query.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::execution::results::QueryResults;
use rdf_fusion::store::Store;
use futures::StreamExt;
let store = Store::default();
// insertions
let ex = NamedNodeRef::new("http://example.com")?;
store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph)).await?;
// SPARQL query
if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }").await? {
assert_eq!(
solutions.next().await.unwrap()?.get("s"),
Some(&ex.into_owned().into())
);
}
Sourcepub async fn query_opt(
&self,
query: impl TryInto<Query, Error = impl Into<QueryEvaluationError> + Debug>,
options: QueryOptions,
) -> Result<QueryResults, QueryEvaluationError>
pub async fn query_opt( &self, query: impl TryInto<Query, Error = impl Into<QueryEvaluationError> + Debug>, options: QueryOptions, ) -> Result<QueryResults, QueryEvaluationError>
Executes a SPARQL 1.1 query with some options.
Usage example with a custom function serializing terms to N-Triples:
use rdf_fusion::model::*;
use rdf_fusion::execution::results::QueryResults;
use rdf_fusion::execution::sparql::QueryOptions;
use rdf_fusion::store::Store;
use futures::StreamExt;
let store = Store::default();
if let QueryResults::Solutions(mut solutions) = store.query_opt(
"SELECT (STR(1) AS ?nt) WHERE {}",
QueryOptions::default(),
).await? {
assert_eq!(
solutions.next().await.unwrap()?.get("nt"),
Some(&Literal::from("1").into())
);
}
Sourcepub async fn explain_query_opt(
&self,
query: impl TryInto<Query, Error = impl Into<QueryEvaluationError> + Debug>,
options: QueryOptions,
) -> Result<(QueryResults, QueryExplanation), QueryEvaluationError>
pub async fn explain_query_opt( &self, query: impl TryInto<Query, Error = impl Into<QueryEvaluationError> + Debug>, options: QueryOptions, ) -> Result<(QueryResults, QueryExplanation), QueryEvaluationError>
Executes a SPARQL 1.1 query with some options and
returns a query explanation with some statistics (if enabled with the with_stats
parameter).
Usage example serialising the explanation with statistics in JSON:
use rdf_fusion::store::Store;
use rdf_fusion::execution::sparql::QueryOptions;
use rdf_fusion::execution::results::QueryResults;
use futures::StreamExt;
let store = Store::default();
if let (QueryResults::Solutions(mut solutions), _explanation) = store.explain_query_opt(
"SELECT ?s WHERE { VALUES ?s { 1 2 3 } }",
QueryOptions::default(),
).await? {
// We make sure to have read all the solutions
while let Some(_) = solutions.next().await { }
// TODO
// let mut buf = Vec::new();
// explanation.write_in_json(&mut buf)?;
}
Sourcepub async fn quads_for_pattern(
&self,
subject: Option<NamedOrBlankNodeRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> Result<QuadStream, QueryEvaluationError>
pub async fn quads_for_pattern( &self, subject: Option<NamedOrBlankNodeRef<'_>>, predicate: Option<NamedNodeRef<'_>>, object: Option<TermRef<'_>>, graph_name: Option<GraphNameRef<'_>>, ) -> Result<QuadStream, QueryEvaluationError>
Retrieves quads with a filter on each quad component
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let store = Store::default();
// insertion
let ex = NamedNode::new("http://example.com")?;
let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), GraphName::DefaultGraph);
store.insert(&quad).await?;
// quad filter by object
let results = store
.quads_for_pattern(None, None, Some((&ex).into()), None).await?
.try_collect_to_vec().await?;
assert_eq!(vec![quad], results);
Sourcepub async fn stream(&self) -> Result<QuadStream, QueryEvaluationError>
pub async fn stream(&self) -> Result<QuadStream, QueryEvaluationError>
Returns all the quads contained in the store.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let store = Store::default();
// insertion
let ex = NamedNode::new("http://example.com")?;
let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), GraphName::DefaultGraph);
store.insert(&quad).await?;
// quad filter by object
let results = store.stream().await?.try_collect_to_vec().await?;
assert_eq!(vec![quad], results);
Sourcepub async fn contains<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, QueryEvaluationError>
pub async fn contains<'a>( &self, quad: impl Into<QuadRef<'a>>, ) -> Result<bool, QueryEvaluationError>
Checks if this store contains a given quad.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, ex);
let store = Store::default();
assert!(!store.contains(quad).await?);
store.insert(quad).await?;
assert!(store.contains(quad).await?);
Sourcepub async fn len(&self) -> Result<usize, QueryEvaluationError>
pub async fn len(&self) -> Result<usize, QueryEvaluationError>
Returns the number of quads in the store.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let store = Store::default();
store.insert(QuadRef::new(ex, ex, ex, ex)).await?;
store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph)).await?;
assert_eq!(2, store.len().await?);
Sourcepub async fn is_empty(&self) -> Result<bool, QueryEvaluationError>
pub async fn is_empty(&self) -> Result<bool, QueryEvaluationError>
Returns if the store is empty.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let store = Store::default();
assert!(store.is_empty().await?);
let ex = NamedNodeRef::new("http://example.com")?;
store.insert(QuadRef::new(ex, ex, ex, ex)).await?;
assert!(!store.is_empty().await?);
Sourcepub async fn update(
&self,
_update: impl TryInto<Update, Error = impl Into<QueryEvaluationError>>,
) -> Result<(), QueryEvaluationError>
pub async fn update( &self, _update: impl TryInto<Update, Error = impl Into<QueryEvaluationError>>, ) -> Result<(), QueryEvaluationError>
Executes a SPARQL 1.1 update.
Usage example:
// use rdf-fusion::model::*;
// use rdf-fusion::store::Store;
// TODO #7: Implement Update
// let store = Store::default();
// insertion
// store
// .update("INSERT DATA { <http://example.com> <http://example.com> <http://example.com> }").await?;
// we inspect the store contents
// let ex = NamedNodeRef::new("http://example.com")?;
// assert!(store.contains(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph)).await?);
Sourcepub async fn update_opt(
&self,
_update: impl TryInto<Update, Error = impl Into<QueryEvaluationError>>,
_options: impl Into<UpdateOptions>,
) -> Result<(), QueryEvaluationError>
pub async fn update_opt( &self, _update: impl TryInto<Update, Error = impl Into<QueryEvaluationError>>, _options: impl Into<UpdateOptions>, ) -> Result<(), QueryEvaluationError>
Executes a SPARQL 1.1 update with some options.
// use rdf-fusion::store::Store;
// use rdf-fusion::sparql::QueryOptions;
// TODO #7: Implement Update
// let store = Store::default();
// store.update_opt(
// "INSERT { ?s <http://example.com/n-triples-representation> ?n } WHERE { ?s ?p ?o BIND(<http://www.w3.org/ns/formats/N-Triples>(?s) AS ?nt) }",
// QueryOptions::default()
//).await?;
Sourcepub async fn load_from_reader(
&self,
parser: impl Into<RdfParser>,
reader: impl Read,
) -> Result<(), LoaderError>
pub async fn load_from_reader( &self, parser: impl Into<RdfParser>, reader: impl Read, ) -> Result<(), LoaderError>
Loads a RDF file under into the store.
This function is atomic, quite slow and memory hungry.
Usage example:
use rdf_fusion::store::Store;
use rdf_fusion::model::*;
use rdf_fusion::io::{RdfParser, RdfFormat};
let store = Store::default();
// insert a dataset file (former load_dataset method)
let file = b"<http://example.com> <http://example.com> <http://example.com> <http://example.com/g> .";
store.load_from_reader(RdfFormat::NQuads, file.as_ref()).await?;
// insert a graph file (former load_graph method)
let file = b"<> <> <> .";
store.load_from_reader(
RdfParser::from_format(RdfFormat::Turtle)
.with_base_iri("http://example.com")?
.without_named_graphs() // No named graphs allowed in the input
.with_default_graph(NamedNodeRef::new("http://example.com/g2")?), // we put the file default graph inside of a named graph
file.as_ref()
).await?;
// we inspect the store contents
let ex = NamedNodeRef::new("http://example.com")?;
assert!(store.contains(QuadRef::new(ex, ex, ex, NamedNodeRef::new("http://example.com/g")?)).await?);
assert!(store.contains(QuadRef::new(ex, ex, ex, NamedNodeRef::new("http://example.com/g2")?)).await?);
Sourcepub async fn insert<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, StorageError>
pub async fn insert<'a>( &self, quad: impl Into<QuadRef<'a>>, ) -> Result<bool, StorageError>
Adds a quad to this store.
Returns true
if the quad was not already in the store.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph);
let store = Store::default();
assert!(store.insert(quad).await?);
assert!(!store.insert(quad).await?);
assert!(store.contains(quad).await?);
Sourcepub async fn extend(
&self,
quads: impl IntoIterator<Item = impl Into<Quad>>,
) -> Result<(), StorageError>
pub async fn extend( &self, quads: impl IntoIterator<Item = impl Into<Quad>>, ) -> Result<(), StorageError>
Atomically adds a set of quads to this store.
Sourcepub async fn remove<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, StorageError>
pub async fn remove<'a>( &self, quad: impl Into<QuadRef<'a>>, ) -> Result<bool, StorageError>
Removes a quad from this store.
Returns true
if the quad was in the store and has been removed.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph);
let store = Store::default();
store.insert(quad).await?;
assert!(store.remove(quad).await?);
assert!(!store.remove(quad).await?);
assert!(!store.contains(quad).await?);
Sourcepub async fn dump_to_writer<W: Write>(
&self,
serializer: impl Into<RdfSerializer>,
writer: W,
) -> Result<W, SerializerError>
pub async fn dump_to_writer<W: Write>( &self, serializer: impl Into<RdfSerializer>, writer: W, ) -> Result<W, SerializerError>
Dumps the store into a file.
use rdf_fusion::store::Store;
use rdf_fusion::io::RdfFormat;
let file =
"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .\n"
.as_bytes();
let store = Store::default();
store.load_from_reader(RdfFormat::NQuads, file).await?;
let buffer = store.dump_to_writer(RdfFormat::NQuads, Vec::new()).await?;
assert_eq!(file, buffer.as_slice());
Sourcepub async fn dump_graph_to_writer<'a, W: Write>(
&self,
from_graph_name: impl Into<GraphNameRef<'a>>,
serializer: impl Into<RdfSerializer>,
writer: W,
) -> Result<W, SerializerError>
pub async fn dump_graph_to_writer<'a, W: Write>( &self, from_graph_name: impl Into<GraphNameRef<'a>>, serializer: impl Into<RdfSerializer>, writer: W, ) -> Result<W, SerializerError>
Dumps a store graph into a file.
Usage example:
use rdf_fusion::io::{RdfParser, RdfFormat};
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let file = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
let store = Store::default();
let parser = RdfParser::from_format(RdfFormat::NTriples);
store.load_from_reader(parser, file.as_ref()).await?;
let mut buffer = Vec::new();
store.dump_graph_to_writer(GraphNameRef::DefaultGraph, RdfFormat::NTriples, &mut buffer).await?;
assert_eq!(file, buffer.as_slice());
Sourcepub async fn named_graphs(&self) -> Result<Vec<NamedOrBlankNode>, StorageError>
pub async fn named_graphs(&self) -> Result<Vec<NamedOrBlankNode>, StorageError>
Returns all the store named graphs.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let ex = NamedNode::new("http://example.com")?;
let store = Store::default();
store.insert(QuadRef::new(&ex, &ex, &ex, &ex)).await?;
store.insert(QuadRef::new(&ex, &ex, &ex, GraphNameRef::DefaultGraph)).await?;
assert_eq!(
vec![NamedOrBlankNode::from(ex)],
store.named_graphs().await?
);
Sourcepub async fn contains_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, QueryEvaluationError>
pub async fn contains_named_graph<'a>( &self, graph_name: impl Into<NamedOrBlankNodeRef<'a>>, ) -> Result<bool, QueryEvaluationError>
Checks if the store contains a given graph
Usage example:
use rdf_fusion::model::{NamedNode, QuadRef};
use rdf_fusion::store::Store;
let ex = NamedNode::new("http://example.com")?;
let store = Store::default();
store.insert(QuadRef::new(&ex, &ex, &ex, &ex)).await?;
assert!(store.contains_named_graph(&ex).await?);
Sourcepub async fn insert_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, StorageError>
pub async fn insert_named_graph<'a>( &self, graph_name: impl Into<NamedOrBlankNodeRef<'a>>, ) -> Result<bool, StorageError>
Inserts a graph into this store.
Returns true
if the graph was not already in the store.
Usage example:
use rdf_fusion::model::NamedNodeRef;
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let store = Store::default();
store.insert_named_graph(ex).await?;
assert_eq!(
store.named_graphs().await?,
vec![ex.into_owned().into()]
);
Sourcepub async fn clear_graph<'a>(
&self,
graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<(), StorageError>
pub async fn clear_graph<'a>( &self, graph_name: impl Into<GraphNameRef<'a>>, ) -> Result<(), StorageError>
Clears a graph from this store.
Usage example:
use rdf_fusion::model::{NamedNodeRef, QuadRef};
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, ex);
let store = Store::default();
store.insert(quad).await?;
assert_eq!(1, store.len().await?);
store.clear_graph(ex).await?;
assert!(store.is_empty().await?);
assert_eq!(1, store.named_graphs().await?.len());
Sourcepub async fn remove_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, StorageError>
pub async fn remove_named_graph<'a>( &self, graph_name: impl Into<NamedOrBlankNodeRef<'a>>, ) -> Result<bool, StorageError>
Removes a graph from this store.
Returns true
if the graph was in the store and has been removed.
Usage example:
use rdf_fusion::model::{NamedNodeRef, QuadRef};
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, ex);
let store = Store::default();
store.insert(quad).await?;
assert_eq!(1, store.len().await?);
assert!(store.remove_named_graph(ex).await?);
assert!(store.is_empty().await?);
assert_eq!(0, store.named_graphs().await?.len());
Sourcepub async fn clear(&self) -> Result<(), StorageError>
pub async fn clear(&self) -> Result<(), StorageError>
Clears the store.
Usage example:
use rdf_fusion::model::*;
use rdf_fusion::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let store = Store::default();
store.insert(QuadRef::new(ex, ex, ex, ex)).await?;
store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph)).await?;
assert_eq!(2, store.len().await?);
store.clear().await?;
assert!(store.is_empty().await?);
Sourcepub async fn optimize(&self) -> Result<(), StorageError>
pub async fn optimize(&self) -> Result<(), StorageError>
Optimizes the database for future workload.
Useful to call after a batch upload or another similar operation. Usually
Sourcepub async fn validate(&self) -> Result<(), StorageError>
pub async fn validate(&self) -> Result<(), StorageError>
Validates that all the store invariants hold in the data storage
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Store
impl !RefUnwindSafe for Store
impl Send for Store
impl Sync for Store
impl Unpin for Store
impl !UnwindSafe for Store
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more