pub struct Store { /* private fields */ }
Expand description
An on-disk RDF dataset. Allows to query and update it using SPARQL. It is based on the RocksDB key-value store.
This store ensures the “repeatable read” isolation level: the store only exposes changes that have been “committed” (i.e. no partial writes) and the exposed state does not change for the complete duration of a read operation (e.g. a SPARQL query) or a read/write operation (e.g. a SPARQL update).
Usage example:
use oxigraph::model::*;
use oxigraph::sparql::QueryResults;
use oxigraph::store::Store;
let store = Store::open("example.db")?;
// insertion
let ex = NamedNode::new("http://example.com")?;
let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), GraphName::DefaultGraph);
store.insert(&quad)?;
// quad filter
let results: Result<Vec<Quad>, _> = store.quads_for_pattern(None, None, None, None).collect();
assert_eq!(vec![quad], results?);
// SPARQL query
if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }")? {
assert_eq!(solutions.next().unwrap()?.get("s"), Some(&ex.into()));
};
Implementations§
Source§impl Store
impl Store
Sourcepub fn new() -> Result<Self, StorageError>
pub fn new() -> Result<Self, StorageError>
New in-memory Store
without RocksDB.
Sourcepub fn query(
&self,
query: impl TryInto<Query, Error = impl Into<EvaluationError>>,
) -> Result<QueryResults, EvaluationError>
pub fn query( &self, query: impl TryInto<Query, Error = impl Into<EvaluationError>>, ) -> Result<QueryResults, EvaluationError>
Executes a SPARQL 1.1 query.
Usage example:
use oxigraph::model::*;
use oxigraph::sparql::QueryResults;
use oxigraph::store::Store;
let store = Store::new()?;
// insertions
let ex = NamedNodeRef::new("http://example.com")?;
store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?;
// SPARQL query
if let QueryResults::Solutions(mut solutions) = store.query("SELECT ?s WHERE { ?s ?p ?o }")? {
assert_eq!(
solutions.next().unwrap()?.get("s"),
Some(&ex.into_owned().into())
);
}
Sourcepub fn query_opt(
&self,
query: impl TryInto<Query, Error = impl Into<EvaluationError>>,
options: QueryOptions,
) -> Result<QueryResults, EvaluationError>
pub fn query_opt( &self, query: impl TryInto<Query, Error = impl Into<EvaluationError>>, options: QueryOptions, ) -> Result<QueryResults, EvaluationError>
Executes a SPARQL 1.1 query with some options.
Usage example with a custom function serializing terms to N-Triples:
use oxigraph::model::*;
use oxigraph::sparql::{QueryOptions, QueryResults};
use oxigraph::store::Store;
let store = Store::new()?;
if let QueryResults::Solutions(mut solutions) = store.query_opt(
"SELECT (<http://www.w3.org/ns/formats/N-Triples>(1) AS ?nt) WHERE {}",
QueryOptions::default().with_custom_function(
NamedNode::new("http://www.w3.org/ns/formats/N-Triples")?,
|args| args.get(0).map(|t| Literal::from(t.to_string()).into()),
),
)? {
assert_eq!(
solutions.next().unwrap()?.get("nt"),
Some(&Literal::from("\"1\"^^<http://www.w3.org/2001/XMLSchema#integer>").into())
);
}
Sourcepub fn explain_query_opt(
&self,
query: impl TryInto<Query, Error = impl Into<EvaluationError>>,
options: QueryOptions,
with_stats: bool,
) -> Result<(Result<QueryResults, EvaluationError>, QueryExplanation), EvaluationError>
pub fn explain_query_opt( &self, query: impl TryInto<Query, Error = impl Into<EvaluationError>>, options: QueryOptions, with_stats: bool, ) -> Result<(Result<QueryResults, EvaluationError>, QueryExplanation), EvaluationError>
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 oxigraph::sparql::{QueryOptions, QueryResults};
use oxigraph::store::Store;
let store = Store::new()?;
if let (Ok(QueryResults::Solutions(solutions)), explanation) = store.explain_query_opt(
"SELECT ?s WHERE { VALUES ?s { 1 2 3 } }",
QueryOptions::default(),
true,
)? {
// We make sure to have read all the solutions
for _ in solutions {}
let mut buf = Vec::new();
explanation.write_in_json(&mut buf)?;
}
Sourcepub fn quads_for_pattern(
&self,
subject: Option<SubjectRef<'_>>,
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> QuadIter ⓘ
pub fn quads_for_pattern( &self, subject: Option<SubjectRef<'_>>, predicate: Option<NamedNodeRef<'_>>, object: Option<TermRef<'_>>, graph_name: Option<GraphNameRef<'_>>, ) -> QuadIter ⓘ
Retrieves quads with a filter on each quad component
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
// insertion
let ex = NamedNode::new("http://example.com")?;
let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), GraphName::DefaultGraph);
store.insert(&quad)?;
// quad filter by object
let results = store
.quads_for_pattern(None, None, Some((&ex).into()), None)
.collect::<Result<Vec<_>, _>>()?;
assert_eq!(vec![quad], results);
Sourcepub fn iter(&self) -> QuadIter ⓘ
pub fn iter(&self) -> QuadIter ⓘ
Returns all the quads contained in the store.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
// insertion
let ex = NamedNode::new("http://example.com")?;
let quad = Quad::new(ex.clone(), ex.clone(), ex.clone(), GraphName::DefaultGraph);
store.insert(&quad)?;
// quad filter by object
let results = store.iter().collect::<Result<Vec<_>, _>>()?;
assert_eq!(vec![quad], results);
Sourcepub fn contains<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, StorageError>
pub fn contains<'a>( &self, quad: impl Into<QuadRef<'a>>, ) -> Result<bool, StorageError>
Checks if this store contains a given quad.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, ex);
let store = Store::new()?;
assert!(!store.contains(quad)?);
store.insert(quad)?;
assert!(store.contains(quad)?);
Sourcepub fn len(&self) -> Result<usize, StorageError>
pub fn len(&self) -> Result<usize, StorageError>
Returns the number of quads in the store.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let store = Store::new()?;
store.insert(QuadRef::new(ex, ex, ex, ex))?;
store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?;
assert_eq!(2, store.len()?);
Sourcepub fn is_empty(&self) -> Result<bool, StorageError>
pub fn is_empty(&self) -> Result<bool, StorageError>
Returns if the store is empty.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
assert!(store.is_empty()?);
let ex = NamedNodeRef::new("http://example.com")?;
store.insert(QuadRef::new(ex, ex, ex, ex))?;
assert!(!store.is_empty()?);
Sourcepub fn transaction<T, E: Error + 'static + From<StorageError>>(
&self,
f: impl for<'a> Fn(Transaction<'a>) -> Result<T, E>,
) -> Result<T, E>
pub fn transaction<T, E: Error + 'static + From<StorageError>>( &self, f: impl for<'a> Fn(Transaction<'a>) -> Result<T, E>, ) -> Result<T, E>
Executes a transaction.
Transactions ensure the “repeatable read” isolation level: the store only exposes changes that have been “committed” (i.e. no partial writes) and the exposed state does not change for the complete duration of a read operation (e.g. a SPARQL query) or a read/write operation (e.g. a SPARQL update).
Usage example:
use oxigraph::model::*;
use oxigraph::store::{StorageError, Store};
let store = Store::new()?;
let a = NamedNodeRef::new("http://example.com/a")?;
let b = NamedNodeRef::new("http://example.com/b")?;
// Copy all triples about ex:a to triples about ex:b
store.transaction(|mut transaction| {
for q in transaction.quads_for_pattern(Some(a.into()), None, None, None) {
let q = q?;
transaction.insert(QuadRef::new(b, &q.predicate, &q.object, &q.graph_name))?;
}
Result::<_, StorageError>::Ok(())
})?;
Sourcepub fn update(
&self,
update: impl TryInto<Update, Error = impl Into<EvaluationError>>,
) -> Result<(), EvaluationError>
pub fn update( &self, update: impl TryInto<Update, Error = impl Into<EvaluationError>>, ) -> Result<(), EvaluationError>
Executes a SPARQL 1.1 update.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
// insertion
store
.update("INSERT DATA { <http://example.com> <http://example.com> <http://example.com> }")?;
// we inspect the store contents
let ex = NamedNodeRef::new("http://example.com")?;
assert!(store.contains(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?);
Sourcepub fn update_opt(
&self,
update: impl TryInto<Update, Error = impl Into<EvaluationError>>,
options: impl Into<UpdateOptions>,
) -> Result<(), EvaluationError>
pub fn update_opt( &self, update: impl TryInto<Update, Error = impl Into<EvaluationError>>, options: impl Into<UpdateOptions>, ) -> Result<(), EvaluationError>
Executes a SPARQL 1.1 update with some options.
use oxigraph::store::Store;
use oxigraph::model::*;
use oxigraph::sparql::QueryOptions;
let store = Store::new()?;
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().with_custom_function(
NamedNode::new("http://www.w3.org/ns/formats/N-Triples")?,
|args| args.get(0).map(|t| Literal::from(t.to_string()).into())
)
)?;
Sourcepub fn load_from_reader(
&self,
parser: impl Into<RdfParser>,
reader: impl Read,
) -> Result<(), LoaderError>
pub 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. To get much better performances you might want to use the bulk_loader
.
Usage example:
use oxigraph::store::Store;
use oxigraph::io::RdfFormat;
use oxigraph::model::*;
use oxrdfio::RdfParser;
let store = Store::new()?;
// 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())?;
// 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()
)?;
// 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")?))?);
assert!(store.contains(QuadRef::new(ex, ex, ex, NamedNodeRef::new("http://example.com/g2")?))?);
Sourcepub fn load_graph(
&self,
reader: impl Read,
format: impl Into<RdfFormat>,
to_graph_name: impl Into<GraphName>,
base_iri: Option<&str>,
) -> Result<(), LoaderError>
👎Deprecated since 0.4.0: use Store.load_from_reader instead
pub fn load_graph( &self, reader: impl Read, format: impl Into<RdfFormat>, to_graph_name: impl Into<GraphName>, base_iri: Option<&str>, ) -> Result<(), LoaderError>
Loads a graph file (i.e. triples) into the store.
This function is atomic, quite slow and memory hungry. To get much better performances you might want to use the bulk_loader
.
Usage example:
use oxigraph::io::RdfFormat;
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
// insertion
let file = b"<http://example.com> <http://example.com> <http://example.com> .";
store.load_graph(
file.as_ref(),
RdfFormat::NTriples,
GraphName::DefaultGraph,
None,
)?;
// we inspect the store contents
let ex = NamedNodeRef::new("http://example.com")?;
assert!(store.contains(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?);
Sourcepub fn load_dataset(
&self,
reader: impl Read,
format: impl Into<RdfFormat>,
base_iri: Option<&str>,
) -> Result<(), LoaderError>
👎Deprecated since 0.4.0: use Store.load_from_reader instead
pub fn load_dataset( &self, reader: impl Read, format: impl Into<RdfFormat>, base_iri: Option<&str>, ) -> Result<(), LoaderError>
Loads a dataset file (i.e. quads) into the store.
This function is atomic, quite slow and memory hungry. To get much better performances you might want to use the bulk_loader
.
Usage example:
use oxigraph::io::RdfFormat;
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
// insertion
let file =
b"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .";
store.load_dataset(file.as_ref(), RdfFormat::NQuads, None)?;
// we inspect the store contents
let ex = NamedNodeRef::new("http://example.com")?;
assert!(store.contains(QuadRef::new(ex, ex, ex, ex))?);
Sourcepub fn insert<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, StorageError>
pub 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 oxigraph::model::*;
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph);
let store = Store::new()?;
assert!(store.insert(quad)?);
assert!(!store.insert(quad)?);
assert!(store.contains(quad)?);
Sourcepub fn extend(
&self,
quads: impl IntoIterator<Item = impl Into<Quad>>,
) -> Result<(), StorageError>
pub fn extend( &self, quads: impl IntoIterator<Item = impl Into<Quad>>, ) -> Result<(), StorageError>
Adds atomically a set of quads to this store.
This operation uses a memory heavy transaction internally, use the bulk_loader
if you plan to add ten of millions of triples.
Sourcepub fn remove<'a>(
&self,
quad: impl Into<QuadRef<'a>>,
) -> Result<bool, StorageError>
pub 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 oxigraph::model::*;
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph);
let store = Store::new()?;
store.insert(quad)?;
assert!(store.remove(quad)?);
assert!(!store.remove(quad)?);
assert!(!store.contains(quad)?);
Sourcepub fn dump_to_writer<W: Write>(
&self,
serializer: impl Into<RdfSerializer>,
writer: W,
) -> Result<W, SerializerError>
pub fn dump_to_writer<W: Write>( &self, serializer: impl Into<RdfSerializer>, writer: W, ) -> Result<W, SerializerError>
Dumps the store into a file.
use oxigraph::io::RdfFormat;
use oxigraph::store::Store;
let file =
"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .\n"
.as_bytes();
let store = Store::new()?;
store.load_from_reader(RdfFormat::NQuads, file)?;
let buffer = store.dump_to_writer(RdfFormat::NQuads, Vec::new())?;
assert_eq!(file, buffer.as_slice());
Sourcepub 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 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 oxigraph::io::RdfFormat;
use oxigraph::model::*;
use oxigraph::store::Store;
let file = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
let store = Store::new()?;
store.load_graph(file, RdfFormat::NTriples, GraphName::DefaultGraph, None)?;
let mut buffer = Vec::new();
store.dump_graph_to_writer(GraphNameRef::DefaultGraph, RdfFormat::NTriples, &mut buffer)?;
assert_eq!(file, buffer.as_slice());
Sourcepub fn dump_graph<'a, W: Write>(
&self,
writer: W,
format: impl Into<RdfFormat>,
from_graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<W, SerializerError>
👎Deprecated since 0.4.0: use Store.dump_graph_to_writer instead
pub fn dump_graph<'a, W: Write>( &self, writer: W, format: impl Into<RdfFormat>, from_graph_name: impl Into<GraphNameRef<'a>>, ) -> Result<W, SerializerError>
Dumps a store graph into a file.
Usage example:
use oxigraph::io::RdfFormat;
use oxigraph::model::*;
use oxigraph::store::Store;
let file = "<http://example.com> <http://example.com> <http://example.com> .\n".as_bytes();
let store = Store::new()?;
store.load_graph(file, RdfFormat::NTriples, GraphName::DefaultGraph, None)?;
let mut buffer = Vec::new();
store.dump_graph(&mut buffer, RdfFormat::NTriples, GraphNameRef::DefaultGraph)?;
assert_eq!(file, buffer.as_slice());
Sourcepub fn dump_dataset<W: Write>(
&self,
writer: W,
format: impl Into<RdfFormat>,
) -> Result<W, SerializerError>
👎Deprecated since 0.4.0: use Store.dump_to_writer instead
pub fn dump_dataset<W: Write>( &self, writer: W, format: impl Into<RdfFormat>, ) -> Result<W, SerializerError>
Dumps the store into a file.
use oxigraph::io::RdfFormat;
use oxigraph::store::Store;
let file =
"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .\n"
.as_bytes();
let store = Store::new()?;
store.load_from_reader(RdfFormat::NQuads, file)?;
let buffer = store.dump_dataset(Vec::new(), RdfFormat::NQuads)?;
assert_eq!(file, buffer.as_slice());
Sourcepub fn named_graphs(&self) -> GraphNameIter ⓘ
pub fn named_graphs(&self) -> GraphNameIter ⓘ
Returns all the store named graphs.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let ex = NamedNode::new("http://example.com")?;
let store = Store::new()?;
store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?;
store.insert(QuadRef::new(&ex, &ex, &ex, GraphNameRef::DefaultGraph))?;
assert_eq!(
vec![NamedOrBlankNode::from(ex)],
store.named_graphs().collect::<Result<Vec<_>, _>>()?
);
Sourcepub fn contains_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, StorageError>
pub fn contains_named_graph<'a>( &self, graph_name: impl Into<NamedOrBlankNodeRef<'a>>, ) -> Result<bool, StorageError>
Checks if the store contains a given graph
Usage example:
use oxigraph::model::{NamedNode, QuadRef};
use oxigraph::store::Store;
let ex = NamedNode::new("http://example.com")?;
let store = Store::new()?;
store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?;
assert!(store.contains_named_graph(&ex)?);
Sourcepub fn insert_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, StorageError>
pub 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 oxigraph::model::NamedNodeRef;
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let store = Store::new()?;
store.insert_named_graph(ex)?;
assert_eq!(
store.named_graphs().collect::<Result<Vec<_>, _>>()?,
vec![ex.into_owned().into()]
);
Sourcepub fn clear_graph<'a>(
&self,
graph_name: impl Into<GraphNameRef<'a>>,
) -> Result<(), StorageError>
pub fn clear_graph<'a>( &self, graph_name: impl Into<GraphNameRef<'a>>, ) -> Result<(), StorageError>
Clears a graph from this store.
Usage example:
use oxigraph::model::{NamedNodeRef, QuadRef};
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, ex);
let store = Store::new()?;
store.insert(quad)?;
assert_eq!(1, store.len()?);
store.clear_graph(ex)?;
assert!(store.is_empty()?);
assert_eq!(1, store.named_graphs().count());
Sourcepub fn remove_named_graph<'a>(
&self,
graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, StorageError>
pub 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 oxigraph::model::{NamedNodeRef, QuadRef};
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let quad = QuadRef::new(ex, ex, ex, ex);
let store = Store::new()?;
store.insert(quad)?;
assert_eq!(1, store.len()?);
assert!(store.remove_named_graph(ex)?);
assert!(store.is_empty()?);
assert_eq!(0, store.named_graphs().count());
Sourcepub fn clear(&self) -> Result<(), StorageError>
pub fn clear(&self) -> Result<(), StorageError>
Clears the store.
Usage example:
use oxigraph::model::*;
use oxigraph::store::Store;
let ex = NamedNodeRef::new("http://example.com")?;
let store = Store::new()?;
store.insert(QuadRef::new(ex, ex, ex, ex))?;
store.insert(QuadRef::new(ex, ex, ex, GraphNameRef::DefaultGraph))?;
assert_eq!(2, store.len()?);
store.clear()?;
assert!(store.is_empty()?);
Sourcepub fn bulk_loader(&self) -> BulkLoader
pub fn bulk_loader(&self) -> BulkLoader
Creates a bulk loader allowing to load at lot of data quickly into the store.
Usage example:
use oxigraph::io::RdfFormat;
use oxigraph::model::*;
use oxigraph::store::Store;
let store = Store::new()?;
// quads file insertion
let file =
b"<http://example.com> <http://example.com> <http://example.com> <http://example.com> .";
store
.bulk_loader()
.load_from_reader(RdfFormat::NQuads, file.as_ref())?;
// we inspect the store contents
let ex = NamedNodeRef::new("http://example.com")?;
assert!(store.contains(QuadRef::new(ex, ex, ex, ex))?);