Fixes the input type of graph manipulation methods

Nested triples are not allowed there
pull/171/head
Tpt 4 years ago
parent 0071f82662
commit 4302316a41
  1. 3
      lib/src/model/mod.rs
  2. 225
      lib/src/model/triple.rs
  3. 6
      lib/src/sparql/algebra.rs
  4. 37
      lib/src/storage/numeric_encoder.rs
  5. 24
      lib/src/store.rs
  6. 2
      lib/tests/store.rs
  7. 124
      python/src/model.rs
  8. 2
      python/src/sparql.rs
  9. 10
      python/src/store.rs
  10. 6
      server/src/main.rs
  11. 2
      testsuite/src/sparql_evaluator.rs
  12. 4
      wikibase/src/main.rs

@ -22,7 +22,8 @@ pub use self::literal::{Literal, LiteralRef};
pub use self::named_node::{NamedNode, NamedNodeRef}; pub use self::named_node::{NamedNode, NamedNodeRef};
pub use self::parser::TermParseError; pub use self::parser::TermParseError;
pub use self::triple::{ 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 oxilangtag::LanguageTagParseError;
pub use oxiri::IriParseError; pub use oxiri::IriParseError;

@ -6,6 +6,163 @@ use rio_api::model as rio;
use std::fmt; use std::fmt;
use std::sync::Arc; 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<NamedNode> for NamedOrBlankNode {
#[inline]
fn from(node: NamedNode) -> Self {
Self::NamedNode(node)
}
}
impl From<NamedNodeRef<'_>> for NamedOrBlankNode {
#[inline]
fn from(node: NamedNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<BlankNode> for NamedOrBlankNode {
#[inline]
fn from(node: BlankNode) -> Self {
Self::BlankNode(node)
}
}
impl From<BlankNodeRef<'_>> 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<NamedNodeRef<'a>> 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<BlankNodeRef<'a>> 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<NamedOrBlankNodeRef<'a>> for NamedOrBlankNode {
#[inline]
fn from(node: NamedOrBlankNodeRef<'a>) -> Self {
node.into_owned()
}
}
impl<'a> From<NamedOrBlankNodeRef<'a>> 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). /// 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)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Subject { pub enum Subject {
@ -89,6 +246,23 @@ impl From<TripleRef<'_>> for Subject {
} }
} }
impl From<NamedOrBlankNode> for Subject {
#[inline]
fn from(node: NamedOrBlankNode) -> Self {
match node {
NamedOrBlankNode::NamedNode(node) => node.into(),
NamedOrBlankNode::BlankNode(node) => node.into(),
}
}
}
impl From<NamedOrBlankNodeRef<'_>> 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). /// 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)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum SubjectRef<'a> { pub enum SubjectRef<'a> {
@ -183,6 +357,23 @@ impl<'a> From<SubjectRef<'a>> for Subject {
} }
} }
impl<'a> From<NamedOrBlankNodeRef<'a>> 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)] #[allow(clippy::unimplemented, clippy::fallible_impl_from)]
impl<'a> From<SubjectRef<'a>> for rio::NamedOrBlankNode<'a> { impl<'a> From<SubjectRef<'a>> for rio::NamedOrBlankNode<'a> {
#[inline] #[inline]
@ -299,6 +490,23 @@ impl From<TripleRef<'_>> for Term {
} }
} }
impl From<NamedOrBlankNode> for Term {
#[inline]
fn from(node: NamedOrBlankNode) -> Self {
match node {
NamedOrBlankNode::NamedNode(node) => node.into(),
NamedOrBlankNode::BlankNode(node) => node.into(),
}
}
}
impl From<NamedOrBlankNodeRef<'_>> for Term {
#[inline]
fn from(node: NamedOrBlankNodeRef<'_>) -> Self {
node.into_owned().into()
}
}
impl From<Subject> for Term { impl From<Subject> for Term {
#[inline] #[inline]
fn from(node: Subject) -> Self { fn from(node: Subject) -> Self {
@ -422,6 +630,23 @@ impl<'a> From<&'a Triple> for TermRef<'a> {
} }
} }
impl<'a> From<NamedOrBlankNodeRef<'a>> 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<SubjectRef<'a>> for TermRef<'a> { impl<'a> From<SubjectRef<'a>> for TermRef<'a> {
#[inline] #[inline]
fn from(node: SubjectRef<'a>) -> Self { fn from(node: SubjectRef<'a>) -> Self {

@ -171,7 +171,7 @@ impl<'a> TryFrom<&'a String> for Update {
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct QueryDataset { pub struct QueryDataset {
default: Option<Vec<GraphName>>, default: Option<Vec<GraphName>>,
named: Option<Vec<Subject>>, named: Option<Vec<NamedOrBlankNode>>,
} }
impl QueryDataset { 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 /// 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() self.named.as_deref()
} }
@ -272,7 +272,7 @@ impl QueryDataset {
/// ///
/// # Result::Ok::<_, Box<dyn std::error::Error>>(()) /// # Result::Ok::<_, Box<dyn std::error::Error>>(())
/// ``` /// ```
pub fn set_available_named_graphs(&mut self, named_graphs: Vec<Subject>) { pub fn set_available_named_graphs(&mut self, named_graphs: Vec<NamedOrBlankNode>) {
self.named = Some(named_graphs); self.named = Some(named_graphs);
} }
} }

@ -601,6 +601,15 @@ impl From<LiteralRef<'_>> for EncodedTerm {
} }
} }
impl From<NamedOrBlankNodeRef<'_>> 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<SubjectRef<'_>> for EncodedTerm { impl From<SubjectRef<'_>> for EncodedTerm {
fn from(term: SubjectRef<'_>) -> Self { fn from(term: SubjectRef<'_>) -> Self {
match term { match term {
@ -737,6 +746,16 @@ pub(crate) trait WriteEncoder: StrContainer {
self.encode_rio_literal(literal.into()) self.encode_rio_literal(literal.into())
} }
fn encode_named_or_blank_node(
&self,
term: NamedOrBlankNodeRef<'_>,
) -> Result<EncodedTerm, Self::Error> {
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<EncodedTerm, Self::Error> { fn encode_subject(&self, term: SubjectRef<'_>) -> Result<EncodedTerm, Self::Error> {
match term { match term {
SubjectRef::NamedNode(named_node) => self.encode_named_node(named_node), 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::NamedNode(named_node) => Ok(named_node.into()),
Term::BlankNode(blank_node) => Ok(blank_node.into()), Term::BlankNode(blank_node) => Ok(blank_node.into()),
Term::Literal(_) => Err(DecoderError::Decoder { 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<NamedOrBlankNode, DecoderError<Self::Error>> {
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 { 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(),
}), }),
} }
} }

@ -439,7 +439,7 @@ impl Store {
/// let store = Store::new()?; /// let store = Store::new()?;
/// store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?; /// store.insert(QuadRef::new(&ex, &ex, &ex, &ex))?;
/// store.insert(QuadRef::new(&ex, &ex, &ex, GraphNameRef::DefaultGraph))?; /// store.insert(QuadRef::new(&ex, &ex, &ex, GraphNameRef::DefaultGraph))?;
/// assert_eq!(vec![Subject::from(ex)], store.named_graphs().collect::<Result<Vec<_>,_>>()?); /// assert_eq!(vec![NamedOrBlankNode::from(ex)], store.named_graphs().collect::<Result<Vec<_>,_>>()?);
/// # Result::<_,Box<dyn std::error::Error>>::Ok(()) /// # Result::<_,Box<dyn std::error::Error>>::Ok(())
/// ``` /// ```
pub fn named_graphs(&self) -> GraphNameIter { pub fn named_graphs(&self) -> GraphNameIter {
@ -464,7 +464,7 @@ impl Store {
/// ``` /// ```
pub fn contains_named_graph<'a>( pub fn contains_named_graph<'a>(
&self, &self,
graph_name: impl Into<SubjectRef<'a>>, graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, io::Error> { ) -> Result<bool, io::Error> {
let graph_name = EncodedTerm::from(graph_name.into()); let graph_name = EncodedTerm::from(graph_name.into());
self.storage.contains_named_graph(&graph_name) self.storage.contains_named_graph(&graph_name)
@ -487,9 +487,9 @@ impl Store {
/// ``` /// ```
pub fn insert_named_graph<'a>( pub fn insert_named_graph<'a>(
&self, &self,
graph_name: impl Into<SubjectRef<'a>>, graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, io::Error> { ) -> Result<bool, io::Error> {
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) self.storage.insert_named_graph(&graph_name)
} }
@ -541,7 +541,7 @@ impl Store {
/// ``` /// ```
pub fn remove_named_graph<'a>( pub fn remove_named_graph<'a>(
&self, &self,
graph_name: impl Into<SubjectRef<'a>>, graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, io::Error> { ) -> Result<bool, io::Error> {
let graph_name = EncodedTerm::from(graph_name.into()); let graph_name = EncodedTerm::from(graph_name.into());
self.storage.remove_named_graph(&graph_name) self.storage.remove_named_graph(&graph_name)
@ -706,9 +706,9 @@ impl Transaction<'_> {
/// Returns `true` if the graph was not already in the store. /// Returns `true` if the graph was not already in the store.
pub fn insert_named_graph<'a>( pub fn insert_named_graph<'a>(
&self, &self,
graph_name: impl Into<SubjectRef<'a>>, graph_name: impl Into<NamedOrBlankNodeRef<'a>>,
) -> Result<bool, UnabortableTransactionError> { ) -> Result<bool, UnabortableTransactionError> {
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) self.storage.insert_named_graph(&graph_name)
} }
} }
@ -737,13 +737,13 @@ pub struct GraphNameIter {
} }
impl Iterator for GraphNameIter { impl Iterator for GraphNameIter {
type Item = Result<Subject, io::Error>; type Item = Result<NamedOrBlankNode, io::Error>;
fn next(&mut self) -> Option<Result<Subject, io::Error>> { fn next(&mut self) -> Option<Result<NamedOrBlankNode, io::Error>> {
Some( Some(
self.iter self.iter.next()?.and_then(|graph_name| {
.next()? Ok(self.store.storage.decode_named_or_blank_node(&graph_name)?)
.and_then(|graph_name| Ok(self.store.storage.decode_subject(&graph_name)?)), }),
) )
} }

@ -181,7 +181,7 @@ fn test_backward_compatibility() -> io::Result<()> {
} }
assert!(store.contains_named_graph(graph_name)?); assert!(store.contains_named_graph(graph_name)?);
assert_eq!( assert_eq!(
vec![Subject::from(graph_name)], vec![NamedOrBlankNode::from(graph_name)],
store.named_graphs().collect::<io::Result<Vec<_>>>()? store.named_graphs().collect::<io::Result<Vec<_>>>()?
); );
}; };

@ -39,6 +39,12 @@ impl From<PyNamedNode> for NamedNode {
} }
} }
impl From<PyNamedNode> for NamedOrBlankNode {
fn from(node: PyNamedNode) -> Self {
node.inner.into()
}
}
impl From<PyNamedNode> for Subject { impl From<PyNamedNode> for Subject {
fn from(node: PyNamedNode) -> Self { fn from(node: PyNamedNode) -> Self {
node.inner.into() node.inner.into()
@ -138,6 +144,12 @@ impl From<PyBlankNode> for BlankNode {
} }
} }
impl From<PyBlankNode> for NamedOrBlankNode {
fn from(node: PyBlankNode) -> Self {
node.inner.into()
}
}
impl From<PyBlankNode> for Subject { impl From<PyBlankNode> for Subject {
fn from(node: PyBlankNode) -> Self { fn from(node: PyBlankNode) -> Self {
node.inner.into() node.inner.into()
@ -404,6 +416,39 @@ impl PyObjectProtocol for PyDefaultGraph {
} }
} }
#[derive(FromPyObject)]
pub enum PyNamedOrBlankNode {
NamedNode(PyNamedNode),
BlankNode(PyBlankNode),
}
impl From<PyNamedOrBlankNode> for NamedOrBlankNode {
fn from(node: PyNamedOrBlankNode) -> Self {
match node {
PyNamedOrBlankNode::NamedNode(node) => node.into(),
PyNamedOrBlankNode::BlankNode(node) => node.into(),
}
}
}
impl From<NamedOrBlankNode> 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<PyObject> 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)] #[derive(FromPyObject)]
pub enum PySubject { pub enum PySubject {
NamedNode(PyNamedNode), NamedNode(PyNamedNode),
@ -424,9 +469,9 @@ impl From<PySubject> for Subject {
impl From<Subject> for PySubject { impl From<Subject> for PySubject {
fn from(node: Subject) -> Self { fn from(node: Subject) -> Self {
match node { match node {
Subject::NamedNode(node) => PySubject::NamedNode(node.into()), Subject::NamedNode(node) => Self::NamedNode(node.into()),
Subject::BlankNode(node) => PySubject::BlankNode(node.into()), Subject::BlankNode(node) => Self::BlankNode(node.into()),
Subject::Triple(triple) => PySubject::Triple(triple.as_ref().clone().into()), Subject::Triple(triple) => Self::Triple(triple.as_ref().clone().into()),
} }
} }
} }
@ -434,9 +479,9 @@ impl From<Subject> for PySubject {
impl IntoPy<PyObject> for PySubject { impl IntoPy<PyObject> for PySubject {
fn into_py(self, py: Python<'_>) -> PyObject { fn into_py(self, py: Python<'_>) -> PyObject {
match self { match self {
PySubject::NamedNode(node) => node.into_py(py), Self::NamedNode(node) => node.into_py(py),
PySubject::BlankNode(node) => node.into_py(py), Self::BlankNode(node) => node.into_py(py),
PySubject::Triple(triple) => triple.into_py(py), Self::Triple(triple) => triple.into_py(py),
} }
} }
} }
@ -463,10 +508,10 @@ impl From<PyTerm> for Term {
impl From<Term> for PyTerm { impl From<Term> for PyTerm {
fn from(term: Term) -> Self { fn from(term: Term) -> Self {
match term { match term {
Term::NamedNode(node) => PyTerm::NamedNode(node.into()), Term::NamedNode(node) => Self::NamedNode(node.into()),
Term::BlankNode(node) => PyTerm::BlankNode(node.into()), Term::BlankNode(node) => Self::BlankNode(node.into()),
Term::Literal(literal) => PyTerm::Literal(literal.into()), Term::Literal(literal) => Self::Literal(literal.into()),
Term::Triple(triple) => PyTerm::Triple(triple.as_ref().clone().into()), Term::Triple(triple) => Self::Triple(triple.as_ref().clone().into()),
} }
} }
} }
@ -474,10 +519,10 @@ impl From<Term> for PyTerm {
impl IntoPy<PyObject> for PyTerm { impl IntoPy<PyObject> for PyTerm {
fn into_py(self, py: Python<'_>) -> PyObject { fn into_py(self, py: Python<'_>) -> PyObject {
match self { match self {
PyTerm::NamedNode(node) => node.into_py(py), Self::NamedNode(node) => node.into_py(py),
PyTerm::BlankNode(node) => node.into_py(py), Self::BlankNode(node) => node.into_py(py),
PyTerm::Literal(literal) => literal.into_py(py), Self::Literal(literal) => literal.into_py(py),
PyTerm::Triple(triple) => triple.into_py(py), Self::Triple(triple) => triple.into_py(py),
} }
} }
} }
@ -645,9 +690,9 @@ impl From<PyGraphName> for GraphName {
impl From<GraphName> for PyGraphName { impl From<GraphName> for PyGraphName {
fn from(graph_name: GraphName) -> Self { fn from(graph_name: GraphName) -> Self {
match graph_name { match graph_name {
GraphName::NamedNode(node) => PyGraphName::NamedNode(node.into()), GraphName::NamedNode(node) => Self::NamedNode(node.into()),
GraphName::BlankNode(node) => PyGraphName::BlankNode(node.into()), GraphName::BlankNode(node) => Self::BlankNode(node.into()),
GraphName::DefaultGraph => PyGraphName::DefaultGraph(PyDefaultGraph::new()), GraphName::DefaultGraph => Self::DefaultGraph(PyDefaultGraph::new()),
} }
} }
} }
@ -655,9 +700,9 @@ impl From<GraphName> for PyGraphName {
impl IntoPy<PyObject> for PyGraphName { impl IntoPy<PyObject> for PyGraphName {
fn into_py(self, py: Python<'_>) -> PyObject { fn into_py(self, py: Python<'_>) -> PyObject {
match self { match self {
PyGraphName::NamedNode(node) => node.into_py(py), Self::NamedNode(node) => node.into_py(py),
PyGraphName::BlankNode(node) => node.into_py(py), Self::BlankNode(node) => node.into_py(py),
PyGraphName::DefaultGraph(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<Self> {
if let Ok(node) = value.downcast::<PyCell<PyNamedNode>>() {
Ok(Self::NamedNode(node.borrow()))
} else if let Ok(node) = value.downcast::<PyCell<PyBlankNode>>() {
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> { pub enum PySubjectRef<'a> {
NamedNode(PyRef<'a, PyNamedNode>), NamedNode(PyRef<'a, PyNamedNode>),
BlankNode(PyRef<'a, PyBlankNode>), BlankNode(PyRef<'a, PyBlankNode>),
Triple(PyRef<'a, PyTriple>),
} }
impl<'a> From<&'a PySubjectRef<'a>> for SubjectRef<'a> { impl<'a> From<&'a PySubjectRef<'a>> for SubjectRef<'a> {
@ -953,6 +1030,7 @@ impl<'a> From<&'a PySubjectRef<'a>> for SubjectRef<'a> {
match value { match value {
PySubjectRef::NamedNode(value) => value.inner.as_ref().into(), PySubjectRef::NamedNode(value) => value.inner.as_ref().into(),
PySubjectRef::BlankNode(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())) Ok(Self::NamedNode(node.borrow()))
} else if let Ok(node) = value.downcast::<PyCell<PyBlankNode>>() { } else if let Ok(node) = value.downcast::<PyCell<PyBlankNode>>() {
Ok(Self::BlankNode(node.borrow())) Ok(Self::BlankNode(node.borrow()))
} else if let Ok(node) = value.downcast::<PyCell<PyTriple>>() {
Ok(Self::Triple(node.borrow()))
} else { } else {
Err(PyTypeError::new_err(format!( Err(PyTypeError::new_err(format!(
"{} is not an RDF named or blank node", "{} is not an RDF named or blank node",
@ -978,6 +1058,7 @@ pub enum PyTermRef<'a> {
NamedNode(PyRef<'a, PyNamedNode>), NamedNode(PyRef<'a, PyNamedNode>),
BlankNode(PyRef<'a, PyBlankNode>), BlankNode(PyRef<'a, PyBlankNode>),
Literal(PyRef<'a, PyLiteral>), Literal(PyRef<'a, PyLiteral>),
Triple(PyRef<'a, PyTriple>),
} }
impl<'a> From<&'a PyTermRef<'a>> for TermRef<'a> { 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::NamedNode(value) => value.inner.as_ref().into(),
PyTermRef::BlankNode(value) => value.inner.as_ref().into(), PyTermRef::BlankNode(value) => value.inner.as_ref().into(),
PyTermRef::Literal(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())) Ok(Self::BlankNode(node.borrow()))
} else if let Ok(node) = value.downcast::<PyCell<PyLiteral>>() { } else if let Ok(node) = value.downcast::<PyCell<PyLiteral>>() {
Ok(Self::Literal(node.borrow())) Ok(Self::Literal(node.borrow()))
} else if let Ok(node) = value.downcast::<PyCell<PyTriple>>() {
Ok(Self::Triple(node.borrow()))
} else { } else {
Err(PyTypeError::new_err(format!( Err(PyTypeError::new_err(format!(
"{} is not an RDF term", "{} is not an RDF term",

@ -50,7 +50,7 @@ pub fn parse_query(
query.dataset_mut().set_available_named_graphs( query.dataset_mut().set_available_named_graphs(
named_graphs named_graphs
.iter()? .iter()?
.map(|graph| Ok(graph?.extract::<PySubject>()?.into())) .map(|graph| Ok(graph?.extract::<PyNamedOrBlankNode>()?.into()))
.collect::<PyResult<_>>()?, .collect::<PyResult<_>>()?,
) )
} }

@ -385,11 +385,11 @@ impl PyStore {
PyGraphNameRef::DefaultGraph => Ok(()), PyGraphNameRef::DefaultGraph => Ok(()),
PyGraphNameRef::NamedNode(graph_name) => self PyGraphNameRef::NamedNode(graph_name) => self
.inner .inner
.insert_named_graph(&PySubjectRef::NamedNode(graph_name)) .insert_named_graph(&PyNamedOrBlankNodeRef::NamedNode(graph_name))
.map(|_| ()), .map(|_| ()),
PyGraphNameRef::BlankNode(graph_name) => self PyGraphNameRef::BlankNode(graph_name) => self
.inner .inner
.insert_named_graph(&PySubjectRef::BlankNode(graph_name)) .insert_named_graph(&PyNamedOrBlankNodeRef::BlankNode(graph_name))
.map(|_| ()), .map(|_| ()),
} }
.map_err(map_io_err) .map_err(map_io_err)
@ -414,11 +414,11 @@ impl PyStore {
PyGraphNameRef::DefaultGraph => self.inner.clear_graph(GraphNameRef::DefaultGraph), PyGraphNameRef::DefaultGraph => self.inner.clear_graph(GraphNameRef::DefaultGraph),
PyGraphNameRef::NamedNode(graph_name) => self PyGraphNameRef::NamedNode(graph_name) => self
.inner .inner
.remove_named_graph(&PySubjectRef::NamedNode(graph_name)) .remove_named_graph(&PyNamedOrBlankNodeRef::NamedNode(graph_name))
.map(|_| ()), .map(|_| ()),
PyGraphNameRef::BlankNode(graph_name) => self PyGraphNameRef::BlankNode(graph_name) => self
.inner .inner
.remove_named_graph(&PySubjectRef::BlankNode(graph_name)) .remove_named_graph(&PyNamedOrBlankNodeRef::BlankNode(graph_name))
.map(|_| ()), .map(|_| ()),
} }
.map_err(map_io_err)?; .map_err(map_io_err)?;
@ -487,7 +487,7 @@ impl PyIterProtocol for GraphNameIter {
slf.into() slf.into()
} }
fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<PySubject>> { fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<PyNamedOrBlankNode>> {
slf.inner slf.inner
.next() .next()
.map(|q| Ok(q.map_err(map_io_err)?.into())) .map(|q| Ok(q.map_err(map_io_err)?.into()))

@ -21,7 +21,7 @@ use http_types::{
StatusCode, StatusCode,
}; };
use oxigraph::io::{DatasetFormat, GraphFormat}; 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::sparql::{Query, QueryResults, QueryResultsFormat, Update};
use oxigraph::store::Store; use oxigraph::store::Store;
use oxiri::Iri; use oxiri::Iri;
@ -407,7 +407,7 @@ fn evaluate_sparql_query(
let named_graph_uris = named_graph_uris let named_graph_uris = named_graph_uris
.into_iter() .into_iter()
.map(|e| Ok(NamedNode::new(e)?.into())) .map(|e| Ok(NamedNode::new(e)?.into()))
.collect::<Result<Vec<Subject>>>() .collect::<Result<Vec<NamedOrBlankNode>>>()
.map_err(bad_request)?; .map_err(bad_request)?;
if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() { 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 let named_graph_uris = named_graph_uris
.into_iter() .into_iter()
.map(|e| Ok(NamedNode::new(e)?.into())) .map(|e| Ok(NamedNode::new(e)?.into()))
.collect::<Result<Vec<Subject>>>() .collect::<Result<Vec<NamedOrBlankNode>>>()
.map_err(bad_request)?; .map_err(bad_request)?;
if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() { if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() {
for using in update.using_datasets_mut() { for using in update.using_datasets_mut() {

@ -113,7 +113,7 @@ fn evaluate_evaluation_test(test: &Test) -> Result<()> {
} }
} }
for graph_name in query.dataset().available_named_graphs().unwrap_or(&[]) { 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())?; load_to_store(graph_name.as_str(), &store, graph_name.as_ref())?;
} else { } else {
return Err(anyhow!( return Err(anyhow!(

@ -21,7 +21,7 @@ use http_types::{
StatusCode, StatusCode,
}; };
use oxigraph::io::GraphFormat; use oxigraph::io::GraphFormat;
use oxigraph::model::{GraphName, NamedNode, Subject}; use oxigraph::model::{GraphName, NamedNode, NamedOrBlankNode};
use oxigraph::sparql::{Query, QueryResults, QueryResultsFormat}; use oxigraph::sparql::{Query, QueryResults, QueryResultsFormat};
use oxigraph::store::Store; use oxigraph::store::Store;
use std::str::FromStr; use std::str::FromStr;
@ -202,7 +202,7 @@ fn evaluate_sparql_query(
let named_graph_uris = named_graph_uris let named_graph_uris = named_graph_uris
.into_iter() .into_iter()
.map(|e| Ok(NamedNode::new(e)?.into())) .map(|e| Ok(NamedNode::new(e)?.into()))
.collect::<Result<Vec<Subject>>>() .collect::<Result<Vec<NamedOrBlankNode>>>()
.map_err(bad_request)?; .map_err(bad_request)?;
if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() { if !default_graph_uris.is_empty() || !named_graph_uris.is_empty() {

Loading…
Cancel
Save