diff --git a/Cargo.lock b/Cargo.lock index c43744ae..c75714f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -676,12 +676,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "mownstr" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76aacdf8f9850a9db34e33e35abfc17a29b9577d0eb2cbfaeb734662cacca5b3" - [[package]] name = "nom" version = "7.1.0" @@ -789,7 +783,6 @@ dependencies = [ "sha-1", "sha2", "siphasher", - "sophia_api", "sparesults", "spargebra", "wasm-bindgen-test", @@ -852,7 +845,6 @@ dependencies = [ "oxilangtag", "oxiri", "rand", - "sophia_api", ] [[package]] @@ -1191,12 +1183,6 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" -[[package]] -name = "resiter" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd69ab1e90258b7769f0b5c46bfd802b8206d0707ced4ca4b9d5681b744de1be" - [[package]] name = "ring" version = "0.16.20" @@ -1443,32 +1429,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" -[[package]] -name = "sophia_api" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aad03aad8253bd0f7c5423da4a1aaf4b18e5856b40e8841063ba5226cebc5efb" -dependencies = [ - "lazy_static", - "mownstr", - "regex", - "resiter", - "sophia_iri", - "thiserror", -] - -[[package]] -name = "sophia_iri" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecf2b1953a03e53c8cbfb029646be5b75c7e3a83cde8ef16ffe185c471093437" -dependencies = [ - "lazy_static", - "mownstr", - "regex", - "thiserror", -] - [[package]] name = "sparesults" version = "0.1.0-beta.4" @@ -1562,26 +1522,6 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" -[[package]] -name = "thiserror" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "time" version = "0.3.7" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 4e90ae23..32040b78 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -18,7 +18,6 @@ all-features = true [features] default = [] -sophia = ["sophia_api", "oxrdf/sophia_api"] http_client = ["oxhttp", "oxhttp/rustls"] [dependencies] @@ -37,7 +36,6 @@ hex = "0.4" nom = "7" siphasher = "0.3" lazy_static = "1" -sophia_api = { version = "0.7", optional = true } num_cpus = "1" oxrdf = { version = "0.1.0-beta.4", path="oxrdf", features = ["rdf-star"] } spargebra = { version = "0.2.0-beta.4", path="spargebra", features = ["rdf-star"] } @@ -55,7 +53,6 @@ getrandom = {version="0.2", features=["js"]} [dev-dependencies] criterion = "0.3" oxhttp = "0.1" -sophia_api = { version = "0.7", features = ["test_macro"] } zstd = "0.10" [target.'cfg(target_arch = "wasm32")'.dev-dependencies] diff --git a/lib/README.md b/lib/README.md index 1c1786f9..dd288344 100644 --- a/lib/README.md +++ b/lib/README.md @@ -14,8 +14,6 @@ It also provides a set of utility functions for reading, writing, and processing Oxigraph is in heavy development and SPARQL query evaluation has not been optimized yet. -The disabled by default `"sophia"` feature provides [`sophia_api`](https://docs.rs/sophia_api/) traits implementation on Oxigraph terms and stores. - Oxigraph also provides [a standalone HTTP server](https://crates.io/crates/oxigraph_server) and [a Python library](https://oxigraph.org/pyoxigraph/) based on this library. diff --git a/lib/oxrdf/Cargo.toml b/lib/oxrdf/Cargo.toml index 62e716a3..c25587f8 100644 --- a/lib/oxrdf/Cargo.toml +++ b/lib/oxrdf/Cargo.toml @@ -21,7 +21,6 @@ rand = "0.8" oxilangtag = "0.1" oxiri = "0.2" lasso = { version = "0.6", features = ["inline-more"] } -sophia_api = { version = "0.7", optional = true } [package.metadata.docs.rs] all-features = true diff --git a/lib/oxrdf/src/lib.rs b/lib/oxrdf/src/lib.rs index 5d65c0d9..8a47b470 100644 --- a/lib/oxrdf/src/lib.rs +++ b/lib/oxrdf/src/lib.rs @@ -20,8 +20,6 @@ mod interning; mod literal; mod named_node; mod parser; -#[cfg(feature = "sophia_api")] -mod sophia; mod triple; mod variable; pub mod vocab; diff --git a/lib/oxrdf/src/sophia.rs b/lib/oxrdf/src/sophia.rs deleted file mode 100644 index 60a2da18..00000000 --- a/lib/oxrdf/src/sophia.rs +++ /dev/null @@ -1,456 +0,0 @@ -//! This crate provides implementation of [Sophia](https://docs.rs/sophia/) traits for the `model` module. - -use crate::*; -use sophia_api::term::*; -use std::fmt; - -impl TTerm for BlankNode { - #[inline] - fn kind(&self) -> TermKind { - TermKind::BlankNode - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - self.as_str().into() - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - self - } -} - -impl TryCopyTerm for BlankNode { - type Error = SophiaToOxigraphConversionError; - - #[inline] - fn try_copy(other: &T) -> Result - where - T: TTerm + ?Sized, - { - match other.kind() { - TermKind::BlankNode => Ok(Self::new_unchecked(other.value_raw().0)), - _ => Err(SophiaToOxigraphConversionError), - } - } -} - -impl<'a> TTerm for BlankNodeRef<'a> { - #[inline] - fn kind(&self) -> TermKind { - TermKind::BlankNode - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - self.as_str().into() - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - self - } -} - -impl TTerm for Literal { - #[inline] - fn kind(&self) -> TermKind { - TermKind::Literal - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - Self::value(self).into() - } - - #[inline] - fn datatype(&self) -> Option> { - Some(SimpleIri::new_unchecked( - Self::datatype(self).as_str(), - None, - )) - } - - #[inline] - fn language(&self) -> Option<&str> { - Self::language(self) - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - self - } -} - -impl TryCopyTerm for Literal { - type Error = SophiaToOxigraphConversionError; - - #[inline] - fn try_copy(other: &T) -> Result - where - T: TTerm + ?Sized, - { - match other.kind() { - TermKind::Literal => match other.language() { - Some(tag) => Ok(Self::new_language_tagged_literal_unchecked( - other.value_raw().0, - tag, - )), - None => Ok(Self::new_typed_literal( - other.value_raw().0, - other.datatype().unwrap(), - )), - }, - _ => Err(SophiaToOxigraphConversionError), - } - } -} - -impl<'a> TTerm for LiteralRef<'a> { - #[inline] - fn kind(&self) -> TermKind { - TermKind::Literal - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - LiteralRef::value(*self).into() - } - - #[inline] - fn datatype(&self) -> Option> { - Some(SimpleIri::new_unchecked( - LiteralRef::datatype(*self).as_str(), - None, - )) - } - - #[inline] - fn language(&self) -> Option<&str> { - LiteralRef::language(*self) - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - self - } -} - -impl TTerm for NamedNode { - #[inline] - fn kind(&self) -> TermKind { - TermKind::Iri - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - self.as_str().into() - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - self - } -} - -impl TryCopyTerm for NamedNode { - type Error = SophiaToOxigraphConversionError; - - #[inline] - fn try_copy(other: &T) -> Result - where - T: TTerm + ?Sized, - { - match other.kind() { - TermKind::Iri => Ok(Self::new_unchecked(other.value())), - _ => Err(SophiaToOxigraphConversionError), - } - } -} - -impl<'a> From> for NamedNode { - #[inline] - fn from(other: SimpleIri<'a>) -> Self { - Self::new_unchecked(other.value()) - } -} - -impl<'a> TTerm for NamedNodeRef<'a> { - #[inline] - fn kind(&self) -> TermKind { - TermKind::BlankNode - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - self.as_str().into() - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - self - } -} - -impl From for Option { - #[inline] - fn from(other: GraphName) -> Self { - match other { - GraphName::NamedNode(n) => Some(n.into()), - GraphName::BlankNode(n) => Some(n.into()), - GraphName::DefaultGraph => None, - } - } -} - -impl<'a> From> for Option> { - #[inline] - fn from(other: GraphNameRef<'a>) -> Self { - match other { - GraphNameRef::NamedNode(n) => Some(n.into()), - GraphNameRef::BlankNode(n) => Some(n.into()), - GraphNameRef::DefaultGraph => None, - } - } -} - -impl TTerm for Subject { - #[inline] - fn kind(&self) -> TermKind { - match self { - Self::NamedNode(_) => TermKind::Iri, - Self::BlankNode(_) => TermKind::BlankNode, - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - match self { - Self::NamedNode(n) => n.value_raw(), - Self::BlankNode(n) => n.value_raw(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - match self { - Self::NamedNode(n) => n.as_dyn(), - Self::BlankNode(n) => n.as_dyn(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } -} - -impl TryCopyTerm for Subject { - type Error = SophiaToOxigraphConversionError; - - #[inline] - fn try_copy(other: &T) -> Result - where - T: TTerm + ?Sized, - { - match other.kind() { - TermKind::Iri => Ok(NamedNode::try_copy(other).unwrap().into()), - TermKind::BlankNode => Ok(BlankNode::try_copy(other).unwrap().into()), - _ => Err(SophiaToOxigraphConversionError), - } - } -} - -impl<'a> TTerm for SubjectRef<'a> { - #[inline] - fn kind(&self) -> TermKind { - match self { - Self::NamedNode(_) => TermKind::Iri, - Self::BlankNode(_) => TermKind::BlankNode, - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - match self { - Self::NamedNode(n) => n.value_raw(), - Self::BlankNode(n) => n.value_raw(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - match self { - Self::NamedNode(n) => n.as_dyn(), - Self::BlankNode(n) => n.as_dyn(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } -} - -impl TTerm for Term { - #[inline] - fn kind(&self) -> TermKind { - match self { - Self::NamedNode(_) => TermKind::Iri, - Self::BlankNode(_) => TermKind::BlankNode, - Self::Literal(_) => TermKind::Literal, - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - match self { - Self::NamedNode(n) => n.value_raw(), - Self::BlankNode(n) => n.value_raw(), - Self::Literal(l) => l.value_raw(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn datatype(&self) -> Option> { - if let Self::Literal(l) = self { - TTerm::datatype(l) - } else { - None - } - } - - #[inline] - fn language(&self) -> Option<&str> { - if let Self::Literal(l) = self { - TTerm::language(l) - } else { - None - } - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - match self { - Self::NamedNode(n) => n.as_dyn(), - Self::BlankNode(n) => n.as_dyn(), - Self::Literal(l) => l.as_dyn(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } -} - -impl TryCopyTerm for Term { - type Error = SophiaToOxigraphConversionError; - - #[inline] - fn try_copy(other: &T) -> Result - where - T: TTerm + ?Sized, - { - match other.kind() { - TermKind::Iri => Ok(NamedNode::try_copy(other).unwrap().into()), - TermKind::BlankNode => Ok(BlankNode::try_copy(other).unwrap().into()), - TermKind::Literal => Ok(Literal::try_copy(other).unwrap().into()), - TermKind::Variable => Err(SophiaToOxigraphConversionError), - } - } -} - -impl<'a> TTerm for TermRef<'a> { - #[inline] - fn kind(&self) -> TermKind { - match self { - Self::NamedNode(_) => TermKind::Iri, - Self::BlankNode(_) => TermKind::BlankNode, - Self::Literal(_) => TermKind::Literal, - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn datatype(&self) -> Option> { - if let Self::Literal(l) = self { - TTerm::datatype(l) - } else { - None - } - } - - #[inline] - fn language(&self) -> Option<&str> { - if let Self::Literal(l) = self { - TTerm::language(l) - } else { - None - } - } - - #[inline] - fn value_raw(&self) -> RawValue<'_> { - match self { - Self::NamedNode(n) => n.value_raw(), - Self::BlankNode(n) => n.value_raw(), - Self::Literal(l) => l.value_raw(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } - - #[inline] - fn as_dyn(&self) -> &dyn TTerm { - match self { - Self::NamedNode(n) => n.as_dyn(), - Self::BlankNode(n) => n.as_dyn(), - Self::Literal(l) => l.as_dyn(), - Self::Triple(_) => panic!("RDF-star is not supported yet by Sophia"), - } - } -} - -impl From for ([Term; 3], Option) { - #[inline] - fn from(other: Quad) -> Self { - ( - [other.subject.into(), other.predicate.into(), other.object], - other.graph_name.into(), - ) - } -} - -impl<'a> From> for ([TermRef<'a>; 3], Option>) { - #[inline] - fn from(other: QuadRef<'a>) -> Self { - ( - [other.subject.into(), other.predicate.into(), other.object], - other.graph_name.into(), - ) - } -} - -impl From for [Term; 3] { - #[inline] - fn from(other: Triple) -> Self { - [other.subject.into(), other.predicate.into(), other.object] - } -} - -impl<'a> From> for [TermRef<'a>; 3] { - #[inline] - fn from(other: TripleRef<'a>) -> Self { - [other.subject.into(), other.predicate.into(), other.object] - } -} - -/// Error raised when trying to copy a [Sophia](sophia) -/// term as an incompatible Oxigraph term -/// (e.g. a literal into `NamedNode`). -#[derive(Clone, Copy, Debug)] -pub struct SophiaToOxigraphConversionError; - -impl fmt::Display for SophiaToOxigraphConversionError { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl std::error::Error for SophiaToOxigraphConversionError {} diff --git a/lib/src/lib.rs b/lib/src/lib.rs index b7dca824..df493c06 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -138,8 +138,6 @@ pub mod io; pub mod model; -#[cfg(feature = "sophia")] -mod sophia; pub mod sparql; mod storage; pub mod store; diff --git a/lib/src/sophia.rs b/lib/src/sophia.rs deleted file mode 100644 index 1259c480..00000000 --- a/lib/src/sophia.rs +++ /dev/null @@ -1,569 +0,0 @@ -//! This crate provides implementation of [Sophia](https://docs.rs/sophia/) traits for the `store` module. - -use crate::model::{ - BlankNodeRef, GraphName, GraphNameRef, LiteralRef, NamedNodeRef, Quad, QuadRef, Subject, - SubjectRef, Term, TermRef, -}; -use crate::store::{StorageError, Store}; -use sophia_api::dataset::{ - CollectibleDataset, DQuadSource, DResultTermSet, DTerm, Dataset, MdResult, MutableDataset, -}; -use sophia_api::quad::stream::{QuadSource, StreamResult}; -use sophia_api::quad::streaming_mode::{ByValue, StreamedQuad}; -use sophia_api::term::{TTerm, TermKind}; -use std::collections::HashSet; -use std::hash::Hash; -use std::iter::empty; - -type SophiaQuad = ([Term; 3], Option); -type StreamedSophiaQuad<'a> = StreamedQuad<'a, ByValue>; - -impl Dataset for Store { - type Quad = ByValue; - type Error = StorageError; - - fn quads(&self) -> DQuadSource<'_, Self> { - Box::new(self.iter().map(quad_map)) - } - - fn quads_with_s<'s, TS>(&'s self, s: &'s TS) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - if s.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, None, None, None).map(quad_map)) - } - } - fn quads_with_p<'s, TP>(&'s self, p: &'s TP) -> DQuadSource<'s, Self> - where - TP: TTerm + ?Sized, - { - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - if p.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, p, None, None).map(quad_map)) - } - } - fn quads_with_o<'s, TS>(&'s self, o: &'s TS) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - { - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - if o.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, None, o, None).map(quad_map)) - } - } - fn quads_with_g<'s, TS>(&'s self, g: Option<&'s TS>) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - { - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, None, None, g).map(quad_map)) - } - } - fn quads_with_sp<'s, TS, TP>(&'s self, s: &'s TS, p: &'s TP) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - if s.is_none() || p.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, p, None, None).map(quad_map)) - } - } - fn quads_with_so<'s, TS, TO>(&'s self, s: &'s TS, o: &'s TO) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TO: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - if s.is_none() || o.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, None, o, None).map(quad_map)) - } - } - fn quads_with_sg<'s, TS, TG>(&'s self, s: &'s TS, g: Option<&'s TG>) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if s.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, None, None, g).map(quad_map)) - } - } - fn quads_with_po<'s, TP, TO>(&'s self, p: &'s TP, o: &'s TO) -> DQuadSource<'s, Self> - where - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - { - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - if p.is_none() || o.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, p, o, None).map(quad_map)) - } - } - fn quads_with_pg<'s, TP, TG>(&'s self, p: &'s TP, g: Option<&'s TG>) -> DQuadSource<'s, Self> - where - TP: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if p.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, p, None, g).map(quad_map)) - } - } - fn quads_with_og<'s, TO, TG>(&'s self, o: &'s TO, g: Option<&'s TG>) -> DQuadSource<'s, Self> - where - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if o.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, None, o, g).map(quad_map)) - } - } - fn quads_with_spo<'s, TS, TP, TO>( - &'s self, - s: &'s TS, - p: &'s TP, - o: &'s TO, - ) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - if s.is_none() || p.is_none() || o.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, p, o, None).map(quad_map)) - } - } - fn quads_with_spg<'s, TS, TP, TG>( - &'s self, - s: &'s TS, - p: &'s TP, - g: Option<&'s TG>, - ) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if s.is_none() || p.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, p, None, g).map(quad_map)) - } - } - fn quads_with_sog<'s, TS, TO, TG>( - &'s self, - s: &'s TS, - o: &'s TO, - g: Option<&'s TG>, - ) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if s.is_none() || o.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, None, o, g).map(quad_map)) - } - } - fn quads_with_pog<'s, TP, TO, TG>( - &'s self, - p: &'s TP, - o: &'s TO, - g: Option<&'s TG>, - ) -> DQuadSource<'s, Self> - where - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if p.is_none() || o.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(None, p, o, g).map(quad_map)) - } - } - fn quads_with_spog<'s, TS, TP, TO, TG>( - &'s self, - s: &'s TS, - p: &'s TP, - o: &'s TO, - g: Option<&'s TG>, - ) -> DQuadSource<'s, Self> - where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let s = convert_subject(s, &mut buf_s); - let mut buf_p = String::new(); - let p = convert_predicate(p, &mut buf_p); - let mut buf_o = String::new(); - let o = convert_object(o, &mut buf_o); - let mut buf_g = String::new(); - let g = convert_graph_name(g, &mut buf_g); - if s.is_none() || p.is_none() || o.is_none() || g.is_none() { - Box::new(empty()) - } else { - Box::new(self.quads_for_pattern(s, p, o, g).map(quad_map)) - } - } - fn subjects(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - self.iter() - .map(|r| r.map(|q| q.subject.into())) - .collect::>() - } - fn predicates(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - self.iter() - .map(|r| r.map(|q| q.predicate.into())) - .collect::>() - } - fn objects(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - self.iter() - .map(|r| r.map(|q| q.object)) - .collect::>() - } - fn graph_names(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - self.named_graphs() - .map(|r| r.map(|g| g.into())) - .collect::>() - } - fn iris(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - let mut iris = HashSet::new(); - for q in self.iter() { - let q = q?; - if let Subject::NamedNode(s) = q.subject { - iris.insert(s.into()); - } - iris.insert(q.predicate.into()); - if let Term::NamedNode(o) = q.object { - iris.insert(o.into()); - } - if let GraphName::NamedNode(g) = q.graph_name { - iris.insert(g.into()); - } - } - Ok(iris) - } - fn bnodes(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - let mut bnodes = HashSet::new(); - for q in self.iter() { - let q = q?; - if let Subject::BlankNode(s) = q.subject { - bnodes.insert(s.into()); - } - if let Term::BlankNode(o) = q.object { - bnodes.insert(o.into()); - } - if let GraphName::BlankNode(g) = q.graph_name { - bnodes.insert(g.into()); - } - } - Ok(bnodes) - } - fn literals(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - let mut literals = HashSet::new(); - for q in self.iter() { - let q = q?; - if let Term::Literal(o) = q.object { - literals.insert(o.into()); - } - } - Ok(literals) - } - fn variables(&self) -> DResultTermSet - where - DTerm: Clone + Eq + Hash, - { - Ok(std::collections::HashSet::new()) - } -} - -impl MutableDataset for Store { - type MutationError = StorageError; - fn insert( - &mut self, - s: &TS, - p: &TP, - o: &TO, - g: Option<&TG>, - ) -> MdResult - where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let mut buf_p = String::new(); - let mut buf_o = String::new(); - let mut buf_g = String::new(); - let quadref = - match convert_quadref(s, p, o, g, &mut buf_s, &mut buf_p, &mut buf_o, &mut buf_g) { - Some(quad) => quad, - None => return Ok(false), - }; - Self::insert(self, quadref).map(|_| true) - } - - fn remove( - &mut self, - s: &TS, - p: &TP, - o: &TO, - g: Option<&TG>, - ) -> MdResult - where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, - { - let mut buf_s = String::new(); - let mut buf_p = String::new(); - let mut buf_o = String::new(); - let mut buf_g = String::new(); - let quadref = - match convert_quadref(s, p, o, g, &mut buf_s, &mut buf_p, &mut buf_o, &mut buf_g) { - Some(quad) => quad, - None => return Ok(false), - }; - Self::remove(self, quadref).map(|_| true) - } -} - -impl CollectibleDataset for Store { - fn from_quad_source(quads: QS) -> StreamResult { - let mut d = Self::new().map_err(sophia_api::quad::stream::StreamError::SinkError)?; - d.insert_all(quads)?; - Ok(d) - } -} - -// helper functions -fn quad_map<'a>(res: Result) -> Result, StorageError> { - res.map(|q| { - let q: SophiaQuad = q.into(); - StreamedQuad::by_value(q) - }) -} - -fn convert_subject<'a, T>(term: &'a T, buffer: &'a mut String) -> Option> -where - T: TTerm + ?Sized + 'a, -{ - match term.kind() { - TermKind::Iri => Some(convert_iri(term, buffer).into()), - TermKind::BlankNode => Some(BlankNodeRef::new_unchecked(term.value_raw().0).into()), - _ => None, - } -} - -fn convert_predicate<'a, T>(term: &'a T, buffer: &'a mut String) -> Option> -where - T: TTerm + ?Sized + 'a, -{ - match term.kind() { - TermKind::Iri => Some(convert_iri(term, buffer)), - _ => None, - } -} - -fn convert_object<'a, T>(term: &'a T, buffer: &'a mut String) -> Option> -where - T: TTerm + ?Sized + 'a, -{ - match term.kind() { - TermKind::Iri => Some(convert_iri(term, buffer).into()), - TermKind::BlankNode => Some(BlankNodeRef::new_unchecked(term.value_raw().0).into()), - TermKind::Literal => { - let value = term.value_raw().0; - let lit = match term.language() { - Some(tag) => LiteralRef::new_language_tagged_literal_unchecked(value, tag), - None => { - let (ns, suffix) = term.datatype().unwrap().destruct(); - let datatype = convert_iri_raw(ns, suffix, buffer); - LiteralRef::new_typed_literal(value, datatype) - } - }; - Some(lit.into()) - } - TermKind::Variable => None, - } -} - -fn convert_graph_name<'a, T>( - graph_name: Option<&'a T>, - buffer: &'a mut String, -) -> Option> -where - T: TTerm + ?Sized + 'a, -{ - match graph_name { - None => Some(GraphNameRef::DefaultGraph), - Some(term) => match term.kind() { - TermKind::Iri => Some(convert_iri(term, buffer).into()), - TermKind::BlankNode => Some(BlankNodeRef::new_unchecked(term.value_raw().0).into()), - _ => None, - }, - } -} - -fn convert_iri<'a, T>(term: &'a T, buffer: &'a mut String) -> NamedNodeRef<'a> -where - T: TTerm + ?Sized + 'a, -{ - debug_assert_eq!(term.kind(), TermKind::Iri); - let raw = term.value_raw(); - convert_iri_raw(raw.0, raw.1, buffer) -} - -fn convert_iri_raw<'a>( - ns: &'a str, - suffix: Option<&'a str>, - buffer: &'a mut String, -) -> NamedNodeRef<'a> { - NamedNodeRef::new_unchecked(match suffix { - Some(suffix) => { - buffer.clear(); - buffer.push_str(ns); - buffer.push_str(suffix); - buffer - } - None => ns, - }) -} - -fn convert_quadref<'a, TS, TP, TO, TG>( - s: &'a TS, - p: &'a TP, - o: &'a TO, - g: Option<&'a TG>, - buf_s: &'a mut String, - buf_p: &'a mut String, - buf_o: &'a mut String, - buf_g: &'a mut String, -) -> Option> -where - TS: TTerm + ?Sized, - TP: TTerm + ?Sized, - TO: TTerm + ?Sized, - TG: TTerm + ?Sized, -{ - let s = match convert_subject(s, buf_s) { - Some(s) => s, - None => return None, - }; - let p = match convert_predicate(p, buf_p) { - Some(p) => p, - None => return None, - }; - let o = match convert_object(o, buf_o) { - Some(o) => o, - None => return None, - }; - let g = match convert_graph_name(g, buf_g) { - Some(g) => g, - None => return None, - }; - Some(QuadRef::new(s, p, o, g)) -} - -#[cfg(test)] -sophia_api::test_dataset_impl!(test, Store, false, false);