Skip to content

Commit

Permalink
rfe11202: SPARQL Update example with batch update
Browse files Browse the repository at this point in the history
<release-note>
rfe11202: SPARQL Update example with batch update

With this change, Java tutorial example 13 has been augmented
to show how to evaluate SPARQL Update queries, including one
that batches updates in a single request.
</release-note>

Added SparqlUpdateTests to prepush tests
make prepush passes
ant tutorial runs

Change-Id: I1e67e02231c676eb6bb03143c575b1895cb2775c

added tutorial prose

Change-Id: I78f197767899230d83c6179c5d60745d63d55b4a
Reviewed-on: https://gerrit.franz.com:9080/1823
Reviewed-by: Ahmon Dancy <dancy@franz.com>
Reviewed-by: John O'Rourke <jor@franz.com>
Tested-by: Kevin Layer <layer@franz.com>
  • Loading branch information
Bill Millar authored and dklayer committed Dec 6, 2011
1 parent 188efd9 commit 495608c
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 5 deletions.
44 changes: 44 additions & 0 deletions src/test/SparqlUpdateTests.java
@@ -0,0 +1,44 @@
/******************************************************************************
** Copyright (c) 2008-2011 Franz Inc.
** All rights reserved. This program and the accompanying materials
** are made available under the terms of the Eclipse Public License v1.0
** which accompanies this distribution, and is available at
** http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/

package test;

import junit.framework.Assert;

import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.query.QueryLanguage;

public class SparqlUpdateTests extends AGAbstractTest {

@Test
@Category(TestSuites.Prepush.class)
public void batchSparqlUpdates() throws Exception {
URI s = vf.createURI("http://example/book1");
URI p = vf.createURI("http://purl.org/dc/elements/1.1/title");
Literal o_wrong = vf.createLiteral("Fundamentals of Compiler Desing");
Literal o_right = vf.createLiteral("Fundamentals of Compiler Design");
URI g = vf.createURI("http://example/bookStore");
conn.add(s,p,o_wrong,g);

// Perform a sequence of SPARQL UPDATE queries in one request to correct the title
String queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "DELETE DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Desing\" } } ; \n"
+ "\n"
+ "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "INSERT DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Design\" } }";

// SPARQL Update queries can be executed using a BooleanQuery (for side effect)
conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate();
Assert.assertTrue("Title should be correct", conn.hasStatement(s,p,o_right,false,g));
Assert.assertFalse("Incorrect title should be gone", conn.hasStatement(s,p,o_wrong,false,g));
}

}
3 changes: 2 additions & 1 deletion src/test/TestSuites.java
Expand Up @@ -78,7 +78,8 @@ public static class Temp {}
DynamicCatalogTests.class,
SpinTest.class,
FreetextTests.class,
DeleteDuplicatesTests.class
DeleteDuplicatesTests.class,
SparqlUpdateTests.class
})
public static class Prepush {}

Expand Down
31 changes: 29 additions & 2 deletions src/tutorial/TutorialExamples.java
Expand Up @@ -57,7 +57,7 @@
public class TutorialExamples {

public static String SERVER_URL = "http://localhost:10035";
public static String CATALOG_ID = "java-catalog";
public static String CATALOG_ID = "java-tutorial";
public static String REPOSITORY_ID = "javatutorial";
public static String USERNAME = "test";
public static String PASSWORD = "xyzzy";
Expand Down Expand Up @@ -1506,7 +1506,7 @@ public static void example12 () throws Exception {


/**
* Ask, Construct, and Describe queries
* Ask, Construct, Describe, and Update queries
*/
public static void example13 () throws Exception {
AGRepositoryConnection conn = example6();
Expand Down Expand Up @@ -1567,6 +1567,33 @@ public static void example13 () throws Exception {
println(gresult.next());
}
gresult.close();

// SPARQL UPDATE queries
queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "INSERT DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Desing\" } }";
println("\nPerforming SPARQL UPDATE query:\n" + queryString);
conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate();
queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "ASK { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Desing\" } }";
println("\nPerforming query:\n" + queryString);
println("Result: " + conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate());

queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "DELETE DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Desing\" } } ; \n"
+ "\n"
+ "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "INSERT DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Design\" } }";

println("\nPerforming a sequence of SPARQL UPDATE queries in one request (to correct the title):\n" + queryString);
conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate();
queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "ASK { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Desing\" } }";
println("\nPerforming query:\n" + queryString);
println("Result: " + conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate());
queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "ASK { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Design\" } }";
println("\nPerforming query:\n" + queryString);
println("Result: " + conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate());
}


Expand Down
17 changes: 15 additions & 2 deletions src/tutorial/java-tutorial-40.html
Expand Up @@ -40,7 +40,7 @@ <h2 id="Contents">Contents</h2>
</ul></td>
<td width="295"><ul>
<li><a href="#Free Text Search">Free Text Search</a></li>
<li><a href="#Ask, Describe, and Construct Queries">Select, Ask, Describe, and Construct Queries</a></li>
<li><a href="#Ask, Describe, Construct and Update Queries">Ask, Describe, Construct, and Update Queries</a></li>
<li><a href="#Parametric Queries">Parametric Queries</a></li>
<li><a href="#Range Matches">Range Matches</a></li>
<li><a href="#Federated Repositories">Federated Repositories</a></li>
Expand Down Expand Up @@ -1177,14 +1177,15 @@ <h2 id="Free Text Search">Free Text Search (example12()) &nbsp;&nbsp;&nbsp;<a cl
<p>This query returns two triples, but they are not quite the same as before:</p>
<pre class="output">Substring match for 'lic'.<br>[s=http://example.org/people/alice1;p=http://example.org/people/fullname;o=&quot;Alice B. Toklas&quot;]<br>[s=http://example.org/people/book1;p=http://example.org/people/title;o=&quot;Alice in Wonderland&quot;]</pre>
<p>As you can see, the regex match found &quot;lic&quot; in &quot;Alice in Wonderland,&quot; which was not a registered free-text predicate. It made this match by doing a string comparison against every object value in the triple store. Even though you can streamline the SPARQL query considerably by writing more restrictive patterns, this is still inherently less efficient than using the indexed approach. </p>
<h2 id="Ask, Describe, and Construct Queries">Select, Ask, Describe, and Construct Queries (example13())&nbsp;&nbsp;&nbsp;<a class="returnlink" href="#Contents">Return to Top</a></h2>
<h2 id="Ask, Describe, Construct and Update Queries">Ask, Describe, Construct, and Update Queries (example13())&nbsp;&nbsp;&nbsp;<a class="returnlink" href="#Contents">Return to Top</a></h2>
<p>SPARQL provides alternatives to the standard SELECT query. Example example13() exercises these alternatives to show how AllegroGraph Server handles them. </p>

<ul>
<li> SELECT: Returns variables bound in a query pattern match. </li>
<li>ASK: Returns a boolean indicating whether a query matches or not. </li>
<li>CONSTRUCT: Returns triples constructed by substituting variables in a set of triple templates. </li>
<li>DESCRIBE: Returns all of the triples of a matching resource. </li>
<li>Update: Evaluates <a href="http://www.w3.org/TR/sparql11-update/">SPARQL Update</a> queries to modify the repository. </li>
</ul>
<p>The example begins by borrowing a connection object from example6(). This connects to a repository that contains vcard and Kennedy data. We'll need to register a Kennedy namespace to make the queries easier to read.
<pre class="input"> public static void example13 () throws Exception {<br> RepositoryConnection conn = example6();<br> conn.setNamespace(&quot;kdy&quot;, &quot;http://www.franz.com/simple#&quot;);</pre>
Expand Down Expand Up @@ -1216,6 +1217,18 @@ <h2 id="Ask, Describe, and Construct Queries">Select, Ask, Describe, and Constru
<p>The output of this loop is lengthy, because the Kennedy resources have many triples. One block of triples looked like this, showing the new has-grandchild triples: </p>
<pre class="output">(http://www.franz.com/simple#person1, http://www.franz.com/simple#has-grandchild, http://www.franz.com/simple#person20)<br>(http://www.franz.com/simple#person1, http://www.franz.com/simple#has-grandchild, http://www.franz.com/simple#person22)<br>(http://www.franz.com/simple#person1, http://www.franz.com/simple#has-grandchild, http://www.franz.com/simple#person24)<br>(http://www.franz.com/simple#person1, http://www.franz.com/simple#has-grandchild, http://www.franz.com/simple#person25)<br>(http://www.franz.com/simple#person1, http://www.franz.com/simple#has-grandchild, http://www.franz.com/simple#person26)<br>
</pre>
<p><a href="http://www.w3.org/TR/sparql11-update/">SPARQL Update</a> queries can also be evaluated to modify the repository. A SPARQL Update query can be evaluated (for side effect) using a BooleanQuery as follows:</p>
<pre class="input">
queryString = "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "DELETE DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Desing\" } } ; \n"
+ "\n"
+ "PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"
+ "INSERT DATA { GRAPH <http://example/bookStore> { <http://example/book1> dc:title \"Fundamentals of Compiler Design\" } }";

println("\nPerforming a sequence of SPARQL UPDATE queries in one request (to correct the title):\n" + queryString);
conn.prepareBooleanQuery(QueryLanguage.SPARQL, queryString).evaluate();
</pre>

<h2 id="Parametric Queries">Parametric Queries (example14())&nbsp;&nbsp;&nbsp;<a class="returnlink" href="#Contents">Return to Top</a></h2>
<p>The Java Sesame API to AllegroGraph Server lets you set up a <strong>parameteric</strong> query and then set the values of some query parameters prior to evaluation; this approach is stylistically cleaner and can be more efficient than building up custom query strings for each of the different bindings. There's also a potential performance benefit to parsing/compiling a query only once during query preparation, rather than during each query evaluation; while parsing/compilation overhead is often neglible, we recommend adopting the style in this example in order to make the most of any future improvements in query preparation.</p>
<p>In <strong>example14()</strong> we set up resources for Alice and Bob, and then prepare a parametric SPARQL query to retrieve the triples. Evaluating this query would normally find all four triples, but by binding the subject value ahead of time, we can retrieve the &quot;Alice&quot; triples separately from the &quot;Bob&quot; triples.</p>
Expand Down

0 comments on commit 495608c

Please sign in to comment.