From 974e5d1e1a361b785998f3cdc388bf096b9758d3 Mon Sep 17 00:00:00 2001 From: Tpt Date: Sun, 12 Jul 2020 17:11:03 +0200 Subject: [PATCH] Breaking: Adds a new enumeration for graph names --- js/src/model.rs | 68 ++++++++++------ js/src/store.rs | 92 +++++++++------------- lib/src/model/mod.rs | 8 +- lib/src/model/triple.rs | 125 +++++++++++++++++++++++++----- lib/src/store/memory.rs | 13 ++-- lib/src/store/mod.rs | 12 +-- lib/src/store/numeric_encoder.rs | 28 +++++-- lib/src/store/rocksdb.rs | 41 +++++++--- lib/src/store/sled.rs | 39 +++++++--- lib/tests/service_test_cases.rs | 7 +- server/src/main.rs | 8 +- testsuite/src/files.rs | 10 +-- testsuite/src/manifest.rs | 4 +- testsuite/src/sparql_evaluator.rs | 10 +-- wikibase/src/loader.rs | 4 +- 15 files changed, 304 insertions(+), 165 deletions(-) diff --git a/js/src/model.rs b/js/src/model.rs index a4c7b228..668ae963 100644 --- a/js/src/model.rs +++ b/js/src/model.rs @@ -68,7 +68,7 @@ impl JsDataFactory { subject: self.from_js.to_term(subject)?, predicate: self.from_js.to_term(predicate)?, object: self.from_js.to_term(object)?, - graph: JsTerm::DefaultGraph(JsDefaultGraph {}), + graph_name: JsTerm::DefaultGraph(JsDefaultGraph {}), }) } @@ -84,7 +84,7 @@ impl JsDataFactory { subject: self.from_js.to_term(subject)?, predicate: self.from_js.to_term(predicate)?, object: self.from_js.to_term(object)?, - graph: if graph.is_undefined() || graph.is_null() { + graph_name: if graph.is_undefined() || graph.is_null() { JsTerm::DefaultGraph(JsDefaultGraph {}) } else { self.from_js.to_term(&graph)? @@ -156,6 +156,12 @@ impl From for Term { } } +impl From for GraphName { + fn from(node: JsNamedNode) -> Self { + node.inner.into() + } +} + #[wasm_bindgen(js_name = BlankNode)] #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct JsBlankNode { @@ -209,6 +215,12 @@ impl From for Term { } } +impl From for GraphName { + fn from(node: JsBlankNode) -> Self { + node.inner.into() + } +} + #[wasm_bindgen(js_name = Literal)] #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct JsLiteral { @@ -349,6 +361,16 @@ impl From for JsTerm { } } +impl From for JsTerm { + fn from(name: GraphName) -> Self { + match name { + GraphName::NamedNode(node) => node.into(), + GraphName::BlankNode(node) => node.into(), + GraphName::DefaultGraph => JsTerm::DefaultGraph(JsDefaultGraph {}), + } + } +} + impl TryFrom for NamedNode { type Error = JsValue; @@ -376,7 +398,7 @@ impl TryFrom for NamedOrBlankNode { JsTerm::NamedNode(node) => Ok(node.into()), JsTerm::BlankNode(node) => Ok(node.into()), JsTerm::Literal(literal) => Err(format_err!( - "The variable {} is not a possible named or blank node term", + "The literal {} is not a possible named or blank node term", literal.inner )), JsTerm::DefaultGraph(_) => { @@ -401,13 +423,29 @@ impl TryFrom for Term { } } +impl TryFrom for GraphName { + type Error = JsValue; + + fn try_from(value: JsTerm) -> Result { + match value { + JsTerm::NamedNode(node) => Ok(node.into()), + JsTerm::BlankNode(node) => Ok(node.into()), + JsTerm::Literal(literal) => Err(format_err!( + "The literal {} is not a possible graph name", + literal.inner + )), + JsTerm::DefaultGraph(_) => Ok(GraphName::DefaultGraph), + } + } +} + #[wasm_bindgen(js_name = Quad)] #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct JsQuad { subject: JsTerm, predicate: JsTerm, object: JsTerm, - graph: JsTerm, + graph_name: JsTerm, } #[wasm_bindgen(js_class = Quad)] @@ -429,7 +467,7 @@ impl JsQuad { #[wasm_bindgen(getter = graph)] pub fn graph(&self) -> JsValue { - self.graph.clone().into() + self.graph_name.clone().into() } pub fn equals(&self, other: &JsValue) -> bool { @@ -445,11 +483,7 @@ impl From for JsQuad { subject: quad.subject.into(), predicate: quad.predicate.into(), object: quad.object.into(), - graph: if let Some(g) = quad.graph_name { - g.into() - } else { - JsTerm::DefaultGraph(JsDefaultGraph {}) - }, + graph_name: quad.graph_name.into(), } } } @@ -462,17 +496,7 @@ impl TryFrom for Quad { subject: NamedOrBlankNode::try_from(quad.subject)?, predicate: NamedNode::try_from(quad.predicate)?, object: Term::try_from(quad.object)?, - graph_name: match quad.graph { - JsTerm::NamedNode(node) => Some(NamedOrBlankNode::from(NamedNode::from(node))), - JsTerm::BlankNode(node) => Some(NamedOrBlankNode::from(BlankNode::from(node))), - JsTerm::Literal(literal) => { - return Err(format_err!( - "The variable ?{} is not a valid graph name", - literal.inner - )) - } - JsTerm::DefaultGraph(_) => None, - }, + graph_name: GraphName::try_from(quad.graph_name)?, }) } } @@ -567,7 +591,7 @@ impl FromJsConverter { subject: self.to_term(&Reflect::get(&value, &self.subject)?)?, predicate: self.to_term(&Reflect::get(&value, &self.predicate)?)?, object: self.to_term(&Reflect::get(&value, &self.object)?)?, - graph: self.to_term(&Reflect::get(&value, &self.graph)?)?, + graph_name: self.to_term(&Reflect::get(&value, &self.graph)?)?, }) } } diff --git a/js/src/store.rs b/js/src/store.rs index f2b39919..7dc651b4 100644 --- a/js/src/store.rs +++ b/js/src/store.rs @@ -2,7 +2,7 @@ use crate::format_err; use crate::model::*; use crate::utils::to_err; use js_sys::{Array, Map}; -use oxigraph::model::NamedOrBlankNode; +use oxigraph::model::GraphName; use oxigraph::sparql::{QueryOptions, QueryResult}; use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, MemoryStore}; use std::convert::TryInto; @@ -63,53 +63,39 @@ impl JsMemoryStore { subject: &JsValue, predicate: &JsValue, object: &JsValue, - graph: &JsValue, + graph_name: &JsValue, ) -> Result, JsValue> { Ok(self .store .quads_for_pattern( - match self.from_js.to_optional_term(subject)? { - Some(JsTerm::NamedNode(node)) => Some(node.into()), - Some(JsTerm::BlankNode(node)) => Some(node.into()), - Some(_) => { - return Err(format_err!( - "The match subject parameter should be a named or a blank node", - )) - } - None => None, - }.as_ref(), - match self.from_js.to_optional_term(predicate)? { - Some(JsTerm::NamedNode(node)) => Some(node.into()), - Some(_) => { - return Err(format_err!( - "The match predicate parameter should be a named node", - )) - } - None => None, - }.as_ref(), - match self.from_js.to_optional_term(object)? { - Some(JsTerm::NamedNode(node)) => Some(node.into()), - Some(JsTerm::BlankNode(node)) => Some(node.into()), - Some(JsTerm::Literal(literal)) => Some(literal.into()), - Some(_) => { - return Err(format_err!( - "The match object parameter should be a named or a blank node or a literal", - )) - } - None => None, - }.as_ref(), - match self.from_js.to_optional_term(graph)? { - Some(JsTerm::NamedNode(node)) => Some(Some(node.into())), - Some(JsTerm::BlankNode(node)) => Some(Some(node.into())), - Some(JsTerm::DefaultGraph(_)) => Some(None), - Some(_) => { - return Err(format_err!( - "The match subject parameter should be a named or a blank node or the default graph", - )) - } - None => None, - }.as_ref().map(|v| v.as_ref()), - ).map(|v| JsQuad::from(v).into()).collect::>().into_boxed_slice()) + if let Some(subject) = self.from_js.to_optional_term(subject)? { + Some(subject.try_into()?) + } else { + None + } + .as_ref(), + if let Some(predicate) = self.from_js.to_optional_term(predicate)? { + Some(predicate.try_into()?) + } else { + None + } + .as_ref(), + if let Some(object) = self.from_js.to_optional_term(object)? { + Some(object.try_into()?) + } else { + None + } + .as_ref(), + if let Some(graph_name) = self.from_js.to_optional_term(graph_name)? { + Some(graph_name.try_into()?) + } else { + None + } + .as_ref(), + ) + .map(|v| JsQuad::from(v).into()) + .collect::>() + .into_boxed_slice()) } pub fn query(&self, query: &str) -> Result { @@ -165,17 +151,11 @@ impl JsMemoryStore { )); }; - let to_graph_name: Option = - match self.from_js.to_optional_term(to_graph_name)? { - Some(JsTerm::NamedNode(node)) => Some(node.into()), - Some(JsTerm::BlankNode(node)) => Some(node.into()), - Some(JsTerm::DefaultGraph(_)) => None, - Some(_) => { - return Err(format_err!( - "If provided, the target graph name should be a NamedNode or a BlankNode" - )) - } - None => None, + let to_graph_name = + if let Some(graph_name) = self.from_js.to_optional_term(to_graph_name)? { + Some(graph_name.try_into()?) + } else { + None }; if let Some(graph_syntax) = GraphSyntax::from_mime_type(mime_type) { @@ -183,7 +163,7 @@ impl JsMemoryStore { .load_graph( Cursor::new(data), graph_syntax, - to_graph_name.as_ref(), + &to_graph_name.unwrap_or(GraphName::DefaultGraph), base_iri.as_deref(), ) .map_err(to_err) diff --git a/lib/src/model/mod.rs b/lib/src/model/mod.rs index d6e2d569..307c26d4 100644 --- a/lib/src/model/mod.rs +++ b/lib/src/model/mod.rs @@ -9,13 +9,9 @@ mod triple; pub mod vocab; pub(crate) mod xsd; -pub use crate::model::blank_node::BlankNode; -pub use crate::model::blank_node::BlankNodeIdParseError; +pub use crate::model::blank_node::{BlankNode, BlankNodeIdParseError}; pub use crate::model::literal::Literal; pub use crate::model::named_node::NamedNode; -pub use crate::model::triple::NamedOrBlankNode; -pub use crate::model::triple::Quad; -pub use crate::model::triple::Term; -pub use crate::model::triple::Triple; +pub use crate::model::triple::{GraphName, NamedOrBlankNode, Quad, Term, Triple}; pub use oxilangtag::LanguageTagParseError; pub use oxiri::IriParseError; diff --git a/lib/src/model/triple.rs b/lib/src/model/triple.rs index 0963f91f..dba52bcd 100644 --- a/lib/src/model/triple.rs +++ b/lib/src/model/triple.rs @@ -70,24 +70,21 @@ impl Term { pub fn is_named_node(&self) -> bool { match self { Term::NamedNode(_) => true, - Term::BlankNode(_) => false, - Term::Literal(_) => false, + _ => false, } } pub fn is_blank_node(&self) -> bool { match self { - Term::NamedNode(_) => false, Term::BlankNode(_) => true, - Term::Literal(_) => false, + _ => false, } } pub fn is_literal(&self) -> bool { match self { - Term::NamedNode(_) => false, - Term::BlankNode(_) => false, Term::Literal(_) => true, + _ => false, } } } @@ -123,8 +120,8 @@ impl From for Term { impl From for Term { fn from(resource: NamedOrBlankNode) -> Self { match resource { - NamedOrBlankNode::NamedNode(node) => Term::NamedNode(node), - NamedOrBlankNode::BlankNode(node) => Term::BlankNode(node), + NamedOrBlankNode::NamedNode(node) => node.into(), + NamedOrBlankNode::BlankNode(node) => node.into(), } } } @@ -197,12 +194,12 @@ impl Triple { } /// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) - pub fn in_graph(self, graph_name: Option) -> Quad { + pub fn in_graph(self, graph_name: impl Into) -> Quad { Quad { subject: self.subject, predicate: self.predicate, object: self.object, - graph_name, + graph_name: graph_name.into(), } } } @@ -223,6 +220,99 @@ impl<'a> From<&'a Triple> for rio::Triple<'a> { } } +/// A possible graph name. +/// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) and the [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph). +#[derive(Eq, PartialEq, Debug, Clone, Hash)] +pub enum GraphName { + NamedNode(NamedNode), + BlankNode(BlankNode), + DefaultGraph, +} + +impl GraphName { + pub fn is_named_node(&self) -> bool { + match self { + GraphName::NamedNode(_) => true, + _ => false, + } + } + + pub fn is_blank_node(&self) -> bool { + match self { + GraphName::BlankNode(_) => true, + _ => false, + } + } + + pub fn is_default_graph(&self) -> bool { + match self { + GraphName::DefaultGraph => true, + _ => false, + } + } +} + +impl fmt::Display for GraphName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + GraphName::NamedNode(node) => node.fmt(f), + GraphName::BlankNode(node) => node.fmt(f), + GraphName::DefaultGraph => write!(f, "DEFAULT"), + } + } +} + +impl From for GraphName { + fn from(node: NamedNode) -> Self { + GraphName::NamedNode(node) + } +} + +impl From for GraphName { + fn from(node: BlankNode) -> Self { + GraphName::BlankNode(node) + } +} + +impl From for GraphName { + fn from(node: NamedOrBlankNode) -> Self { + match node { + NamedOrBlankNode::NamedNode(node) => node.into(), + NamedOrBlankNode::BlankNode(node) => node.into(), + } + } +} + +impl From> for GraphName { + fn from(name: Option) -> Self { + if let Some(node) = name { + node.into() + } else { + GraphName::DefaultGraph + } + } +} + +impl From for Option { + fn from(name: GraphName) -> Self { + match name { + GraphName::NamedNode(node) => Some(node.into()), + GraphName::BlankNode(node) => Some(node.into()), + GraphName::DefaultGraph => None, + } + } +} + +impl<'a> From<&'a GraphName> for Option> { + fn from(name: &'a GraphName) -> Self { + match name { + GraphName::NamedNode(node) => Some(rio::NamedNode::from(node).into()), + GraphName::BlankNode(node) => Some(rio::BlankNode::from(node).into()), + GraphName::DefaultGraph => None, + } + } +} + /// A [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct Quad { @@ -235,9 +325,8 @@ pub struct Quad { /// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple pub object: Term, - /// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is - /// or None if it is in the [default graph](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph) - pub graph_name: Option, + /// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is. + pub graph_name: GraphName, } impl Quad { @@ -246,7 +335,7 @@ impl Quad { subject: impl Into, predicate: impl Into, object: impl Into, - graph_name: impl Into>, + graph_name: impl Into, ) -> Self { Self { subject: subject.into(), @@ -287,12 +376,12 @@ impl Quad { } #[deprecated(note = "Use directly the `graph_name` field")] - pub const fn graph_name(&self) -> &Option { + pub const fn graph_name(&self) -> &GraphName { &self.graph_name } #[deprecated(note = "Use directly the `graph_name` field")] - pub fn graph_name_owned(self) -> Option { + pub fn graph_name_owned(self) -> GraphName { self.graph_name } @@ -302,7 +391,7 @@ impl Quad { } #[deprecated(note = "Use directly the struct fields")] - pub fn destruct(self) -> (NamedOrBlankNode, NamedNode, Term, Option) { + pub fn destruct(self) -> (NamedOrBlankNode, NamedNode, Term, GraphName) { (self.subject, self.predicate, self.object, self.graph_name) } } @@ -319,7 +408,7 @@ impl<'a> From<&'a Quad> for rio::Quad<'a> { subject: (&node.subject).into(), predicate: (&node.predicate).into(), object: (&node.object).into(), - graph_name: node.graph_name.as_ref().map(|g| g.into()), + graph_name: (&node.graph_name).into(), } } } diff --git a/lib/src/store/memory.rs b/lib/src/store/memory.rs index fa713447..cd26f8ab 100644 --- a/lib/src/store/memory.rs +++ b/lib/src/store/memory.rs @@ -144,18 +144,17 @@ impl MemoryStore { /// assert_eq!(vec![quad], results); /// # Result::Ok(()) /// ``` - #[allow(clippy::option_option)] pub fn quads_for_pattern( &self, subject: Option<&NamedOrBlankNode>, predicate: Option<&NamedNode>, object: Option<&Term>, - graph_name: Option>, + graph_name: Option<&GraphName>, ) -> impl Iterator { let subject = subject.map(|s| s.into()); let predicate = predicate.map(|p| p.into()); let object = object.map(|o| o.into()); - let graph_name = graph_name.map(|g| g.map_or(ENCODED_DEFAULT_GRAPH, |g| g.into())); + let graph_name = graph_name.map(|g| g.into()); let this = self.clone(); self.encoded_quads_for_pattern_inner(subject, predicate, object, graph_name) .into_iter() @@ -237,7 +236,7 @@ impl MemoryStore { /// /// // insertion /// let file = b" ."; - /// store.load_graph(file.as_ref(), GraphSyntax::NTriples, None, None); + /// store.load_graph(file.as_ref(), GraphSyntax::NTriples, &GraphName::DefaultGraph, None); /// /// // quad filter /// let results: Vec = store.quads_for_pattern(None, None, None, None).collect(); @@ -249,7 +248,7 @@ impl MemoryStore { &self, reader: impl BufRead, syntax: GraphSyntax, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, base_iri: Option<&str>, ) -> Result<()> { let mut store = self; @@ -870,7 +869,7 @@ impl<'a> MemoryTransaction<'a> { /// // insertion /// let file = b" ."; /// store.transaction(|transaction| { - /// store.load_graph(file.as_ref(), GraphSyntax::NTriples, None, None) + /// store.load_graph(file.as_ref(), GraphSyntax::NTriples, &GraphName::DefaultGraph, None) /// })?; /// /// // quad filter @@ -883,7 +882,7 @@ impl<'a> MemoryTransaction<'a> { &mut self, reader: impl BufRead, syntax: GraphSyntax, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, base_iri: Option<&str>, ) -> Result<()> { load_graph(self, reader, syntax, to_graph_name, base_iri) diff --git a/lib/src/store/mod.rs b/lib/src/store/mod.rs index 108772af..1eada5ed 100644 --- a/lib/src/store/mod.rs +++ b/lib/src/store/mod.rs @@ -47,7 +47,7 @@ fn load_graph( store: &mut S, reader: impl BufRead, syntax: GraphSyntax, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, base_iri: Option<&str>, ) -> Result<()> { let base_iri = base_iri.unwrap_or(""); @@ -67,19 +67,15 @@ fn load_graph( fn load_from_triple_parser( store: &mut S, mut parser: P, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, ) -> Result<()> where Error: From, { let mut bnode_map = HashMap::default(); - let graph_name = if let Some(graph_name) = to_graph_name { - store.encode_named_or_blank_node(graph_name)? - } else { - EncodedTerm::DefaultGraph - }; + let to_graph_name = store.encode_graph_name(to_graph_name)?; parser.parse_all(&mut move |t| { - let quad = store.encode_rio_triple_in_graph(t, graph_name, &mut bnode_map)?; + let quad = store.encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map)?; store.insert_encoded(&quad) }) } diff --git a/lib/src/store/numeric_encoder.rs b/lib/src/store/numeric_encoder.rs index a72273f6..fed6e981 100644 --- a/lib/src/store/numeric_encoder.rs +++ b/lib/src/store/numeric_encoder.rs @@ -561,6 +561,16 @@ impl From<&Term> for EncodedTerm { } } +impl From<&GraphName> for EncodedTerm { + fn from(node: &GraphName) -> Self { + match node { + GraphName::NamedNode(node) => node.into(), + GraphName::BlankNode(node) => node.into(), + GraphName::DefaultGraph => ENCODED_DEFAULT_GRAPH, + } + } +} + #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] pub struct EncodedQuad { pub subject: EncodedTerm, @@ -591,10 +601,7 @@ impl From<&Quad> for EncodedQuad { subject: (&quad.subject).into(), predicate: (&quad.predicate).into(), object: (&quad.object).into(), - graph_name: quad - .graph_name - .as_ref() - .map_or(ENCODED_DEFAULT_GRAPH, |g| g.into()), + graph_name: (&quad.graph_name).into(), } } } @@ -996,15 +1003,20 @@ pub trait Encoder { } } + fn encode_graph_name(&mut self, name: &GraphName) -> Result { + match name { + GraphName::NamedNode(named_node) => self.encode_named_node(named_node), + GraphName::BlankNode(blank_node) => self.encode_blank_node(blank_node), + GraphName::DefaultGraph => Ok(ENCODED_DEFAULT_GRAPH), + } + } + fn encode_quad(&mut self, quad: &Quad) -> Result { Ok(EncodedQuad { subject: self.encode_named_or_blank_node(&quad.subject)?, predicate: self.encode_named_node(&quad.predicate)?, object: self.encode_term(&quad.object)?, - graph_name: match &quad.graph_name { - Some(graph_name) => self.encode_named_or_blank_node(graph_name)?, - None => ENCODED_DEFAULT_GRAPH, - }, + graph_name: self.encode_graph_name(&quad.graph_name)?, }) } diff --git a/lib/src/store/rocksdb.rs b/lib/src/store/rocksdb.rs index 480cafdd..66efe564 100644 --- a/lib/src/store/rocksdb.rs +++ b/lib/src/store/rocksdb.rs @@ -130,13 +130,12 @@ impl RocksDbStore { /// Retrieves quads with a filter on each quad component /// /// See `MemoryStore` for a usage example. - #[allow(clippy::option_option)] pub fn quads_for_pattern<'a>( &'a self, subject: Option<&NamedOrBlankNode>, predicate: Option<&NamedNode>, object: Option<&Term>, - graph_name: Option>, + graph_name: Option<&GraphName>, ) -> impl Iterator> + 'a where Self: 'a, @@ -144,7 +143,7 @@ impl RocksDbStore { let subject = subject.map(|s| s.into()); let predicate = predicate.map(|p| p.into()); let object = object.map(|o| o.into()); - let graph_name = graph_name.map(|g| g.map_or(ENCODED_DEFAULT_GRAPH, |g| g.into())); + let graph_name = graph_name.map(|g| g.into()); self.handle() .encoded_quads_for_pattern(subject, predicate, object, graph_name) .map(move |quad| self.decode_quad(&quad?)) @@ -181,7 +180,7 @@ impl RocksDbStore { &self, reader: impl BufRead, syntax: GraphSyntax, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, base_iri: Option<&str>, ) -> Result<()> { let mut transaction = self.handle().auto_transaction(); @@ -539,7 +538,7 @@ impl RocksDbTransaction<'_> { &mut self, reader: impl BufRead, syntax: GraphSyntax, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, base_iri: Option<&str>, ) -> Result<()> { load_graph(self, reader, syntax, to_graph_name, base_iri) @@ -804,13 +803,23 @@ fn store() -> Result<()> { ); assert_eq!( store - .quads_for_pattern(Some(&main_s), Some(&main_p), Some(&main_o), Some(None)) + .quads_for_pattern( + Some(&main_s), + Some(&main_p), + Some(&main_o), + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, target ); assert_eq!( store - .quads_for_pattern(Some(&main_s), Some(&main_p), None, Some(None)) + .quads_for_pattern( + Some(&main_s), + Some(&main_p), + None, + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, all_o ); @@ -822,13 +831,18 @@ fn store() -> Result<()> { ); assert_eq!( store - .quads_for_pattern(Some(&main_s), None, Some(&main_o), Some(None)) + .quads_for_pattern( + Some(&main_s), + None, + Some(&main_o), + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, target ); assert_eq!( store - .quads_for_pattern(Some(&main_s), None, None, Some(None)) + .quads_for_pattern(Some(&main_s), None, None, Some(&GraphName::DefaultGraph)) .collect::>>()?, all_o ); @@ -852,13 +866,18 @@ fn store() -> Result<()> { ); assert_eq!( store - .quads_for_pattern(None, None, None, Some(None)) + .quads_for_pattern(None, None, None, Some(&GraphName::DefaultGraph)) .collect::>>()?, all_o ); assert_eq!( store - .quads_for_pattern(None, Some(&main_p), Some(&main_o), Some(None)) + .quads_for_pattern( + None, + Some(&main_p), + Some(&main_o), + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, target ); diff --git a/lib/src/store/sled.rs b/lib/src/store/sled.rs index 1dcea666..6c6a493f 100644 --- a/lib/src/store/sled.rs +++ b/lib/src/store/sled.rs @@ -116,18 +116,17 @@ impl SledStore { /// Retrieves quads with a filter on each quad component /// /// See `MemoryStore` for a usage example. - #[allow(clippy::option_option)] pub fn quads_for_pattern( &self, subject: Option<&NamedOrBlankNode>, predicate: Option<&NamedNode>, object: Option<&Term>, - graph_name: Option>, + graph_name: Option<&GraphName>, ) -> impl Iterator> { let subject = subject.map(|s| s.into()); let predicate = predicate.map(|p| p.into()); let object = object.map(|o| o.into()); - let graph_name = graph_name.map(|g| g.map_or(ENCODED_DEFAULT_GRAPH, |g| g.into())); + let graph_name = graph_name.map(|g| g.into()); let this = self.clone(); self.encoded_quads_for_pattern_inner(subject, predicate, object, graph_name) .map(move |quad| this.decode_quad(&quad?)) @@ -149,7 +148,7 @@ impl SledStore { &self, reader: impl BufRead, syntax: GraphSyntax, - to_graph_name: Option<&NamedOrBlankNode>, + to_graph_name: &GraphName, base_iri: Option<&str>, ) -> Result<()> { let mut store = self; @@ -593,13 +592,23 @@ fn store() -> Result<()> { ); assert_eq!( store - .quads_for_pattern(Some(&main_s), Some(&main_p), Some(&main_o), Some(None)) + .quads_for_pattern( + Some(&main_s), + Some(&main_p), + Some(&main_o), + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, target ); assert_eq!( store - .quads_for_pattern(Some(&main_s), Some(&main_p), None, Some(None)) + .quads_for_pattern( + Some(&main_s), + Some(&main_p), + None, + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, all_o ); @@ -611,13 +620,18 @@ fn store() -> Result<()> { ); assert_eq!( store - .quads_for_pattern(Some(&main_s), None, Some(&main_o), Some(None)) + .quads_for_pattern( + Some(&main_s), + None, + Some(&main_o), + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, target ); assert_eq!( store - .quads_for_pattern(Some(&main_s), None, None, Some(None)) + .quads_for_pattern(Some(&main_s), None, None, Some(&GraphName::DefaultGraph)) .collect::>>()?, all_o ); @@ -641,13 +655,18 @@ fn store() -> Result<()> { ); assert_eq!( store - .quads_for_pattern(None, None, None, Some(None)) + .quads_for_pattern(None, None, None, Some(&GraphName::DefaultGraph)) .collect::>>()?, all_o ); assert_eq!( store - .quads_for_pattern(None, Some(&main_p), Some(&main_o), Some(None)) + .quads_for_pattern( + None, + Some(&main_p), + Some(&main_o), + Some(&GraphName::DefaultGraph) + ) .collect::>>()?, target ); diff --git a/lib/tests/service_test_cases.rs b/lib/tests/service_test_cases.rs index be5e1f2c..2f4542dd 100644 --- a/lib/tests/service_test_cases.rs +++ b/lib/tests/service_test_cases.rs @@ -194,7 +194,12 @@ fn literal(str: &str) -> Term { fn make_store(reader: impl BufRead) -> Result { let store = MemoryStore::new(); store - .load_graph(reader, GraphSyntax::NTriples, None, None) + .load_graph( + reader, + GraphSyntax::NTriples, + &GraphName::DefaultGraph, + None, + ) .unwrap(); Ok(store) } diff --git a/server/src/main.rs b/server/src/main.rs index 76b60485..b45dac77 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -16,6 +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::model::GraphName; use oxigraph::sparql::{QueryOptions, QueryResult, QueryResultSyntax}; use oxigraph::{DatasetSyntax, FileSyntax, GraphSyntax, RocksDbStore}; use std::str::FromStr; @@ -61,7 +62,12 @@ async fn handle_request(request: Request, store: RocksDbStore) -> Result Result { Ok(buf) } -pub fn load_to_store( - url: &str, - store: &MemoryStore, - to_graph_name: Option<&NamedOrBlankNode>, -) -> Result<()> { +pub fn load_to_store(url: &str, store: &MemoryStore, to_graph_name: &GraphName) -> Result<()> { if url.ends_with(".nt") { store.load_graph( read_file(url)?, @@ -77,6 +73,6 @@ pub fn load_to_store( pub fn load_store(url: &str) -> Result { let store = MemoryStore::new(); - load_to_store(url, &store, None)?; + load_to_store(url, &store, &GraphName::DefaultGraph)?; Ok(store) } diff --git a/testsuite/src/manifest.rs b/testsuite/src/manifest.rs index 6e3a251d..046dfea2 100644 --- a/testsuite/src/manifest.rs +++ b/testsuite/src/manifest.rs @@ -177,7 +177,9 @@ impl Iterator for TestManifest { match self.manifests_to_do.pop() { Some(url) => { let manifest = NamedOrBlankNode::from(NamedNode::new(url.clone()).unwrap()); - if let Err(error) = load_to_store(&url, &self.graph, None) { + if let Err(error) = + load_to_store(&url, &self.graph, &&GraphName::DefaultGraph) + { return Some(Err(error)); } diff --git a/testsuite/src/sparql_evaluator.rs b/testsuite/src/sparql_evaluator.rs index 3e1cf5f8..0d05dee9 100644 --- a/testsuite/src/sparql_evaluator.rs +++ b/testsuite/src/sparql_evaluator.rs @@ -73,14 +73,10 @@ fn evaluate_sparql_test(test: &Test) -> Result<()> { { let store = MemoryStore::new(); if let Some(data) = &test.data { - load_to_store(data, &store, None)?; + load_to_store(data, &store, &GraphName::DefaultGraph)?; } for graph_data in &test.graph_data { - load_to_store( - &graph_data, - &store, - Some(&NamedNode::new(graph_data)?.into()), - )?; + load_to_store(&graph_data, &store, &NamedNode::new(graph_data)?.into())?; } let query_file = test .query @@ -165,7 +161,7 @@ impl StaticServiceHandler { .map(|(name, data)| { let name = NamedNode::new(name)?; let store = MemoryStore::new(); - load_to_store(&data, &store, None)?; + load_to_store(&data, &store, &GraphName::DefaultGraph)?; Ok((name, store)) }) .collect::>()?, diff --git a/wikibase/src/loader.rs b/wikibase/src/loader.rs index 386ad58c..20e56def 100644 --- a/wikibase/src/loader.rs +++ b/wikibase/src/loader.rs @@ -263,7 +263,7 @@ impl WikibaseLoader { self.store.transaction(|transaction| { let to_remove = self .store - .quads_for_pattern(None, None, None, Some(Some(&graph_name))) + .quads_for_pattern(None, None, None, Some(&graph_name)) .collect::>>()?; for q in to_remove { transaction.remove(&q)?; @@ -272,7 +272,7 @@ impl WikibaseLoader { transaction.load_graph( BufReader::new(data), GraphSyntax::NTriples, - Some(&NamedNode::new(uri)?.into()), + &NamedNode::new(uri)?.into(), None, ) })?;