Adds concrete PreparedQuery structs and deprecates the trait

Allows to explicitly state the type of prepared queries
pull/41/head
Tpt 5 years ago
parent 966d3d8f40
commit 3f3406e1a0
  1. 2
      js/src/store.rs
  2. 3
      lib/Cargo.toml
  3. 7
      lib/src/lib.rs
  4. 2
      lib/src/sparql/eval.rs
  5. 19
      lib/src/sparql/mod.rs
  6. 4
      lib/src/sparql/model.rs
  7. 2
      lib/src/sparql/plan.rs
  8. 36
      lib/src/store/memory.rs
  9. 18
      lib/src/store/mod.rs
  10. 34
      lib/src/store/rocksdb.rs
  11. 32
      lib/src/store/sled.rs
  12. 2
      lib/tests/wasm.rs
  13. 2
      server/src/main.rs
  14. 2
      wikibase/src/main.rs

@ -3,7 +3,7 @@ use crate::model::*;
use crate::utils::to_err;
use js_sys::{Array, Map};
use oxigraph::model::NamedOrBlankNode;
use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult};
use oxigraph::sparql::{QueryOptions, QueryResult};
use oxigraph::{DatasetSyntax, Error, FileSyntax, GraphSyntax, MemoryStore};
use std::convert::TryInto;
use std::io::Cursor;

@ -11,6 +11,9 @@ An RDF and SPARQL library in Rust
"""
edition = "2018"
[package.metadata.docs.rs]
all-features = true
[dependencies]
lazy_static = "1"
rocksdb = { version = "0.14", optional = true }

@ -17,7 +17,7 @@
//! ```
//! use oxigraph::model::*;
//! use oxigraph::{MemoryStore, Result};
//! use crate::oxigraph::sparql::{PreparedQuery, QueryOptions};
//! use crate::oxigraph::sparql::QueryOptions;
//! use oxigraph::sparql::QueryResult;
//!
//! let store = MemoryStore::default();
@ -110,17 +110,14 @@
mod error;
pub mod model;
pub mod sparql;
pub(crate) mod store;
pub mod store;
mod syntax;
pub use error::Error;
pub type Result<T> = ::std::result::Result<T, Error>;
pub use crate::store::MemoryStore;
pub use crate::store::MemoryTransaction;
#[cfg(feature = "rocksdb")]
pub use crate::store::RocksDbStore;
#[cfg(feature = "rocksdb")]
pub use crate::store::RocksDbTransaction;
#[cfg(feature = "sled")]
pub use crate::store::SledStore;
pub use crate::syntax::DatasetSyntax;

@ -31,7 +31,7 @@ const REGEX_SIZE_LIMIT: usize = 1_000_000;
type EncodedTuplesIterator<'a> = Box<dyn Iterator<Item = Result<EncodedTuple>> + 'a>;
pub struct SimpleEvaluator<S: ReadableEncodedStore> {
pub(crate) struct SimpleEvaluator<S: ReadableEncodedStore> {
dataset: DatasetView<S>,
base_iri: Option<Iri<String>>,
bnodes_map: Mutex<BTreeMap<StrHash, u128>>,

@ -32,12 +32,12 @@ pub use crate::sparql::parser::Query;
pub use crate::sparql::parser::SparqlParseError;
/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/)
pub trait PreparedQuery {
/// Evaluates the query and returns its results
fn exec(&self) -> Result<QueryResult<'_>>;
}
#[deprecated(
note = "Not useful anymore. The exec method is already implemented by the different PreparedQuery structures"
)]
pub trait PreparedQuery {}
/// An implementation of `PreparedQuery` for internal use
/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/)
pub(crate) struct SimplePreparedQuery<S: ReadableEncodedStore>(SimplePreparedQueryAction<S>);
enum SimplePreparedQueryAction<S: ReadableEncodedStore> {
@ -61,7 +61,7 @@ enum SimplePreparedQueryAction<S: ReadableEncodedStore> {
},
}
impl<'a, S: ReadableEncodedStore + 'a> SimplePreparedQuery<S> {
impl<S: ReadableEncodedStore> SimplePreparedQuery<S> {
pub(crate) fn new(store: S, query: &str, options: QueryOptions<'_>) -> Result<Self> {
let dataset = DatasetView::new(store, options.default_graph_as_union);
Ok(Self(match Query::parse(query, options.base_iri)?.0 {
@ -132,10 +132,9 @@ impl<'a, S: ReadableEncodedStore + 'a> SimplePreparedQuery<S> {
evaluator: SimpleEvaluator::new(dataset, base_iri, options.service_handler),
}))
}
}
impl<S: ReadableEncodedStore> PreparedQuery for SimplePreparedQuery<S> {
fn exec(&self) -> Result<QueryResult<'_>> {
/// Evaluates the query and returns its results
pub fn exec(&self) -> Result<QueryResult<'_>> {
match &self.0 {
SimplePreparedQueryAction::Select {
plan,
@ -209,7 +208,7 @@ impl<'a> Default for QueryOptions<'a> {
}
impl<'a> QueryOptions<'a> {
/// Allows to set the base IRI of the query
/// Allows setting the base IRI of the query
pub fn with_base_iri(mut self, base_iri: &'a str) -> Self {
self.base_iri = Some(base_iri);
self

@ -124,7 +124,7 @@ impl FileSyntax for QueryResultSyntax {
///
/// ```
/// use oxigraph::{MemoryStore, Result};
/// use oxigraph::sparql::{PreparedQuery, QueryResult, QueryOptions, Variable};
/// use oxigraph::sparql::{QueryResult, QueryOptions};
///
/// let store = MemoryStore::new();
/// let prepared_query = store.prepare_query("SELECT ?s WHERE { ?s ?p ?o }", QueryOptions::default())?;
@ -155,7 +155,7 @@ impl<'a> QuerySolutionsIterator<'a> {
///
/// ```
/// use oxigraph::{MemoryStore, Result};
/// use oxigraph::sparql::{PreparedQuery, QueryResult, QueryOptions, Variable};
/// use oxigraph::sparql::{QueryResult, QueryOptions, Variable};
///
/// let store = MemoryStore::new();
/// let prepared_query = store.prepare_query("SELECT ?s ?o WHERE { ?s ?p ?o }", QueryOptions::default())?;

@ -553,7 +553,7 @@ impl EncodedTuple {
}
}
pub struct DatasetView<S: ReadableEncodedStore> {
pub(crate) struct DatasetView<S: ReadableEncodedStore> {
store: S,
extra: RefCell<MemoryStrStore>,
default_graph_as_union: bool,

@ -1,5 +1,7 @@
//! In-memory store.
use crate::model::*;
use crate::sparql::{PreparedQuery, QueryOptions, SimplePreparedQuery};
use crate::sparql::{QueryOptions, QueryResult, SimplePreparedQuery};
use crate::store::numeric_encoder::*;
use crate::store::*;
use crate::{DatasetSyntax, GraphSyntax, Result};
@ -8,7 +10,7 @@ use std::hash::Hash;
use std::io::BufRead;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
/// Memory based store.
/// In-memory store.
/// It encodes a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) and allows to query and update it using SPARQL.
/// It is cheap to build using the `MemoryStore::new()` method.
///
@ -16,7 +18,7 @@ use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
/// ```
/// use oxigraph::model::*;
/// use oxigraph::{MemoryStore, Result};
/// use oxigraph::sparql::{PreparedQuery, QueryResult, QueryOptions};
/// use oxigraph::sparql::{QueryResult, QueryOptions};
///
/// let store = MemoryStore::new();
///
@ -77,7 +79,7 @@ impl MemoryStore {
/// ```
/// use oxigraph::model::*;
/// use oxigraph::{MemoryStore, Result};
/// use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult};
/// use oxigraph::sparql::{QueryOptions, QueryResult};
///
/// let store = MemoryStore::default();
///
@ -96,8 +98,12 @@ impl MemoryStore {
&self,
query: &str,
options: QueryOptions<'_>,
) -> Result<impl PreparedQuery> {
SimplePreparedQuery::new(self.clone(), query, options)
) -> Result<MemoryPreparedQuery> {
Ok(MemoryPreparedQuery(SimplePreparedQuery::new(
self.clone(),
query,
options,
)?))
}
/// This is similar to `prepare_query`, but useful if a SPARQL query has already been parsed, which is the case when building `ServiceHandler`s for federated queries with `SERVICE` clauses. For examples, look in the tests.
@ -105,8 +111,12 @@ impl MemoryStore {
&self,
graph_pattern: &GraphPattern,
options: QueryOptions<'_>,
) -> Result<impl PreparedQuery> {
SimplePreparedQuery::new_from_pattern(self.clone(), graph_pattern, options)
) -> Result<MemoryPreparedQuery> {
Ok(MemoryPreparedQuery(SimplePreparedQuery::new_from_pattern(
self.clone(),
graph_pattern,
options,
)?))
}
/// Retrieves quads with a filter on each quad component
@ -785,6 +795,16 @@ fn quad_map_flatten<'a, T: Copy>(gspo: &'a QuadMap<T>) -> impl Iterator<Item = (
})
}
/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/) for the `MemoryStore`.
pub struct MemoryPreparedQuery(SimplePreparedQuery<MemoryStore>);
impl MemoryPreparedQuery {
/// Evaluates the query and returns its results
pub fn exec(&self) -> Result<QueryResult<'_>> {
self.0.exec()
}
}
/// Allows to insert and delete quads during a transaction with the `MemoryStore`.
pub struct MemoryTransaction<'a> {
store: &'a MemoryStore,

@ -1,19 +1,19 @@
//! Store implementations
//! RDF quads storage implementations.
//!
//! They encode a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
//! and allow to query and update it using SPARQL.
mod memory;
pub mod memory;
pub(crate) mod numeric_encoder;
#[cfg(feature = "rocksdb")]
mod rocksdb;
pub mod rocksdb;
#[cfg(feature = "sled")]
mod sled;
pub mod sled;
use crate::sparql::GraphPattern;
pub use crate::store::memory::MemoryStore;
pub use crate::store::memory::MemoryTransaction;
#[cfg(feature = "rocksdb")]
pub use crate::store::rocksdb::RocksDbStore;
#[cfg(feature = "rocksdb")]
pub use crate::store::rocksdb::RocksDbTransaction;
#[cfg(feature = "sled")]
pub use crate::store::sled::SledStore;
@ -27,7 +27,7 @@ use std::collections::HashMap;
use std::io::BufRead;
use std::iter::Iterator;
pub trait ReadableEncodedStore: StrLookup + Sized {
pub(crate) trait ReadableEncodedStore: StrLookup {
fn encoded_quads_for_pattern<'a>(
&'a self,
subject: Option<EncodedTerm>,
@ -37,7 +37,7 @@ pub trait ReadableEncodedStore: StrLookup + Sized {
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a>;
}
pub trait WritableEncodedStore: StrContainer + Sized {
pub(crate) trait WritableEncodedStore: StrContainer {
fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<()>;
fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<()>;

@ -1,5 +1,7 @@
//! Store based on the [RocksDB](https://rocksdb.org/) key-value database.
use crate::model::*;
use crate::sparql::{GraphPattern, PreparedQuery, QueryOptions, SimplePreparedQuery};
use crate::sparql::{GraphPattern, QueryOptions, QueryResult, SimplePreparedQuery};
use crate::store::numeric_encoder::*;
use crate::store::{load_dataset, load_graph, ReadableEncodedStore, WritableEncodedStore};
use crate::{DatasetSyntax, GraphSyntax, Result};
@ -19,7 +21,7 @@ use std::sync::Arc;
/// ```
/// use oxigraph::model::*;
/// use oxigraph::{Result, RocksDbStore};
/// use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult};
/// use oxigraph::sparql::{QueryOptions, QueryResult};
/// # use std::fs::remove_dir_all;
///
/// # {
@ -104,8 +106,12 @@ impl RocksDbStore {
&'a self,
query: &str,
options: QueryOptions<'_>,
) -> Result<impl PreparedQuery + 'a> {
SimplePreparedQuery::new((*self).clone(), query, options)
) -> Result<RocksDbPreparedQuery> {
Ok(RocksDbPreparedQuery(SimplePreparedQuery::new(
(*self).clone(),
query,
options,
)?))
}
/// This is similar to `prepare_query`, but useful if a SPARQL query has already been parsed, which is the case when building `ServiceHandler`s for federated queries with `SERVICE` clauses. For examples, look in the tests.
@ -113,8 +119,12 @@ impl RocksDbStore {
&'a self,
graph_pattern: &GraphPattern,
options: QueryOptions<'_>,
) -> Result<impl PreparedQuery + 'a> {
SimplePreparedQuery::new_from_pattern((*self).clone(), graph_pattern, options)
) -> Result<RocksDbPreparedQuery> {
Ok(RocksDbPreparedQuery(SimplePreparedQuery::new_from_pattern(
(*self).clone(),
graph_pattern,
options,
)?))
}
/// Retrieves quads with a filter on each quad component
@ -485,6 +495,16 @@ impl<'a> RocksDbStoreHandle<'a> {
}
}
/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/) for the `RocksDbStore`.
pub struct RocksDbPreparedQuery(SimplePreparedQuery<RocksDbStore>);
impl RocksDbPreparedQuery {
/// Evaluates the query and returns its results
pub fn exec(&self) -> Result<QueryResult<'_>> {
self.0.exec()
}
}
/// Allows to insert and delete quads during a transaction with the `RocksDbStore`.
pub struct RocksDbTransaction<'a> {
inner: RocksDbInnerTransaction<'a>,
@ -558,7 +578,7 @@ impl RocksDbTransaction<'_> {
}
}
pub struct RocksDbAutoTransaction<'a> {
struct RocksDbAutoTransaction<'a> {
inner: RocksDbInnerTransaction<'a>,
}

@ -1,5 +1,7 @@
//! Store based on the [Sled](https://sled.rs/) key-value database.
use crate::model::*;
use crate::sparql::{GraphPattern, PreparedQuery, QueryOptions, SimplePreparedQuery};
use crate::sparql::{GraphPattern, QueryOptions, QueryResult, SimplePreparedQuery};
use crate::store::numeric_encoder::*;
use crate::store::{load_dataset, load_graph, ReadableEncodedStore, WritableEncodedStore};
use crate::{DatasetSyntax, GraphSyntax, Result};
@ -19,7 +21,7 @@ use std::str;
/// ```
/// use oxigraph::model::*;
/// use oxigraph::{Result, SledStore};
/// use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult};
/// use oxigraph::sparql::{QueryOptions, QueryResult};
/// # use std::fs::remove_dir_all;
///
/// # {
@ -90,8 +92,12 @@ impl SledStore {
&'a self,
query: &str,
options: QueryOptions<'_>,
) -> Result<impl PreparedQuery + 'a> {
SimplePreparedQuery::new((*self).clone(), query, options)
) -> Result<SledPreparedQuery> {
Ok(SledPreparedQuery(SimplePreparedQuery::new(
(*self).clone(),
query,
options,
)?))
}
/// This is similar to `prepare_query`, but useful if a SPARQL query has already been parsed, which is the case when building `ServiceHandler`s for federated queries with `SERVICE` clauses. For examples, look in the tests.
@ -99,8 +105,12 @@ impl SledStore {
&'a self,
graph_pattern: &GraphPattern,
options: QueryOptions<'_>,
) -> Result<impl PreparedQuery + 'a> {
SimplePreparedQuery::new_from_pattern((*self).clone(), graph_pattern, options)
) -> Result<SledPreparedQuery> {
Ok(SledPreparedQuery(SimplePreparedQuery::new_from_pattern(
(*self).clone(),
graph_pattern,
options,
)?))
}
/// Retrieves quads with a filter on each quad component
@ -478,6 +488,16 @@ impl<'a> WritableEncodedStore for &'a SledStore {
}
}
/// A prepared [SPARQL query](https://www.w3.org/TR/sparql11-query/) for the `SledStore`.
pub struct SledPreparedQuery(SimplePreparedQuery<SledStore>);
impl SledPreparedQuery {
/// Evaluates the query and returns its results
pub fn exec(&self) -> Result<QueryResult<'_>> {
self.0.exec()
}
}
fn encode_term(t: EncodedTerm) -> Vec<u8> {
let mut vec = Vec::with_capacity(WRITTEN_TERM_MAX_SIZE);
write_term(&mut vec, t);

@ -1,7 +1,7 @@
#[cfg(target_arch = "wasm32")]
mod test {
use oxigraph::model::*;
use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult};
use oxigraph::sparql::{QueryOptions, QueryResult};
use oxigraph::{MemoryStore, Result};
use std::str::FromStr;
use wasm_bindgen_test::*;

@ -16,7 +16,7 @@ use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task::{block_on, spawn, spawn_blocking};
use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode};
use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::sparql::{QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, RocksDbStore};
use std::str::FromStr;
use url::form_urlencoded;

@ -16,7 +16,7 @@ use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task::{spawn, spawn_blocking};
use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode};
use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::sparql::{QueryOptions, QueryResult, QueryResultSyntax};
use oxigraph::{FileSyntax, GraphSyntax, RocksDbStore};
use std::str::FromStr;
use std::time::Duration;

Loading…
Cancel
Save