diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e99cb3..959492e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## unreleased ### Added -- Oxigraph native parsers for N-Triples, Turtle and RDF/XML. +- Oxigraph native parsers for N-Triples, Turtle, RDF/XML and N-Quads. ### Improved - Restructured a code based to account for further additions to the codebase. diff --git a/oxrdflib/_converter.py b/oxrdflib/_converter.py index bc957c2..7dcac3a 100644 --- a/oxrdflib/_converter.py +++ b/oxrdflib/_converter.py @@ -122,6 +122,8 @@ def rdflib_to_mime_type(rdflib_type: str) -> str: return "application/rdf+xml" if rdflib_type == "trig": return "application/trig" + if rdflib_type == "nquads": + return "application/n-quads" if rdflib_type == "trix": return "application/trix" raise ValueError(f"Unsupported rdflib type: {rdflib_type}") @@ -129,10 +131,13 @@ def rdflib_to_mime_type(rdflib_type: str) -> str: def ox_to_rdflib_type(ox_format: str) -> str: """Convert an Oxigraph format to a rdflib parser format.""" + print(ox_format) if ox_format in ("ox-turtle", "ox-ttl"): return "turtle" if ox_format in ("ox-nt", "ox-ntriples"): return "nt" if ox_format == "ox-xml": return "xml" + if ox_format in ("ox-nquads", "ox-nq"): + return "nquads" raise ValueError(f"Unsupported Oxigraph type: {ox_format}") diff --git a/oxrdflib/parser.py b/oxrdflib/parser.py index d839da9..c1764e8 100644 --- a/oxrdflib/parser.py +++ b/oxrdflib/parser.py @@ -1,7 +1,7 @@ import warnings from typing import Any, Optional -from rdflib import ConjunctiveGraph, Graph +from rdflib import Graph from rdflib.exceptions import ParserError from rdflib.parser import ( FileInputSource, @@ -47,6 +47,7 @@ def parse( else: base_iri = sink.absolutize(source.getPublicId() or source.getSystemId() or "") + graph_identifier = to_ox(sink.identifier) if format not in ("ox-nq", "ox-nquads") else None if isinstance(source, FileInputSource): input = source.file @@ -60,14 +61,14 @@ def parse( input, rdflib_to_mime_type(ox_to_rdflib_type(format)), base_iri=base_iri, - to_graph=to_ox(sink.identifier), + to_graph=graph_identifier, ) else: sink.store._inner.bulk_load( input, rdflib_to_mime_type(ox_to_rdflib_type(format)), base_iri=base_iri, - to_graph=to_ox(sink.identifier), + to_graph=graph_identifier, ) @@ -111,12 +112,12 @@ class OxigraphNQuadsParser(OxigraphParser): def parse( self, source: InputSource, - sink: ConjunctiveGraph, - format: str, + sink: Graph, + format: str = "ox-nquads", encoding: Optional[str] = None, **kwargs: Any, ) -> None: - raise NotImplementedError("N-Quads is not supported yet") + super().parse(source, sink, format, encoding, **kwargs) class OxigraphTriGParser(OxigraphParser): diff --git a/pyproject.toml b/pyproject.toml index 96eb452..a6cf9a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,8 @@ ox-ttl = "oxrdflib.parser:OxigraphTurtleParser" ox-ntriples = "oxrdflib.parser:OxigraphNTriplesParser" ox-nt = "oxrdflib.parser:OxigraphNTriplesParser" ox-xml = "oxrdflib.parser:OxigraphRdfXmlParser" +ox-nquads = "oxrdflib.parser:OxigraphNQuadsParser" +ox-nq = "oxrdflib.parser:OxigraphNQuadsParser" [project.urls] diff --git a/tests/data/test.nq b/tests/data/test.nq new file mode 100644 index 0000000..6d53a3f --- /dev/null +++ b/tests/data/test.nq @@ -0,0 +1,6 @@ + . + "Example Document" . + . + . + "John Doe" . + . diff --git a/tests/test_parser.py b/tests/test_parser.py index e7c18c6..c637d85 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -6,6 +6,12 @@ _TEST_DIR = Path(__file__).resolve().parent +_NAMEDGRAPH_QUERY = """SELECT DISTINCT ?g WHERE { + GRAPH ?g { + ?s ?p ?o . + } +}""" + class TestGraphParsing(unittest.TestCase): def test_parsing_ox_turtle_bulk_load(self): @@ -127,6 +133,18 @@ def test_parsing_ox_rdfxml_fallback(self): ) self.assertEqual(len(graph), 6) + def test_parsing_ox_nquads_bulk_load(self): + graph = rdflib.Dataset(store="Oxigraph") + graph.parse(_TEST_DIR / "data/test.nq", format="ox-nquads", transactional=False) + self.assertEqual(len(graph), 6) + self.assertEqual(len(graph.query(_NAMEDGRAPH_QUERY)), 1) + + def test_parsing_ox_nquads_load(self): + graph = rdflib.Dataset(store="Oxigraph") + graph.parse(_TEST_DIR / "data/test.nq", format="ox-nquads", transactional=True) + self.assertEqual(len(graph), 6) + self.assertEqual(len(graph.query(_NAMEDGRAPH_QUERY)), 1) + if __name__ == "__main__": unittest.main()