JS: Allows to load serialized triples and quads into MemoryStore

pull/35/head
Tpt 4 years ago
parent 16451b7c53
commit a05476b191
  1. 23
      js/README.md
  2. 2
      js/src/model.rs
  3. 66
      js/src/store.rs
  4. 32
      js/test/store.js

@ -10,6 +10,9 @@ Oxigraph is a work in progress graph database written in Rust implementing the [
It is a work in progress and currently offers a simple in-memory store with [SPARQL 1.1 Query](https://www.w3.org/TR/sparql11-query/) capabilities.
The store is also able to load RDF serialized in [Turtle](https://www.w3.org/TR/turtle/), [TriG](https://www.w3.org/TR/trig/), [N-Triples](https://www.w3.org/TR/n-triples/), [N-Quads](https://www.w3.org/TR/n-quads/) and [RDF XML](https://www.w3.org/TR/rdf-syntax-grammar/).
It is distributed using a [a NPM package](https://www.npmjs.com/package/oxigraph) that should work with nodeJS.
```bash
@ -116,6 +119,26 @@ if (store.query("ASK { ?s ?s ?s }")) {
}
```
### `MemoryStore.prototype.load(String data, String mimeType, NamedNode|String? baseIRI, NamedNode|BlankNode|DefaultGraph? toNamedGraph)`
Loads serialized RDF triples or quad into the store.
The method arguments are:
1. `data`: the serialized RDF triples or quads.
2. `mimeType`: the MIME type of the serialization. See below for the supported mime types.
3. `baseIRI`: the base IRI to use to resolve the relative IRIs in the serialization.
4. `toNamedGraph`: for triple serialization formats, the name of the named graph the triple should be loaded to.
The available formats are:
* [Turtle](https://www.w3.org/TR/turtle/): `text/turtle`
* [TriG](https://www.w3.org/TR/trig/): `application/trig`
* [N-Triples](https://www.w3.org/TR/n-triples/): `application/n-triples`
* [N-Quads](https://www.w3.org/TR/n-quads/): `application/n-quads`
* [RDF XML](https://www.w3.org/TR/rdf-syntax-grammar/): `application/rdf+xml`
Example of loading a Turtle file into the named graph `<http://example.com/graph>` with the base IRI `http://example.com`:
```js
store.load("<http://example.com> <http://example.com> <> .", "text/turtle", "http://example.com", store.dataFactory.namedNode("http://example.com/graph"));
```
## Example

@ -101,7 +101,7 @@ impl JsDataFactory {
#[wasm_bindgen(js_name = fromQuad)]
pub fn convert_quad(&self, original: &JsValue) -> Result<JsQuad, JsValue> {
Ok(self.from_js.to_quad(original)?.into())
Ok(self.from_js.to_quad(original)?)
}
}

@ -2,9 +2,14 @@ use crate::format_err;
use crate::model::*;
use crate::utils::to_err;
use js_sys::{Array, Map};
use oxigraph::model::NamedOrBlankNode;
use oxigraph::sparql::{PreparedQuery, QueryOptions, QueryResult};
use oxigraph::{Error, MemoryRepository, Repository, RepositoryConnection};
use oxigraph::{
DatasetSyntax, Error, FileSyntax, GraphSyntax, MemoryRepository, Repository,
RepositoryConnection,
};
use std::convert::TryInto;
use std::io::Cursor;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(js_name = MemoryStore)]
@ -154,4 +159,63 @@ impl JsMemoryStore {
};
Ok(output)
}
pub fn load(
&self,
data: &str,
mime_type: &str,
base_iri: &JsValue,
to_graph_name: &JsValue,
) -> Result<(), JsValue> {
let base_iri = if base_iri.is_null() || base_iri.is_undefined() {
None
} else if base_iri.is_string() {
base_iri.as_string()
} else if let JsTerm::NamedNode(base_iri) = self.from_js.to_term(&base_iri)? {
Some(base_iri.value())
} else {
return Err(format_err!(
"If provided, the base IRI should be a NamedNode or a string"
));
};
let to_graph_name: Option<NamedOrBlankNode> =
match self.from_js.to_optional_term(to_graph_name)? {
Some(JsTerm::NamedNode(node)) => Some(node.into()),
Some(JsTerm::BlankNode(node)) => Some(node.into()),
Some(JsTerm::DefaultGraph(_)) => None,
Some(_) => {
return Err(format_err!(
"If provided, the target graph name should be a NamedNode or a BlankNode"
))
}
None => None,
};
if let Some(graph_syntax) = GraphSyntax::from_mime_type(mime_type) {
self.store
.connection()
.map_err(to_err)?
.load_graph(
Cursor::new(data),
graph_syntax,
to_graph_name.as_ref(),
base_iri.as_deref(),
)
.map_err(to_err)
} else if let Some(dataset_syntax) = DatasetSyntax::from_mime_type(mime_type) {
if to_graph_name.is_some() {
return Err(format_err!(
"The target graph name parameter is not available for dataset formats"
));
}
self.store
.connection()
.map_err(to_err)?
.load_dataset(Cursor::new(data), dataset_syntax, base_iri.as_deref())
.map_err(to_err)
} else {
Err(format_err!("Not supported MIME type: {}", mime_type))
}
}
}

@ -63,4 +63,36 @@ describe('MemoryStore', function() {
assert(ex.equals(results[0].get("s")));
});
});
describe('#load()', function() {
it('load NTriples in the default graph', function() {
const store = new MemoryStore();
store.load("<http://example.com> <http://example.com> <http://example.com> .", "application/n-triples");
assert(store.has(dataFactory.triple(ex, ex, ex)));
});
it('load NTriples in an other graph', function() {
const store = new MemoryStore();
store.load("<http://example.com> <http://example.com> <http://example.com> .", "application/n-triples", null, ex);
assert(store.has(dataFactory.quad(ex, ex, ex, ex)));
});
it('load Turtle with a base IRI', function() {
const store = new MemoryStore();
store.load("<http://example.com> <http://example.com> <> .", "text/turtle", "http://example.com");
assert(store.has(dataFactory.triple(ex, ex, ex)));
});
it('load NQuads', function() {
const store = new MemoryStore();
store.load("<http://example.com> <http://example.com> <http://example.com> <http://example.com> .", "application/n-quads");
assert(store.has(dataFactory.quad(ex, ex, ex, ex)));
});
it('load TriG with a base IRI', function() {
const store = new MemoryStore();
store.load("GRAPH <> { <http://example.com> <http://example.com> <> }", "application/trig", "http://example.com");
assert(store.has(dataFactory.quad(ex, ex, ex, ex)));
});
});
});

Loading…
Cancel
Save