From 4302316a413541787442de99ee0909e76d6fab77 Mon Sep 17 00:00:00 2001 From: Tpt Date: Sun, 2 May 2021 12:35:00 +0200 Subject: [PATCH] Fixes the input type of graph manipulation methods Nested triples are not allowed there --- lib/src/model/mod.rs | 3 +- lib/src/model/triple.rs | 225 +++++++++++++++++++++++++++++ lib/src/sparql/algebra.rs | 6 +- lib/src/storage/numeric_encoder.rs | 37 ++++- lib/src/store.rs | 24 +-- lib/tests/store.rs | 2 +- python/src/model.rs | 124 +++++++++++++--- python/src/sparql.rs | 2 +- python/src/store.rs | 10 +- server/src/main.rs | 6 +- testsuite/src/sparql_evaluator.rs | 2 +- wikibase/src/main.rs | 4 +- 12 files changed, 394 insertions(+), 51 deletions(-) diff --git a/lib/src/model/mod.rs b/lib/src/model/mod.rs index 044c7ec1..940ab2d3 100644 --- a/lib/src/model/mod.rs +++ b/lib/src/model/mod.rs @@ -22,7 +22,8 @@ pub use self::literal::{Literal, LiteralRef}; pub use self::named_node::{NamedNode, NamedNodeRef}; pub use self::parser::TermParseError; pub use self::triple::{ - GraphName, GraphNameRef, Quad, QuadRef, Subject, SubjectRef, Term, TermRef, Triple, TripleRef, + GraphName, GraphNameRef, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, QuadRef, Subject, + SubjectRef, Term, TermRef, Triple, TripleRef, }; pub use oxilangtag::LanguageTagParseError; pub use oxiri::IriParseError; diff --git a/lib/src/model/triple.rs b/lib/src/model/triple.rs index 786c436c..31cb8bc7 100644 --- a/lib/src/model/triple.rs +++ b/lib/src/model/triple.rs @@ -6,6 +6,163 @@ use rio_api::model as rio; use std::fmt; use std::sync::Arc; +/// The owned union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node). +#[derive(Eq, PartialEq, Debug, Clone, Hash)] +pub enum NamedOrBlankNode { + NamedNode(NamedNode), + BlankNode(BlankNode), +} + +impl NamedOrBlankNode { + #[inline] + pub fn is_named_node(&self) -> bool { + self.as_ref().is_named_node() + } + + #[inline] + pub fn is_blank_node(&self) -> bool { + self.as_ref().is_blank_node() + } + + #[inline] + pub fn as_ref(&self) -> NamedOrBlankNodeRef<'_> { + match self { + Self::NamedNode(node) => NamedOrBlankNodeRef::NamedNode(node.as_ref()), + Self::BlankNode(node) => NamedOrBlankNodeRef::BlankNode(node.as_ref()), + } + } +} + +impl fmt::Display for NamedOrBlankNode { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_ref().fmt(f) + } +} + +impl From for NamedOrBlankNode { + #[inline] + fn from(node: NamedNode) -> Self { + Self::NamedNode(node) + } +} + +impl From> for NamedOrBlankNode { + #[inline] + fn from(node: NamedNodeRef<'_>) -> Self { + node.into_owned().into() + } +} + +impl From for NamedOrBlankNode { + #[inline] + fn from(node: BlankNode) -> Self { + Self::BlankNode(node) + } +} + +impl From> for NamedOrBlankNode { + #[inline] + fn from(node: BlankNodeRef<'_>) -> Self { + node.into_owned().into() + } +} + +/// The borrowed union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node). +#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] +pub enum NamedOrBlankNodeRef<'a> { + NamedNode(NamedNodeRef<'a>), + BlankNode(BlankNodeRef<'a>), +} + +impl<'a> NamedOrBlankNodeRef<'a> { + #[inline] + pub fn is_named_node(&self) -> bool { + match self { + Self::NamedNode(_) => true, + Self::BlankNode(_) => false, + } + } + + #[inline] + pub fn is_blank_node(&self) -> bool { + match self { + Self::NamedNode(_) => false, + Self::BlankNode(_) => true, + } + } + + #[inline] + pub fn into_owned(self) -> NamedOrBlankNode { + match self { + Self::NamedNode(node) => NamedOrBlankNode::NamedNode(node.into_owned()), + Self::BlankNode(node) => NamedOrBlankNode::BlankNode(node.into_owned()), + } + } +} + +impl fmt::Display for NamedOrBlankNodeRef<'_> { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::NamedNode(node) => node.fmt(f), + Self::BlankNode(node) => node.fmt(f), + } + } +} + +impl<'a> From> for NamedOrBlankNodeRef<'a> { + #[inline] + fn from(node: NamedNodeRef<'a>) -> Self { + Self::NamedNode(node) + } +} + +impl<'a> From<&'a NamedNode> for NamedOrBlankNodeRef<'a> { + #[inline] + fn from(node: &'a NamedNode) -> Self { + node.as_ref().into() + } +} + +impl<'a> From> for NamedOrBlankNodeRef<'a> { + #[inline] + fn from(node: BlankNodeRef<'a>) -> Self { + Self::BlankNode(node) + } +} + +impl<'a> From<&'a BlankNode> for NamedOrBlankNodeRef<'a> { + #[inline] + fn from(node: &'a BlankNode) -> Self { + node.as_ref().into() + } +} + +impl<'a> From<&'a NamedOrBlankNode> for NamedOrBlankNodeRef<'a> { + #[inline] + fn from(node: &'a NamedOrBlankNode) -> Self { + node.as_ref() + } +} + +impl<'a> From> for NamedOrBlankNode { + #[inline] + fn from(node: NamedOrBlankNodeRef<'a>) -> Self { + node.into_owned() + } +} + +impl<'a> From> for rio::NamedOrBlankNode<'a> { + #[inline] + fn from(node: NamedOrBlankNodeRef<'a>) -> Self { + match node { + NamedOrBlankNodeRef::NamedNode(node) => rio::NamedNode::from(node).into(), + NamedOrBlankNodeRef::BlankNode(node) => rio::BlankNode::from(node).into(), + } + } +} + /// The owned 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 [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple). #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub enum Subject { @@ -89,6 +246,23 @@ impl From> for Subject { } } +impl From for Subject { + #[inline] + fn from(node: NamedOrBlankNode) -> Self { + match node { + NamedOrBlankNode::NamedNode(node) => node.into(), + NamedOrBlankNode::BlankNode(node) => node.into(), + } + } +} + +impl From> for Subject { + #[inline] + fn from(node: NamedOrBlankNodeRef<'_>) -> Self { + node.into_owned().into() + } +} + /// The borrowed 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 [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple). #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] pub enum SubjectRef<'a> { @@ -183,6 +357,23 @@ impl<'a> From> for Subject { } } +impl<'a> From> for SubjectRef<'a> { + #[inline] + fn from(node: NamedOrBlankNodeRef<'a>) -> Self { + match node { + NamedOrBlankNodeRef::NamedNode(node) => node.into(), + NamedOrBlankNodeRef::BlankNode(node) => node.into(), + } + } +} + +impl<'a> From<&'a NamedOrBlankNode> for SubjectRef<'a> { + #[inline] + fn from(node: &'a NamedOrBlankNode) -> Self { + node.as_ref().into() + } +} + #[allow(clippy::unimplemented, clippy::fallible_impl_from)] impl<'a> From> for rio::NamedOrBlankNode<'a> { #[inline] @@ -299,6 +490,23 @@ impl From> for Term { } } +impl From for Term { + #[inline] + fn from(node: NamedOrBlankNode) -> Self { + match node { + NamedOrBlankNode::NamedNode(node) => node.into(), + NamedOrBlankNode::BlankNode(node) => node.into(), + } + } +} + +impl From> for Term { + #[inline] + fn from(node: NamedOrBlankNodeRef<'_>) -> Self { + node.into_owned().into() + } +} + impl From for Term { #[inline] fn from(node: Subject) -> Self { @@ -422,6 +630,23 @@ impl<'a> From<&'a Triple> for TermRef<'a> { } } +impl<'a> From> for TermRef<'a> { + #[inline] + fn from(node: NamedOrBlankNodeRef<'a>) -> Self { + match node { + NamedOrBlankNodeRef::NamedNode(node) => node.into(), + NamedOrBlankNodeRef::BlankNode(node) => node.into(), + } + } +} + +impl<'a> From<&'a NamedOrBlankNode> for TermRef<'a> { + #[inline] + fn from(node: &'a NamedOrBlankNode) -> Self { + node.as_ref().into() + } +} + impl<'a> From> for TermRef<'a> { #[inline] fn from(node: SubjectRef<'a>) -> Self { diff --git a/lib/src/sparql/algebra.rs b/lib/src/sparql/algebra.rs index 38a116d1..44f17ae2 100644 --- a/lib/src/sparql/algebra.rs +++ b/lib/src/sparql/algebra.rs @@ -171,7 +171,7 @@ impl<'a> TryFrom<&'a String> for Update { #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct QueryDataset { default: Option>, - named: Option>, + named: Option>, } impl QueryDataset { @@ -255,7 +255,7 @@ impl QueryDataset { } /// Returns the list of the available named graphs for the query or `None` if all graphs are available - pub fn available_named_graphs(&self) -> Option<&[Subject]> { + pub fn available_named_graphs(&self) -> Option<&[NamedOrBlankNode]> { self.named.as_deref() } @@ -272,7 +272,7 @@ impl QueryDataset { /// /// # Result::Ok::<_, Box>(()) /// ``` - pub fn set_available_named_graphs(&mut self, named_graphs: Vec) { + pub fn set_available_named_graphs(&mut self, named_graphs: Vec) { self.named = Some(named_graphs); } } diff --git a/lib/src/storage/numeric_encoder.rs b/lib/src/storage/numeric_encoder.rs index 065d6c83..695bde75 100644 --- a/lib/src/storage/numeric_encoder.rs +++ b/lib/src/storage/numeric_encoder.rs @@ -601,6 +601,15 @@ impl From> for EncodedTerm { } } +impl From> for EncodedTerm { + fn from(term: NamedOrBlankNodeRef<'_>) -> Self { + match term { + NamedOrBlankNodeRef::NamedNode(named_node) => named_node.into(), + NamedOrBlankNodeRef::BlankNode(blank_node) => blank_node.into(), + } + } +} + impl From> for EncodedTerm { fn from(term: SubjectRef<'_>) -> Self { match term { @@ -737,6 +746,16 @@ pub(crate) trait WriteEncoder: StrContainer { self.encode_rio_literal(literal.into()) } + fn encode_named_or_blank_node( + &self, + term: NamedOrBlankNodeRef<'_>, + ) -> Result { + match term { + NamedOrBlankNodeRef::NamedNode(named_node) => self.encode_named_node(named_node), + NamedOrBlankNodeRef::BlankNode(blank_node) => self.encode_blank_node(blank_node), + } + } + fn encode_subject(&self, term: SubjectRef<'_>) -> Result { match term { SubjectRef::NamedNode(named_node) => self.encode_named_node(named_node), @@ -1065,10 +1084,24 @@ pub(crate) trait Decoder: StrLookup { Term::NamedNode(named_node) => Ok(named_node.into()), Term::BlankNode(blank_node) => Ok(blank_node.into()), Term::Literal(_) => Err(DecoderError::Decoder { - msg: "A literal has been found instead of a named node".to_owned(), + msg: "A literal has been found instead of a subject node".to_owned(), + }), + Term::Triple(triple) => Ok(Subject::Triple(triple)), + } + } + + fn decode_named_or_blank_node( + &self, + encoded: &EncodedTerm, + ) -> Result> { + match self.decode_term(encoded)? { + Term::NamedNode(named_node) => Ok(named_node.into()), + Term::BlankNode(blank_node) => Ok(blank_node.into()), + Term::Literal(_) => Err(DecoderError::Decoder { + msg: "A literal has been found instead of a named or blank node".to_owned(), }), Term::Triple(_) => Err(DecoderError::Decoder { - msg: "A triple has been found instead of a named node".to_owned(), + msg: "A triple has been found instead of a named or blank node".to_owned(), }), } } diff --git a/lib/src/store.rs b/lib/src/store.rs index 6afa0996..7f785160 100644 --- a/lib/src/store.rs +++ b/lib/src/store.rs @@ -439,7 +439,7 @@ impl Store { /// let store = Store::new()?; /// store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?; /// store.insert(QuadRef::new(&ex, &ex, &ex, GraphNameRef::DefaultGraph))?; - /// assert_eq!(vec![Subject::from(ex)], store.named_graphs().collect::,_>>()?); + /// assert_eq!(vec![NamedOrBlankNode::from(ex)], store.named_graphs().collect::,_>>()?); /// # Result::<_,Box>::Ok(()) /// ``` pub fn named_graphs(&self) -> GraphNameIter { @@ -464,7 +464,7 @@ impl Store { /// ``` pub fn contains_named_graph<'a>( &self, - graph_name: impl Into>, + graph_name: impl Into>, ) -> Result { let graph_name = EncodedTerm::from(graph_name.into()); self.storage.contains_named_graph(&graph_name) @@ -487,9 +487,9 @@ impl Store { /// ``` pub fn insert_named_graph<'a>( &self, - graph_name: impl Into>, + graph_name: impl Into>, ) -> Result { - let graph_name = self.storage.encode_subject(graph_name.into())?; + let graph_name = self.storage.encode_named_or_blank_node(graph_name.into())?; self.storage.insert_named_graph(&graph_name) } @@ -541,7 +541,7 @@ impl Store { /// ``` pub fn remove_named_graph<'a>( &self, - graph_name: impl Into>, + graph_name: impl Into>, ) -> Result { let graph_name = EncodedTerm::from(graph_name.into()); self.storage.remove_named_graph(&graph_name) @@ -706,9 +706,9 @@ impl Transaction<'_> { /// Returns `true` if the graph was not already in the store. pub fn insert_named_graph<'a>( &self, - graph_name: impl Into>, + graph_name: impl Into>, ) -> Result { - let graph_name = self.storage.encode_subject(graph_name.into())?; + let graph_name = self.storage.encode_named_or_blank_node(graph_name.into())?; self.storage.insert_named_graph(&graph_name) } } @@ -737,13 +737,13 @@ pub struct GraphNameIter { } impl Iterator for GraphNameIter { - type Item = Result; + type Item = Result; - fn next(&mut self) -> Option> { + fn next(&mut self) -> Option> { Some( - self.iter - .next()? - .and_then(|graph_name| Ok(self.store.storage.decode_subject(&graph_name)?)), + self.iter.next()?.and_then(|graph_name| { + Ok(self.store.storage.decode_named_or_blank_node(&graph_name)?) + }), ) } diff --git a/lib/tests/store.rs b/lib/tests/store.rs index d1dbf814..c4a2b146 100644 --- a/lib/tests/store.rs +++ b/lib/tests/store.rs @@ -181,7 +181,7 @@ fn test_backward_compatibility() -> io::Result<()> { } assert!(store.contains_named_graph(graph_name)?); assert_eq!( - vec![Subject::from(graph_name)], + vec![NamedOrBlankNode::from(graph_name)], store.named_graphs().collect::>>()? ); }; diff --git a/python/src/model.rs b/python/src/model.rs index 02bde29b..12e61db0 100644 --- a/python/src/model.rs +++ b/python/src/model.rs @@ -39,6 +39,12 @@ impl From for NamedNode { } } +impl From for NamedOrBlankNode { + fn from(node: PyNamedNode) -> Self { + node.inner.into() + } +} + impl From for Subject { fn from(node: PyNamedNode) -> Self { node.inner.into() @@ -138,6 +144,12 @@ impl From for BlankNode { } } +impl From for NamedOrBlankNode { + fn from(node: PyBlankNode) -> Self { + node.inner.into() + } +} + impl From for Subject { fn from(node: PyBlankNode) -> Self { node.inner.into() @@ -404,6 +416,39 @@ impl PyObjectProtocol for PyDefaultGraph { } } +#[derive(FromPyObject)] +pub enum PyNamedOrBlankNode { + NamedNode(PyNamedNode), + BlankNode(PyBlankNode), +} + +impl From for NamedOrBlankNode { + fn from(node: PyNamedOrBlankNode) -> Self { + match node { + PyNamedOrBlankNode::NamedNode(node) => node.into(), + PyNamedOrBlankNode::BlankNode(node) => node.into(), + } + } +} + +impl From for PyNamedOrBlankNode { + fn from(node: NamedOrBlankNode) -> Self { + match node { + NamedOrBlankNode::NamedNode(node) => Self::NamedNode(node.into()), + NamedOrBlankNode::BlankNode(node) => Self::BlankNode(node.into()), + } + } +} + +impl IntoPy for PyNamedOrBlankNode { + fn into_py(self, py: Python<'_>) -> PyObject { + match self { + Self::NamedNode(node) => node.into_py(py), + Self::BlankNode(node) => node.into_py(py), + } + } +} + #[derive(FromPyObject)] pub enum PySubject { NamedNode(PyNamedNode), @@ -424,9 +469,9 @@ impl From for Subject { impl From for PySubject { fn from(node: Subject) -> Self { match node { - Subject::NamedNode(node) => PySubject::NamedNode(node.into()), - Subject::BlankNode(node) => PySubject::BlankNode(node.into()), - Subject::Triple(triple) => PySubject::Triple(triple.as_ref().clone().into()), + Subject::NamedNode(node) => Self::NamedNode(node.into()), + Subject::BlankNode(node) => Self::BlankNode(node.into()), + Subject::Triple(triple) => Self::Triple(triple.as_ref().clone().into()), } } } @@ -434,9 +479,9 @@ impl From for PySubject { impl IntoPy for PySubject { fn into_py(self, py: Python<'_>) -> PyObject { match self { - PySubject::NamedNode(node) => node.into_py(py), - PySubject::BlankNode(node) => node.into_py(py), - PySubject::Triple(triple) => triple.into_py(py), + Self::NamedNode(node) => node.into_py(py), + Self::BlankNode(node) => node.into_py(py), + Self::Triple(triple) => triple.into_py(py), } } } @@ -463,10 +508,10 @@ impl From for Term { impl From for PyTerm { fn from(term: Term) -> Self { match term { - Term::NamedNode(node) => PyTerm::NamedNode(node.into()), - Term::BlankNode(node) => PyTerm::BlankNode(node.into()), - Term::Literal(literal) => PyTerm::Literal(literal.into()), - Term::Triple(triple) => PyTerm::Triple(triple.as_ref().clone().into()), + Term::NamedNode(node) => Self::NamedNode(node.into()), + Term::BlankNode(node) => Self::BlankNode(node.into()), + Term::Literal(literal) => Self::Literal(literal.into()), + Term::Triple(triple) => Self::Triple(triple.as_ref().clone().into()), } } } @@ -474,10 +519,10 @@ impl From for PyTerm { impl IntoPy for PyTerm { fn into_py(self, py: Python<'_>) -> PyObject { match self { - PyTerm::NamedNode(node) => node.into_py(py), - PyTerm::BlankNode(node) => node.into_py(py), - PyTerm::Literal(literal) => literal.into_py(py), - PyTerm::Triple(triple) => triple.into_py(py), + Self::NamedNode(node) => node.into_py(py), + Self::BlankNode(node) => node.into_py(py), + Self::Literal(literal) => literal.into_py(py), + Self::Triple(triple) => triple.into_py(py), } } } @@ -645,9 +690,9 @@ impl From for GraphName { impl From for PyGraphName { fn from(graph_name: GraphName) -> Self { match graph_name { - GraphName::NamedNode(node) => PyGraphName::NamedNode(node.into()), - GraphName::BlankNode(node) => PyGraphName::BlankNode(node.into()), - GraphName::DefaultGraph => PyGraphName::DefaultGraph(PyDefaultGraph::new()), + GraphName::NamedNode(node) => Self::NamedNode(node.into()), + GraphName::BlankNode(node) => Self::BlankNode(node.into()), + GraphName::DefaultGraph => Self::DefaultGraph(PyDefaultGraph::new()), } } } @@ -655,9 +700,9 @@ impl From for PyGraphName { impl IntoPy for PyGraphName { fn into_py(self, py: Python<'_>) -> PyObject { match self { - PyGraphName::NamedNode(node) => node.into_py(py), - PyGraphName::BlankNode(node) => node.into_py(py), - PyGraphName::DefaultGraph(node) => node.into_py(py), + Self::NamedNode(node) => node.into_py(py), + Self::BlankNode(node) => node.into_py(py), + Self::DefaultGraph(node) => node.into_py(py), } } } @@ -943,9 +988,41 @@ impl<'a> TryFrom<&'a PyAny> for PyNamedNodeRef<'a> { } } +pub enum PyNamedOrBlankNodeRef<'a> { + NamedNode(PyRef<'a, PyNamedNode>), + BlankNode(PyRef<'a, PyBlankNode>), +} + +impl<'a> From<&'a PyNamedOrBlankNodeRef<'a>> for NamedOrBlankNodeRef<'a> { + fn from(value: &'a PyNamedOrBlankNodeRef<'a>) -> Self { + match value { + PyNamedOrBlankNodeRef::NamedNode(value) => value.inner.as_ref().into(), + PyNamedOrBlankNodeRef::BlankNode(value) => value.inner.as_ref().into(), + } + } +} + +impl<'a> TryFrom<&'a PyAny> for PyNamedOrBlankNodeRef<'a> { + type Error = PyErr; + + fn try_from(value: &'a PyAny) -> PyResult { + if let Ok(node) = value.downcast::>() { + Ok(Self::NamedNode(node.borrow())) + } else if let Ok(node) = value.downcast::>() { + Ok(Self::BlankNode(node.borrow())) + } else { + Err(PyTypeError::new_err(format!( + "{} is not an RDF named or blank node", + value.get_type().name()?, + ))) + } + } +} + pub enum PySubjectRef<'a> { NamedNode(PyRef<'a, PyNamedNode>), BlankNode(PyRef<'a, PyBlankNode>), + Triple(PyRef<'a, PyTriple>), } impl<'a> From<&'a PySubjectRef<'a>> for SubjectRef<'a> { @@ -953,6 +1030,7 @@ impl<'a> From<&'a PySubjectRef<'a>> for SubjectRef<'a> { match value { PySubjectRef::NamedNode(value) => value.inner.as_ref().into(), PySubjectRef::BlankNode(value) => value.inner.as_ref().into(), + PySubjectRef::Triple(value) => (&value.inner).into(), } } } @@ -965,6 +1043,8 @@ impl<'a> TryFrom<&'a PyAny> for PySubjectRef<'a> { Ok(Self::NamedNode(node.borrow())) } else if let Ok(node) = value.downcast::>() { Ok(Self::BlankNode(node.borrow())) + } else if let Ok(node) = value.downcast::>() { + Ok(Self::Triple(node.borrow())) } else { Err(PyTypeError::new_err(format!( "{} is not an RDF named or blank node", @@ -978,6 +1058,7 @@ pub enum PyTermRef<'a> { NamedNode(PyRef<'a, PyNamedNode>), BlankNode(PyRef<'a, PyBlankNode>), Literal(PyRef<'a, PyLiteral>), + Triple(PyRef<'a, PyTriple>), } impl<'a> From<&'a PyTermRef<'a>> for TermRef<'a> { @@ -986,6 +1067,7 @@ impl<'a> From<&'a PyTermRef<'a>> for TermRef<'a> { PyTermRef::NamedNode(value) => value.inner.as_ref().into(), PyTermRef::BlankNode(value) => value.inner.as_ref().into(), PyTermRef::Literal(value) => value.inner.as_ref().into(), + PyTermRef::Triple(value) => (&value.inner).into(), } } } @@ -1006,6 +1088,8 @@ impl<'a> TryFrom<&'a PyAny> for PyTermRef<'a> { Ok(Self::BlankNode(node.borrow())) } else if let Ok(node) = value.downcast::>() { Ok(Self::Literal(node.borrow())) + } else if let Ok(node) = value.downcast::>() { + Ok(Self::Triple(node.borrow())) } else { Err(PyTypeError::new_err(format!( "{} is not an RDF term", diff --git a/python/src/sparql.rs b/python/src/sparql.rs index e0173d83..b79fb756 100644 --- a/python/src/sparql.rs +++ b/python/src/sparql.rs @@ -50,7 +50,7 @@ pub fn parse_query( query.dataset_mut().set_available_named_graphs( named_graphs .iter()? - .map(|graph| Ok(graph?.extract::()?.into())) + .map(|graph| Ok(graph?.extract::()?.into())) .collect::>()?, ) } diff --git a/python/src/store.rs b/python/src/store.rs index 4a8c9295..b815e6fd 100644 --- a/python/src/store.rs +++ b/python/src/store.rs @@ -385,11 +385,11 @@ impl PyStore { PyGraphNameRef::DefaultGraph => Ok(()), PyGraphNameRef::NamedNode(graph_name) => self .inner - .insert_named_graph(&PySubjectRef::NamedNode(graph_name)) + .insert_named_graph(&PyNamedOrBlankNodeRef::NamedNode(graph_name)) .map(|_| ()), PyGraphNameRef::BlankNode(graph_name) => self .inner - .insert_named_graph(&PySubjectRef::BlankNode(graph_name)) + .insert_named_graph(&PyNamedOrBlankNodeRef::BlankNode(graph_name)) .map(|_| ()), } .map_err(map_io_err) @@ -414,11 +414,11 @@ impl PyStore { PyGraphNameRef::DefaultGraph => self.inner.clear_graph(GraphNameRef::DefaultGraph), PyGraphNameRef::NamedNode(graph_name) => self .inner - .remove_named_graph(&PySubjectRef::NamedNode(graph_name)) + .remove_named_graph(&PyNamedOrBlankNodeRef::NamedNode(graph_name)) .map(|_| ()), PyGraphNameRef::BlankNode(graph_name) => self .inner - .remove_named_graph(&PySubjectRef::BlankNode(graph_name)) + .remove_named_graph(&PyNamedOrBlankNodeRef::BlankNode(graph_name)) .map(|_| ()), } .map_err(map_io_err)?; @@ -487,7 +487,7 @@ impl PyIterProtocol for GraphNameIter { slf.into() } - fn __next__(mut slf: PyRefMut) -> PyResult> { + fn __next__(mut slf: PyRefMut) -> PyResult> { slf.inner .next() .map(|q| Ok(q.map_err(map_io_err)?.into())) diff --git a/server/src/main.rs b/server/src/main.rs index 366ef6ab..1e03256e 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -21,7 +21,7 @@ use http_types::{ StatusCode, }; use oxigraph::io::{DatasetFormat, GraphFormat}; -use oxigraph::model::{GraphName, GraphNameRef, NamedNode, Subject}; +use oxigraph::model::{GraphName, GraphNameRef, NamedNode, NamedOrBlankNode}; use oxigraph::sparql::{Query, QueryResults, QueryResultsFormat, Update}; use oxigraph::store::Store; use oxiri::Iri; @@ -407,7 +407,7 @@ fn evaluate_sparql_query( let named_graph_uris = named_graph_uris .into_iter() .map(|e| Ok(NamedNode::new(e)?.into())) - .collect::>>() + .collect::>>() .map_err(bad_request)?; if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() { @@ -490,7 +490,7 @@ fn evaluate_sparql_update( let named_graph_uris = named_graph_uris .into_iter() .map(|e| Ok(NamedNode::new(e)?.into())) - .collect::>>() + .collect::>>() .map_err(bad_request)?; if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() { for using in update.using_datasets_mut() { diff --git a/testsuite/src/sparql_evaluator.rs b/testsuite/src/sparql_evaluator.rs index 1aa5a66c..5ac05e12 100644 --- a/testsuite/src/sparql_evaluator.rs +++ b/testsuite/src/sparql_evaluator.rs @@ -113,7 +113,7 @@ fn evaluate_evaluation_test(test: &Test) -> Result<()> { } } for graph_name in query.dataset().available_named_graphs().unwrap_or(&[]) { - if let Subject::NamedNode(graph_name) = graph_name { + if let NamedOrBlankNode::NamedNode(graph_name) = graph_name { load_to_store(graph_name.as_str(), &store, graph_name.as_ref())?; } else { return Err(anyhow!( diff --git a/wikibase/src/main.rs b/wikibase/src/main.rs index 10e867ab..3f06019f 100644 --- a/wikibase/src/main.rs +++ b/wikibase/src/main.rs @@ -21,7 +21,7 @@ use http_types::{ StatusCode, }; use oxigraph::io::GraphFormat; -use oxigraph::model::{GraphName, NamedNode, Subject}; +use oxigraph::model::{GraphName, NamedNode, NamedOrBlankNode}; use oxigraph::sparql::{Query, QueryResults, QueryResultsFormat}; use oxigraph::store::Store; use std::str::FromStr; @@ -202,7 +202,7 @@ fn evaluate_sparql_query( let named_graph_uris = named_graph_uris .into_iter() .map(|e| Ok(NamedNode::new(e)?.into())) - .collect::>>() + .collect::>>() .map_err(bad_request)?; if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() {