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"
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"

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

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

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

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

@ -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 model;
#[cfg(feature = "sophia")]
mod sophia;
pub mod sparql;
mod storage;
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