"1" .'), "text/turtle", base_iri="http://example.com/", to_graph=NamedNode("http://example.com/g"))
- /// >>> list(store)
- /// [ predicate= object=> graph_name=>]
- #[text_signature = "($self, input, /, mime_type, *, base_iri = None, to_graph = None)"]
- #[args(input, mime_type, "*", base_iri = "None", to_graph = "None")]
- fn load(
- &self,
- input: PyObject,
- mime_type: &str,
- base_iri: Option<&str>,
- to_graph: Option<&PyAny>,
- ) -> PyResult<()> {
- let to_graph_name = if let Some(graph_name) = to_graph {
- Some(PyGraphNameRef::try_from(graph_name)?)
- } else {
- None
- };
- let input = BufReader::new(PyFileLike::new(input));
- if let Some(graph_format) = GraphFormat::from_media_type(mime_type) {
- self.inner
- .load_graph(
- input,
- graph_format,
- &to_graph_name.unwrap_or(PyGraphNameRef::DefaultGraph),
- base_iri,
- )
- .map_err(map_io_err)
- } else if let Some(dataset_format) = DatasetFormat::from_media_type(mime_type) {
- if to_graph_name.is_some() {
- return Err(PyValueError::new_err(
- "The target graph name parameter is not available for dataset formats",
- ));
- }
- self.inner
- .load_dataset(input, dataset_format, base_iri)
- .map_err(map_io_err)
- } else {
- Err(PyValueError::new_err(format!(
- "Not supported MIME type: {}",
- mime_type
- )))
- }
- }
-
- /// Dumps the store quads or triples into a file
- ///
- /// It currently supports the following formats:
- ///
- /// * `N-Triples `_ (``application/n-triples``)
- /// * `N-Quads `_ (``application/n-quads``)
- /// * `Turtle `_ (``text/turtle``)
- /// * `TriG `_ (``application/trig``)
- /// * `RDF/XML `_ (``application/rdf+xml``)
- ///
- /// It supports also some MIME type aliases.
- /// For example ``application/turtle`` could also be used for `Turtle `_
- /// and ``application/xml`` for `RDF/XML `_.
- ///
- /// :param output: The binary I/O object to write to. For example, it could be a file opened in binary mode with ``open('my_file.ttl', 'wb')``.
- /// :type input: io.RawIOBase or io.BufferedIOBase
- /// :param mime_type: the MIME type of the RDF serialization
- /// :type mime_type: str
- /// :param from_graph: if a triple based format is requested, the store graph from which dump the triples. By default, the default graph is used.
- /// :type from_graph: NamedNode or BlankNode or DefaultGraph or None, optional
- /// :raises ValueError: if the MIME type is not supported or the `from_graph` parameter is given with a quad syntax.
- ///
- /// >>> store = MemoryStore()
- /// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
- /// >>> output = io.BytesIO()
- /// >>> store.dump(output, "text/turtle", from_graph=NamedNode("http://example.com/g"))
- /// >>> output.getvalue()
- /// b' "1" .\n'
- #[text_signature = "($self, output, /, mime_type, *, from_graph = None)"]
- #[args(output, mime_type, "*", from_graph = "None")]
- fn dump(&self, output: PyObject, mime_type: &str, from_graph: Option<&PyAny>) -> PyResult<()> {
- let from_graph_name = if let Some(graph_name) = from_graph {
- Some(PyGraphNameRef::try_from(graph_name)?)
- } else {
- None
- };
- let output = PyFileLike::new(output);
- if let Some(graph_format) = GraphFormat::from_media_type(mime_type) {
- self.inner
- .dump_graph(
- output,
- graph_format,
- &from_graph_name.unwrap_or(PyGraphNameRef::DefaultGraph),
- )
- .map_err(map_io_err)
- } else if let Some(dataset_format) = DatasetFormat::from_media_type(mime_type) {
- if from_graph_name.is_some() {
- return Err(PyValueError::new_err(
- "The target graph name parameter is not available for dataset formats",
- ));
- }
- self.inner
- .dump_dataset(output, dataset_format)
- .map_err(map_io_err)
- } else {
- Err(PyValueError::new_err(format!(
- "Not supported MIME type: {}",
- mime_type
- )))
- }
- }
-
- /// Returns an iterator over all the store named graphs
- ///
- /// :return: an iterator of the store graph names
- /// :rtype: iter(NamedNode or BlankNode)
- ///
- /// >>> store = MemoryStore()
- /// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
- /// >>> list(store.named_graphs())
- /// []
- #[text_signature = "($self)"]
- fn named_graphs(&self) -> GraphNameIter {
- GraphNameIter {
- inner: self.inner.named_graphs(),
- }
- }
-
- /// Adds a named graph to the store
- ///
- /// :param graph_name: the name of the name graph to add
- /// :type graph_name: NamedNode or BlankNode
- ///
- /// >>> store = MemoryStore()
- /// >>> store.add_graph(NamedNode('http://example.com/g'))
- /// >>> list(store.named_graphs())
- /// []
- #[text_signature = "($self, graph_name)"]
- fn add_graph(&self, graph_name: PyGraphName) {
- match graph_name {
- PyGraphName::DefaultGraph(_) => (),
- PyGraphName::NamedNode(graph_name) => self.inner.insert_named_graph(graph_name),
- PyGraphName::BlankNode(graph_name) => self.inner.insert_named_graph(graph_name),
- }
- }
-
- /// Removes a graph from the store
- ///
- /// The default graph will not be remove but just cleared.
- ///
- /// :param graph_name: the name of the name graph to remove
- /// :type graph_name: NamedNode or BlankNode or DefaultGraph
- ///
- /// >>> store = MemoryStore()
- /// >>> quad = Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))
- /// >>> store.remove_graph(NamedNode('http://example.com/g'))
- /// >>> list(store)
- /// []
- #[text_signature = "($self, graph_name)"]
- fn remove_graph(&self, graph_name: &PyAny) -> PyResult<()> {
- match PyGraphNameRef::try_from(graph_name)? {
- PyGraphNameRef::DefaultGraph => self.inner.clear_graph(GraphNameRef::DefaultGraph),
- PyGraphNameRef::NamedNode(graph_name) => self
- .inner
- .remove_named_graph(&PyNamedOrBlankNodeRef::NamedNode(graph_name)),
- PyGraphNameRef::BlankNode(graph_name) => self
- .inner
- .remove_named_graph(&PyNamedOrBlankNodeRef::BlankNode(graph_name)),
- }
- Ok(())
- }
-}
-
-#[pyproto]
-impl PyObjectProtocol for PyMemoryStore {
- fn __str__(&self) -> String {
- self.inner.to_string()
- }
-
- fn __richcmp__(&self, other: &PyCell, op: CompareOp) -> PyResult {
- let other: &PyMemoryStore = &other.borrow();
- match op {
- CompareOp::Eq => Ok(self == other),
- CompareOp::Ne => Ok(self != other),
- _ => Err(PyNotImplementedError::new_err(
- "Ordering is not implemented",
- )),
- }
- }
-
- fn __bool__(&self) -> bool {
- !self.inner.is_empty()
- }
-}
-
-#[pyproto]
-impl<'p> PySequenceProtocol<'p> for PyMemoryStore {
- fn __len__(&self) -> usize {
- self.inner.len()
- }
-
- fn __contains__(&self, quad: PyQuad) -> bool {
- self.inner.contains(&quad)
- }
-}
-
-#[pyproto]
-impl PyIterProtocol for PyMemoryStore {
- fn __iter__(slf: PyRef) -> QuadIter {
- QuadIter {
- inner: slf.inner.iter(),
- }
- }
-}
-
-#[pyclass(unsendable, module = "oxigraph")]
-pub struct QuadIter {
- inner: MemoryQuadIter,
-}
-
-#[pyproto]
-impl PyIterProtocol for QuadIter {
- fn __iter__(slf: PyRefMut) -> Py {
- slf.into()
- }
-
- fn __next__(mut slf: PyRefMut) -> Option {
- slf.inner.next().map(|q| q.into())
- }
-}
-
-#[pyclass(unsendable, module = "oxigraph")]
-pub struct GraphNameIter {
- inner: MemoryGraphNameIter,
-}
-
-#[pyproto]
-impl PyIterProtocol for GraphNameIter {
- fn __iter__(slf: PyRefMut) -> Py {
- slf.into()
- }
-
- fn __next__(mut slf: PyRefMut) -> Option {
- slf.inner.next().map(|q| q.into())
- }
-}
diff --git a/python/src/sparql.rs b/python/src/sparql.rs
index f3dafd1a..b79fb756 100644
--- a/python/src/sparql.rs
+++ b/python/src/sparql.rs
@@ -1,5 +1,5 @@
+use crate::io::map_io_err;
use crate::model::*;
-use crate::store_utils::*;
use oxigraph::model::Term;
use oxigraph::sparql::*;
use pyo3::exceptions::{PyRuntimeError, PySyntaxError, PyTypeError, PyValueError};
@@ -73,7 +73,7 @@ pub fn query_results_to_python(py: Python<'_>, results: QueryResults) -> PyResul
/// It could be indexes by variable name (:py:class:`Variable` or :py:class:`str`) or position in the tuple (:py:class:`int`).
/// Unpacking also works.
///
-/// >>> store = SledStore()
+/// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> solution = next(store.query('SELECT ?s ?p ?o WHERE { ?s ?p ?o }'))
/// >>> solution[Variable('s')]
@@ -164,7 +164,7 @@ impl PyIterProtocol for SolutionValueIter {
/// An iterator of :py:class:`QuerySolution` returned by a SPARQL ``SELECT`` query
///
-/// >>> store = SledStore()
+/// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> list(store.query('SELECT ?s WHERE { ?s ?p ?o }'))
/// [>]
@@ -178,7 +178,7 @@ impl PyQuerySolutions {
/// :return: the ordered list of all variables that could appear in the query results
/// :rtype: list(Variable)
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.query('SELECT ?s WHERE { ?s ?p ?o }').variables
/// []
#[getter]
@@ -209,7 +209,7 @@ impl PyIterProtocol for PyQuerySolutions {
/// An iterator of :py:class:`Triple` returned by a SPARQL ``CONSTRUCT`` or ``DESCRIBE`` query
///
-/// >>> store = MemoryStore()
+/// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> list(store.query('CONSTRUCT WHERE { ?s ?p ?o }'))
/// [ predicate= object=>>]
diff --git a/python/src/sled_store.rs b/python/src/store.rs
similarity index 91%
rename from python/src/sled_store.rs
rename to python/src/store.rs
index 9c24b406..0adc2cdc 100644
--- a/python/src/sled_store.rs
+++ b/python/src/store.rs
@@ -1,7 +1,6 @@
-use crate::io::PyFileLike;
+use crate::io::{map_io_err, PyFileLike};
use crate::model::*;
use crate::sparql::*;
-use crate::store_utils::*;
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::GraphNameRef;
use oxigraph::store::sled::*;
@@ -10,35 +9,33 @@ use pyo3::prelude::{
pyclass, pymethods, pyproto, Py, PyAny, PyObject, PyRef, PyRefMut, PyResult, Python,
};
use pyo3::{PyIterProtocol, PyObjectProtocol, PySequenceProtocol};
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
use std::io::BufReader;
-/// Store based on the `Sled `_ key-value database.
+/// Disk-based RDF store.
///
-/// In-memory store.
/// It encodes a `RDF dataset `_ and allows to query it using SPARQL.
+/// It is based on the `Sled `_ key-value database
///
-/// :param path: the path of the directory in which Sled should read and write its data. If the directory does not exist, it is created. If no directory is provided a temporary one is created and removed when the Python garbage collector removes the store.
+/// :param path: the path of the directory in which the store should read and write its data. If the directory does not exist, it is created. If no directory is provided a temporary one is created and removed when the Python garbage collector removes the store.
/// :type path: str or None, optional
/// :raises IOError: if the target directory contains invalid data or could not be accessed
///
-/// Warning: Sled is not stable yet and might break its storage format.
-///
/// The :py:func:`str` function provides a serialization of the store in NQuads:
///
-/// >>> store = SledStore()
+/// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
/// >>> str(store)
/// ' "1" .\n'
-#[pyclass(name = "SledStore", module = "oxigraph")]
+#[pyclass(name = "Store", module = "oxigraph")]
#[text_signature = "(path = None)"]
#[derive(Clone)]
-pub struct PySledStore {
+pub struct PyStore {
inner: SledStore,
}
#[pymethods]
-impl PySledStore {
+impl PyStore {
#[new]
fn new(path: Option<&str>) -> PyResult {
Ok(Self {
@@ -57,7 +54,7 @@ impl PySledStore {
/// :type quad: Quad
/// :raises IOError: if an I/O error happens during the quad insertion
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
/// >>> list(store)
/// [ predicate= object=> graph_name=>]
@@ -72,7 +69,7 @@ impl PySledStore {
/// :type quad: Quad
/// :raises IOError: if an I/O error happens during the quad removal
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> quad = Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))
/// >>> store.add(quad)
/// >>> store.remove(quad)
@@ -97,7 +94,7 @@ impl PySledStore {
/// :rtype: iter(Quad)
/// :raises IOError: if an I/O error happens during the quads lookup
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
/// >>> list(store.quads_for_pattern(NamedNode('http://example.com'), None, None, None))
/// [ predicate= object=> graph_name=>]
@@ -138,21 +135,21 @@ impl PySledStore {
///
/// ``SELECT`` query:
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> list(solution['s'] for solution in store.query('SELECT ?s WHERE { ?s ?p ?o }'))
/// []
///
/// ``CONSTRUCT`` query:
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> list(store.query('CONSTRUCT WHERE { ?s ?p ?o }'))
/// [ predicate= object=>>]
///
/// ``ASK`` query:
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> store.query('ASK { ?s ?p ?o }')
/// True
@@ -194,14 +191,14 @@ impl PySledStore {
///
/// ``INSERT DATA`` update:
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> store.update('INSERT DATA { "1" }')
/// >>> list(store)
/// [ predicate= object=> graph_name=>]
///
/// ``DELETE DATA`` update:
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> store.update('DELETE DATA { "1" }')
/// >>> list(store)
@@ -209,7 +206,7 @@ impl PySledStore {
///
/// ``DELETE`` update:
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1')))
/// >>> store.update('DELETE WHERE { ?p ?o }')
/// >>> list(store)
@@ -245,7 +242,7 @@ impl PySledStore {
/// :raises SyntaxError: if the provided data is invalid
/// :raises IOError: if an I/O error happens during a quad insertion
///
- /// >>> store = SledStore()
+ /// >>> store = Store()
/// >>> store.load(io.BytesIO(b' "1" .'), "text/turtle", base_iri="http://example.com/", to_graph=NamedNode("http://example.com/g"))
/// >>> list(store)
/// [ predicate= object=> graph_name=>]
@@ -313,7 +310,7 @@ impl PySledStore {
/// :raises ValueError: if the MIME type is not supported or the `from_graph` parameter is given with a quad syntax.
/// :raises IOError: if an I/O error happens during a quad lookup
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
/// >>> output = io.BytesIO()
/// >>> store.dump(output, "text/turtle", from_graph=NamedNode("http://example.com/g"))
@@ -359,7 +356,7 @@ impl PySledStore {
/// :rtype: iter(NamedNode or BlankNode)
/// :raises IOError: if an I/O error happens during the named graphs lookup
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
/// >>> list(store.named_graphs())
/// []
@@ -376,7 +373,7 @@ impl PySledStore {
/// :type graph_name: NamedNode or BlankNode
/// :raises IOError: if an I/O error happens during the named graph insertion
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> store.add_graph(NamedNode('http://example.com/g'))
/// >>> list(store.named_graphs())
/// []
@@ -402,7 +399,7 @@ impl PySledStore {
/// :type graph_name: NamedNode or BlankNode or DefaultGraph
/// :raises IOError: if an I/O error happens during the named graph removal
///
- /// >>> store = MemoryStore()
+ /// >>> store = Store()
/// >>> quad = Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))
/// >>> store.remove_graph(NamedNode('http://example.com/g'))
/// >>> list(store)
@@ -423,7 +420,7 @@ impl PySledStore {
}
#[pyproto]
-impl PyObjectProtocol for PySledStore {
+impl PyObjectProtocol for PyStore {
fn __str__(&self) -> String {
self.inner.to_string()
}
@@ -434,7 +431,7 @@ impl PyObjectProtocol for PySledStore {
}
#[pyproto]
-impl PySequenceProtocol for PySledStore {
+impl PySequenceProtocol for PyStore {
fn __len__(&self) -> usize {
self.inner.len()
}
@@ -445,7 +442,7 @@ impl PySequenceProtocol for PySledStore {
}
#[pyproto]
-impl PyIterProtocol for PySledStore {
+impl PyIterProtocol for PyStore {
fn __iter__(slf: PyRef) -> QuadIter {
QuadIter {
inner: slf.inner.iter(),
@@ -490,3 +487,42 @@ impl PyIterProtocol for GraphNameIter {
.transpose()
}
}
+
+pub fn extract_quads_pattern<'a>(
+ subject: &'a PyAny,
+ predicate: &'a PyAny,
+ object: &'a PyAny,
+ graph_name: Option<&'a PyAny>,
+) -> PyResult<(
+ Option>,
+ Option>,
+ Option>,
+ Option>,
+)> {
+ Ok((
+ if subject.is_none() {
+ None
+ } else {
+ Some(subject.try_into()?)
+ },
+ if predicate.is_none() {
+ None
+ } else {
+ Some(predicate.try_into()?)
+ },
+ if object.is_none() {
+ None
+ } else {
+ Some(object.try_into()?)
+ },
+ if let Some(graph_name) = graph_name {
+ if graph_name.is_none() {
+ None
+ } else {
+ Some(graph_name.try_into()?)
+ }
+ } else {
+ None
+ },
+ ))
+}
diff --git a/python/src/store_utils.rs b/python/src/store_utils.rs
deleted file mode 100644
index 22b8e9ac..00000000
--- a/python/src/store_utils.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use crate::model::*;
-use pyo3::exceptions::{PyIOError, PySyntaxError, PyValueError};
-use pyo3::{PyAny, PyErr, PyResult};
-use std::convert::TryInto;
-use std::io;
-
-pub fn extract_quads_pattern<'a>(
- subject: &'a PyAny,
- predicate: &'a PyAny,
- object: &'a PyAny,
- graph_name: Option<&'a PyAny>,
-) -> PyResult<(
- Option>,
- Option>,
- Option>,
- Option>,
-)> {
- Ok((
- if subject.is_none() {
- None
- } else {
- Some(subject.try_into()?)
- },
- if predicate.is_none() {
- None
- } else {
- Some(predicate.try_into()?)
- },
- if object.is_none() {
- None
- } else {
- Some(object.try_into()?)
- },
- if let Some(graph_name) = graph_name {
- if graph_name.is_none() {
- None
- } else {
- Some(graph_name.try_into()?)
- }
- } else {
- None
- },
- ))
-}
-
-pub fn map_io_err(error: io::Error) -> PyErr {
- match error.kind() {
- io::ErrorKind::InvalidInput => PyValueError::new_err(error.to_string()),
- io::ErrorKind::InvalidData | io::ErrorKind::UnexpectedEof => {
- PySyntaxError::new_err(error.to_string())
- }
- _ => PyIOError::new_err(error.to_string()),
- }
-}
diff --git a/python/tests/test_store.py b/python/tests/test_store.py
index e2d8af33..ecbf4e56 100644
--- a/python/tests/test_store.py
+++ b/python/tests/test_store.py
@@ -1,5 +1,4 @@
import unittest
-from abc import ABC, abstractmethod
from io import BytesIO
from pyoxigraph import *
@@ -10,20 +9,16 @@ baz = NamedNode("http://baz")
graph = NamedNode("http://graph")
-class TestAbstractStore(unittest.TestCase, ABC):
- @abstractmethod
- def store(self):
- pass
-
+class TestStore(unittest.TestCase):
def test_add(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz))
store.add(Quad(foo, bar, baz, DefaultGraph()))
store.add(Quad(foo, bar, baz, graph))
self.assertEqual(len(store), 2)
def test_remove(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz))
store.add(Quad(foo, bar, baz, DefaultGraph()))
store.add(Quad(foo, bar, baz, graph))
@@ -31,13 +26,13 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(len(store), 1)
def test_len(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz))
store.add(Quad(foo, bar, baz, graph))
self.assertEqual(len(store), 2)
def test_in(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz))
store.add(Quad(foo, bar, baz, DefaultGraph()))
store.add(Quad(foo, bar, baz, graph))
@@ -47,7 +42,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertNotIn(Quad(foo, bar, baz, foo), store)
def test_iter(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz, DefaultGraph()))
store.add(Quad(foo, bar, baz, graph))
self.assertEqual(
@@ -56,7 +51,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
)
def test_quads_for_pattern(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz, DefaultGraph()))
store.add(Quad(foo, bar, baz, graph))
self.assertEqual(
@@ -77,13 +72,13 @@ class TestAbstractStore(unittest.TestCase, ABC):
)
def test_ask_query(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, foo, foo))
self.assertTrue(store.query("ASK { ?s ?s ?s }"))
self.assertFalse(store.query("ASK { FILTER(false) }"))
def test_construct_query(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz))
results = store.query("CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }")
self.assertIsInstance(results, QueryTriples)
@@ -92,7 +87,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
)
def test_select_query(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz))
solutions = store.query("SELECT ?s ?o WHERE { ?s ?p ?o }")
self.assertIsInstance(solutions, QuerySolutions)
@@ -110,7 +105,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(o, baz)
def test_select_query_union_default_graph(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz, graph))
self.assertEqual(len(list(store.query("SELECT ?s WHERE { ?s ?p ?o }"))), 0)
results = store.query(
@@ -125,7 +120,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(len(list(results)), 1)
def test_select_query_with_default_graph(self):
- store = self.store()
+ store = Store()
graph_bnode = BlankNode("g")
store.add(Quad(foo, bar, baz, graph))
store.add(Quad(foo, bar, foo))
@@ -140,7 +135,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(len(list(results)), 3)
def test_select_query_with_named_graph(self):
- store = self.store()
+ store = Store()
graph_bnode = BlankNode("g")
store.add(Quad(foo, bar, baz, graph))
store.add(Quad(foo, bar, foo))
@@ -153,29 +148,29 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(len(list(results)), 2)
def test_update_insert_data(self):
- store = self.store()
+ store = Store()
store.update('INSERT DATA { }')
self.assertEqual(len(store), 1)
def test_update_delete_data(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, foo, foo))
store.update('DELETE DATA { }')
self.assertEqual(len(store), 0)
def test_update_delete_where(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, foo, foo))
store.update('DELETE WHERE { ?v ?v ?v }')
self.assertEqual(len(store), 0)
def test_update_load(self):
- store = self.store()
+ store = Store()
store.update('LOAD ')
self.assertGreater(len(store), 100)
def test_load_ntriples_to_default_graph(self):
- store = self.store()
+ store = Store()
store.load(
BytesIO(b" ."),
mime_type="application/n-triples",
@@ -183,7 +178,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(set(store), {Quad(foo, bar, baz, DefaultGraph())})
def test_load_ntriples_to_named_graph(self):
- store = self.store()
+ store = Store()
store.load(
BytesIO(b" ."),
mime_type="application/n-triples",
@@ -192,7 +187,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(set(store), {Quad(foo, bar, baz, graph)})
def test_load_turtle_with_base_iri(self):
- store = self.store()
+ store = Store()
store.load(
BytesIO(b" <> ."),
mime_type="text/turtle",
@@ -201,7 +196,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(set(store), {Quad(foo, bar, baz, DefaultGraph())})
def test_load_nquads(self):
- store = self.store()
+ store = Store()
store.load(
BytesIO(b" ."),
mime_type="application/n-quads",
@@ -209,7 +204,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(set(store), {Quad(foo, bar, baz, graph)})
def test_load_trig_with_base_iri(self):
- store = self.store()
+ store = Store()
store.load(
BytesIO(b" { <> . }"),
mime_type="application/trig",
@@ -218,7 +213,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(set(store), {Quad(foo, bar, baz, graph)})
def test_dump_ntriples(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz, graph))
output = BytesIO()
store.dump(output, "application/n-triples", from_graph=graph)
@@ -227,7 +222,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
)
def test_dump_nquads(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz, graph))
output = BytesIO()
store.dump(output, "application/n-quads")
@@ -237,7 +232,7 @@ class TestAbstractStore(unittest.TestCase, ABC):
)
def test_write_in_read(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, bar))
store.add(Quad(foo, bar, baz))
for triple in store:
@@ -245,12 +240,12 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(len(store), 4)
def test_add_graph(self):
- store = self.store()
+ store = Store()
store.add_graph(graph)
self.assertEqual(list(store.named_graphs()), [graph])
def test_remove_graph(self):
- store = self.store()
+ store = Store()
store.add(Quad(foo, bar, baz, graph))
store.add_graph(NamedNode("http://graph2"))
store.remove_graph(graph)
@@ -259,17 +254,5 @@ class TestAbstractStore(unittest.TestCase, ABC):
self.assertEqual(list(store), [])
-class TestMemoryStore(TestAbstractStore):
- def store(self):
- return MemoryStore()
-
-
-class TestSledStore(TestAbstractStore):
- def store(self):
- return SledStore()
-
-
-del TestAbstractStore # We do not want to expose this class to the test runner
-
if __name__ == "__main__":
unittest.main()