Removes Sophia traits implementation

Sophia is planning to depend on Oxigraph, this will make stuff simpler
pull/190/head
Tpt 3 years ago
parent fe58a84bfa
commit 9870ce4881
  1. 60
      Cargo.lock
  2. 3
      lib/Cargo.toml
  3. 2
      lib/README.md
  4. 1
      lib/oxrdf/Cargo.toml
  5. 2
      lib/oxrdf/src/lib.rs
  6. 456
      lib/oxrdf/src/sophia.rs
  7. 2
      lib/src/lib.rs
  8. 569
      lib/src/sophia.rs

60
Cargo.lock generated

@ -676,12 +676,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "mownstr"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76aacdf8f9850a9db34e33e35abfc17a29b9577d0eb2cbfaeb734662cacca5b3"
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.0" version = "7.1.0"
@ -789,7 +783,6 @@ dependencies = [
"sha-1", "sha-1",
"sha2", "sha2",
"siphasher", "siphasher",
"sophia_api",
"sparesults", "sparesults",
"spargebra", "spargebra",
"wasm-bindgen-test", "wasm-bindgen-test",
@ -852,7 +845,6 @@ dependencies = [
"oxilangtag", "oxilangtag",
"oxiri", "oxiri",
"rand", "rand",
"sophia_api",
] ]
[[package]] [[package]]
@ -1191,12 +1183,6 @@ version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "resiter"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd69ab1e90258b7769f0b5c46bfd802b8206d0707ced4ca4b9d5681b744de1be"
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.16.20" version = "0.16.20"
@ -1443,32 +1429,6 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 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]] [[package]]
name = "sparesults" name = "sparesults"
version = "0.1.0-beta.4" version = "0.1.0-beta.4"
@ -1562,26 +1522,6 @@ version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" 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]] [[package]]
name = "time" name = "time"
version = "0.3.7" version = "0.3.7"

@ -18,7 +18,6 @@ all-features = true
[features] [features]
default = [] default = []
sophia = ["sophia_api", "oxrdf/sophia_api"]
http_client = ["oxhttp", "oxhttp/rustls"] http_client = ["oxhttp", "oxhttp/rustls"]
[dependencies] [dependencies]
@ -37,7 +36,6 @@ hex = "0.4"
nom = "7" nom = "7"
siphasher = "0.3" siphasher = "0.3"
lazy_static = "1" lazy_static = "1"
sophia_api = { version = "0.7", optional = true }
num_cpus = "1" num_cpus = "1"
oxrdf = { version = "0.1.0-beta.4", path="oxrdf", features = ["rdf-star"] } oxrdf = { version = "0.1.0-beta.4", path="oxrdf", features = ["rdf-star"] }
spargebra = { version = "0.2.0-beta.4", path="spargebra", 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] [dev-dependencies]
criterion = "0.3" criterion = "0.3"
oxhttp = "0.1" oxhttp = "0.1"
sophia_api = { version = "0.7", features = ["test_macro"] }
zstd = "0.10" zstd = "0.10"
[target.'cfg(target_arch = "wasm32")'.dev-dependencies] [target.'cfg(target_arch = "wasm32")'.dev-dependencies]

@ -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. 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. 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.

@ -21,7 +21,6 @@ rand = "0.8"
oxilangtag = "0.1" oxilangtag = "0.1"
oxiri = "0.2" oxiri = "0.2"
lasso = { version = "0.6", features = ["inline-more"] } lasso = { version = "0.6", features = ["inline-more"] }
sophia_api = { version = "0.7", optional = true }
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

@ -20,8 +20,6 @@ mod interning;
mod literal; mod literal;
mod named_node; mod named_node;
mod parser; mod parser;
#[cfg(feature = "sophia_api")]
mod sophia;
mod triple; mod triple;
mod variable; mod variable;
pub mod vocab; pub mod vocab;

@ -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<T>(other: &T) -> Result<Self, Self::Error>
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<SimpleIri<'_>> {
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<T>(other: &T) -> Result<Self, Self::Error>
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<SimpleIri<'_>> {
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<T>(other: &T) -> Result<Self, Self::Error>
where
T: TTerm + ?Sized,
{
match other.kind() {
TermKind::Iri => Ok(Self::new_unchecked(other.value())),
_ => Err(SophiaToOxigraphConversionError),
}
}
}
impl<'a> From<SimpleIri<'a>> 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<GraphName> for Option<Term> {
#[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<GraphNameRef<'a>> for Option<TermRef<'a>> {
#[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<T>(other: &T) -> Result<Self, Self::Error>
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<SimpleIri<'_>> {
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<T>(other: &T) -> Result<Self, Self::Error>
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<SimpleIri<'_>> {
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<Quad> for ([Term; 3], Option<Term>) {
#[inline]
fn from(other: Quad) -> Self {
(
[other.subject.into(), other.predicate.into(), other.object],
other.graph_name.into(),
)
}
}
impl<'a> From<QuadRef<'a>> for ([TermRef<'a>; 3], Option<TermRef<'a>>) {
#[inline]
fn from(other: QuadRef<'a>) -> Self {
(
[other.subject.into(), other.predicate.into(), other.object],
other.graph_name.into(),
)
}
}
impl From<Triple> for [Term; 3] {
#[inline]
fn from(other: Triple) -> Self {
[other.subject.into(), other.predicate.into(), other.object]
}
}
impl<'a> From<TripleRef<'a>> 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 {}

@ -138,8 +138,6 @@
pub mod io; pub mod io;
pub mod model; pub mod model;
#[cfg(feature = "sophia")]
mod sophia;
pub mod sparql; pub mod sparql;
mod storage; mod storage;
pub mod store; pub mod store;

@ -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<Term>);
type StreamedSophiaQuad<'a> = StreamedQuad<'a, ByValue<SophiaQuad>>;
impl Dataset for Store {
type Quad = ByValue<SophiaQuad>;
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<Self>
where
DTerm<Self>: Clone + Eq + Hash,
{
self.iter()
.map(|r| r.map(|q| q.subject.into()))
.collect::<Result<_, _>>()
}
fn predicates(&self) -> DResultTermSet<Self>
where
DTerm<Self>: Clone + Eq + Hash,
{
self.iter()
.map(|r| r.map(|q| q.predicate.into()))
.collect::<Result<_, _>>()
}
fn objects(&self) -> DResultTermSet<Self>
where
DTerm<Self>: Clone + Eq + Hash,
{
self.iter()
.map(|r| r.map(|q| q.object))
.collect::<Result<_, _>>()
}
fn graph_names(&self) -> DResultTermSet<Self>
where
DTerm<Self>: Clone + Eq + Hash,
{
self.named_graphs()
.map(|r| r.map(|g| g.into()))
.collect::<Result<_, _>>()
}
fn iris(&self) -> DResultTermSet<Self>
where
DTerm<Self>: 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<Self>
where
DTerm<Self>: 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<Self>
where
DTerm<Self>: 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<Self>
where
DTerm<Self>: Clone + Eq + Hash,
{
Ok(std::collections::HashSet::new())
}
}
impl MutableDataset for Store {
type MutationError = StorageError;
fn insert<TS, TP, TO, TG>(
&mut self,
s: &TS,
p: &TP,
o: &TO,
g: Option<&TG>,
) -> MdResult<Self, bool>
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<TS, TP, TO, TG>(
&mut self,
s: &TS,
p: &TP,
o: &TO,
g: Option<&TG>,
) -> MdResult<Self, bool>
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<QS: QuadSource>(quads: QS) -> StreamResult<Self, QS::Error, Self::Error> {
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<Quad, StorageError>) -> Result<StreamedSophiaQuad<'a>, 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<SubjectRef<'a>>
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<NamedNodeRef<'a>>
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<TermRef<'a>>
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<GraphNameRef<'a>>
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<QuadRef<'a>>
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);
Loading…
Cancel
Save