From 535e5e30536b5ff9837de746936cff0ee13873c8 Mon Sep 17 00:00:00 2001 From: Tpt Date: Sat, 15 Aug 2020 22:51:01 +0200 Subject: [PATCH] Adds .update() and .dump() to JavaScript bindings --- js/README.md | 28 ++++++++++++++++++++++++++++ js/src/store.rs | 36 ++++++++++++++++++++++++++++++++++++ js/test/store.js | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/js/README.md b/js/README.md index d679c948..641982a2 100644 --- a/js/README.md +++ b/js/README.md @@ -135,6 +135,14 @@ if (store.query("ASK { ?s ?s ?s }")) { } ``` +#### `MemoryStore.prototype.update(String query)` +Executes a [SPARQL 1.1 Update](https://www.w3.org/TR/sparql11-update/). + +Example of update: +```js +store.update("DELETE WHERE { ?p ?o }") +``` + ### `MemoryStore.prototype.load(String data, String mimeType, NamedNode|String? baseIRI, NamedNode|BlankNode|DefaultGraph? toNamedGraph)` Loads serialized RDF triples or quad into the store. @@ -157,6 +165,26 @@ store.load(" <> .", "text/turtle", "htt ``` +### `MemoryStore.prototype.dump(String mimeType, NamedNode|BlankNode|DefaultGraph? fromNamedGraph)` + +Returns serialized RDF triples or quad from the store. +The method arguments are: +1. `mimeType`: the MIME type of the serialization. See below for the supported mime types. +2. `fromNamedGraph`: for triple serialization formats, the name of the named graph the triple should be loaded from. + +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 building a Turtle file from the named graph ``: +```js +store.dump("text/turtle", store.dataFactory.namedNode("http://example.com/graph")); +``` + + ## How to contribute The Oxigraph bindings are written in Rust using [the Rust WASM toolkit](https://rustwasm.github.io/docs.html). diff --git a/js/src/store.rs b/js/src/store.rs index 3b50772f..0fdf4728 100644 --- a/js/src/store.rs +++ b/js/src/store.rs @@ -137,6 +137,10 @@ impl JsMemoryStore { Ok(output) } + pub fn update(&self, update: &str) -> Result<(), JsValue> { + self.store.update(update).map_err(to_err) + } + pub fn load( &self, data: &str, @@ -185,4 +189,36 @@ impl JsMemoryStore { Err(format_err!("Not supported MIME type: {}", mime_type)) } } + + pub fn dump(&self, mime_type: &str, from_graph_name: &JsValue) -> Result { + let from_graph_name = + if let Some(graph_name) = self.from_js.to_optional_term(from_graph_name)? { + Some(graph_name.try_into()?) + } else { + None + }; + + let mut buffer = Vec::new(); + if let Some(graph_format) = GraphFormat::from_media_type(mime_type) { + self.store + .dump_graph( + &mut buffer, + graph_format, + &from_graph_name.unwrap_or(GraphName::DefaultGraph), + ) + .map_err(to_err)?; + } else if let Some(dataset_format) = DatasetFormat::from_media_type(mime_type) { + if from_graph_name.is_some() { + return Err(format_err!( + "The target graph name parameter is not available for dataset formats" + )); + } + self.store + .dump_dataset(&mut buffer, dataset_format) + .map_err(to_err)?; + } else { + return Err(format_err!("Not supported MIME type: {}", mime_type)); + } + String::from_utf8(buffer).map_err(to_err) + } } diff --git a/js/test/store.js b/js/test/store.js index 80a1ccae..aca406a7 100644 --- a/js/test/store.js +++ b/js/test/store.js @@ -79,6 +79,26 @@ describe('MemoryStore', function () { }) }) + describe('#update()', function () { + it('INSERT DATA', function () { + const store = new MemoryStore() + store.update('INSERT DATA { }') + assert.strictEqual(1, store.size) + }) + + it('DELETE DATA', function () { + const store = new MemoryStore([dataFactory.triple(ex, ex, ex)]) + store.update('DELETE DATA { }') + assert.strictEqual(0, store.size) + }) + + it('DELETE WHERE', function () { + const store = new MemoryStore([dataFactory.triple(ex, ex, ex)]) + store.update('DELETE WHERE { ?v ?v ?v }') + assert.strictEqual(0, store.size) + }) + }) + describe('#load()', function () { it('load NTriples in the default graph', function () { const store = new MemoryStore() @@ -110,4 +130,21 @@ describe('MemoryStore', function () { assert(store.has(dataFactory.quad(ex, ex, ex, ex))) }) }) + + describe('#dump()', function () { + it('dump dataset content', function () { + const store = new MemoryStore([dataFactory.quad(ex, ex, ex, ex)]) + assert.strictEqual(' .\n', store.dump('application/n-quads')) + }) + + it('dump named graph content', function () { + const store = new MemoryStore([dataFactory.quad(ex, ex, ex, ex)]) + assert.strictEqual(' .\n', store.dump('application/n-triples', ex)) + }) + + it('dump default graph content', function () { + const store = new MemoryStore([dataFactory.quad(ex, ex, ex, ex)]) + assert.strictEqual('', store.dump('application/n-triples')) + }) + }) })