Book Home

Contents
Preface


Overview
Data Representation
RDF and SPARQL API and SQL
SPARUL -- an Update Language For RDF Graphs
RDF Insert Methods in Virtuoso
Virtuoso Sponger
Dereferencable IRIs and RDF Linked Data
RDF Views -- Mapping Relational Data to RDF
RDF Inference in Virtuoso
Using Full Text Search in SPARQL
Virtuoso SPARQL Query Service
Introduction Service Endpoint Service Endpoint with authenticated SPARUL option Request Methods Functions Request Parameters Response Codes Response Format Additional Response Formats -- SELECT Examples Implementation Notes Virtuoso Semantic Bank end point Making RDF View Dereferenceable -- Northwind example RDF proxy service SPARQL ini service SPARQL OAuth Endpoint SPARQL Endpoint with Excel mime-type output option SPARQL Endpoint with JSON+RDF
Business Intelligence Extensions for SPARQL
Debugging SPARQL queries
Virtuoso RDF Performance Tuning
RDF Store Benchmarks
SPARQL Implementation Details
Native RDF Storage Providers
SPARQL predicates usage

15.11. Virtuoso SPARQL Query Service

15.11.1. Introduction

The Virtuoso SPARQL query service implements the SPARQL Protocol for RDF (W3C Working Draft 25 January 2006) providing SPARQL query processing for RDF data available on the open internet.

The query processor extends the standard protocol to provide support for multiple output formats. At present this uses additional query parameters.

Supported features include


15.11.2. Service Endpoint

Virtuoso reserves the path '/sparql/' and a synonym path '/SPARQL/' for SPARQL service.

In the current implementation, Virtuoso defines virtual directories for HTTP requests that come to the port specified as 'ServerPort' in the '[HTTPServer]' section of Virtuoso configuration file and refer to one of these two path strings. So if the Virtuoso installation on host example.com listens for HTTP requests on port 8080 then client applications should use the 'service endpoint' string equal to 'http://example.com:8080/sparql/'.

Both GET and POST requests are supported by both server and client. The server recognizes the 'Accept: ...' line of request header to find MIME types preferred by the connected client and adjust the output mode of the response.

The client chooses between GET and POST automatically, using the length of query text as a criterion.

If the SPARQL endpoint is accessed without any URL and query entered, will be shown page with interactive query form.


15.11.3. Service Endpoint with authenticated SPARUL option

Virtuoso reserves the path '/sparql-auth/' for SPARQL service with authenticated SPARUL option.

This endpoint allows specific SQL accounts to perform SPARUL over the SPARQL protocol.

"SPARQL_UPDATE" is needed to be granted on a user to perform all operations on physical triples and the user to be able allowed to perform SQL/ODBC logins:

Note that if there is a table used in a RDF view, and this table is not granted to SPARQL_SELECT ( SPARQL_UPDATE inherits it ), then select on all graph will return access violation error as the user account has no permissions to read it. Thus the account need to have privileges on all tables included in any rdf view in order to be able to select on *all* graphs.


15.11.4. Request Methods

Table: 15.11.4.1. Methods List
Method Supported? Notes
GET Yes short queries are sent in GET mode
POST Yes Queries longer than 1900 bytes are POST-ed.
DELETE No
PUT No


15.11.5. Functions

The SPARQL client can be invoked by three similar functions:

Table: 15.11.5.1. Functions List
Function Notes
DB.DBA.SPARQL_REXEC behaves like DBA.SPARQL_EVAL, but executes the query on the specified server. The procedure does not return anything. Instead, it creates a result set.
DB.DBA.SPARQL_REXEC_TO_ARRAY behaves like DBA.SPARQL_EXEC_TO_ARRAY (), but executes the query on the specified server. The function return a vector of rows, where every row is represented by a vector of values of fields.
DB.DBA.SPARQL_REXEC_WITH_META has no local 'SPARQL_EVAL' analog. It produces not only an array of result rows but also array of metadata about result set in a format used by the exec () function. This function can be used when the result should be passed later to exec_result_names () and exec_result () built-in functions. To process local query in similar style, an application can use plain SQL built-in function exec (): an SPARQL query (with 'SPARQL' keyword in front) can be passed to exec () instead of text of plain SQL SELECT statement.

create procedure DB.DBA.SPARQL_REXEC (
    in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any,
    in req_hdr any, in maxrows integer, in bnode_dict any );
create function DB.DBA.SPARQL_REXEC_TO_ARRAY (
    in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any,
    in req_hdr any, in maxrows integer, in bnode_dict any )
    returns any;
create procedure DB.DBA.SPARQL_REXEC_WITH_META (
    in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any,
    in req_hdr any, in maxrows integer, in bnode_dict any,
    out metadata any,  -- metadata like exec () returns.
    out resultset any) -- results as 'long valmode' values.

15.11.6. Request Parameters

Table: 15.11.6.1. Request Parameters List
Parameter Notes Required? Occurrence
service service URI such as 'http://example.com/sparql/' Yes
query text of the query Yes
dflt_graph default graph URI (string or NULL) No
named_graphs vector of named graphs (or NULL to not override what's specified in the query Yes
req_hdr additional HTTP header lines that should be passed to the service; 'Host: ...' is most popular No
maxrows limit on numbers of rows that should be returned (actual size of result set may differ) No
bnode_dict dictionary of known blank node names, or NULL for usual loading No


15.11.7. Response Codes

If the query is a CONSTRUCT or DESCRIBE then the result set consists of a single row and a single column, the value inside is a dictionary of triples in 'long valmode'. Note that the dictionary object can not be sent to SQL client, say, via ODBC. The client can loose database connection trying to fetch a result set row that contain a dictionary object. This disconnect will be safe for server, so the client can re-connect to the server, but the disconnected transaction will be rolled back.


15.11.8. Response Format

All standard MIME types of SPARQL Protocol are supported:

Table: 15.11.8.1. Supported MIME Types list
Mimetype Supported for result of Query
'application/sparql-results+xml' SELECT
'application/sparql-results+xml' ASK
'application/rdf+xml' CONSTRUCT
'application/rdf+xml' DESCRIBE
'text/rdf+n3' CONSTRUCT
'text/rdf+n3' DESCRIBE

If the HTTP header returned by the remote server does not contain 'Content-Type' line, the MIME type may be guessed from the text of the returned body.

The current implementation does not support results of SELECT returned in RDF /XML, TURTLE or 'sparql-results-2'.

Error messages returned from the service are returned as XML documents, using the mime type application/xml. The documents consist of a single element containing an error message.


15.11.9. Additional Response Formats -- SELECT

Use the format parameter to select one of the following alternate output formats:

Table: 15.11.9.1. Additional Response formats list
Format Value Description Mimetype
HTML HTML document containing query summary and tabular results text/html
json JSON serialization of results. Conforms to the draft specification Serializing SPARQL Query Results in JSON application/sparql-results+json
js Javascript serialization of results. Generates an HTML table with the CSS class sparql. The table contains a column indicating row number and additional columns for each query variable. Each query solution contributes one row of the table. Unbound variables are indicated with a non-breaking space in the appropriate table cells. application/javascript
table text/html
XML text/html
TURTLE text/html


15.11.10. Examples

Virtuoso's SPARQL Implementation Demo offers a live demonstration of Virtuoso's implementation of DAWG's SPARQL test-suite; a collection of SPARQL query language use-cases that enable interactive and simplified testing of a Triple Store's implementation. Can be found at 'http://example.com:8080/sparql_demo/' depending on the local Virtuoso Server Configuration, or live at Virtuoso Demo Server.

Simple example with CONSTRUCT:

Go to the sparql endpoint UI: i.e. go to http://host:port/sparql

Enter for Default Graph URI: http://www.w3.org/2001/sw/DataAccess/proto-tests/data/construct/simple-data.rdf

Select "Retrieve remote RDF data for all missing source graphs".

Enter as Query:

SELECT * WHERE {?s ?p ?o}

Click the "Run Query" button.

As result will be shown the save in the graph http://www.w3.org/2001/sw/DataAccess/proto-tests/data/construct/simple-data.rdf retrieved triples

s  	                                  p  	                                           o
http://www.example/jose/foaf.rdf#jose 	  http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://xmlns.com/foaf/0.1/Person
http://www.example/jose/foaf.rdf#jose 	  http://xmlns.com/foaf/0.1/nick 	           Jo
http://www.example/jose/foaf.rdf#jose 	  http://xmlns.com/foaf/0.1/name 	           Jose Jimen~ez
http://www.example/jose/foaf.rdf#jose 	  http://xmlns.com/foaf/0.1/knows 	           http://www.example/jose/foaf.rdf#juan
http://www.example/jose/foaf.rdf#jose 	  http://xmlns.com/foaf/0.1/homepage 	           http://www.example/jose/
http://www.example/jose/foaf.rdf#jose 	  http://xmlns.com/foaf/0.1/workplaceHomepage 	   http://www.corp.example/
http://www.example/jose/foaf.rdf#kendall  http://xmlns.com/foaf/0.1/knows                  http://www.example/jose/foaf.rdf#edd
http://www.example/jose/foaf.rdf#julia 	  http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://xmlns.com/foaf/0.1/Person
http://www.example/jose/foaf.rdf#julia 	  http://xmlns.com/foaf/0.1/mbox 	           mailto:julia@mail.example
http://www.example/jose/foaf.rdf#juan 	  http://www.w3.org/1999/02/22-rdf-syntax-ns#type  http://xmlns.com/foaf/0.1/Person
http://www.example/jose/foaf.rdf#juan 	  http://xmlns.com/foaf/0.1/mbox 	           mailto:juan@mail.example

Now let's take the CONSTRUCT query:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX myfoaf: <http://www.example/jose/foaf.rdf#>
CONSTRUCT
  { myfoaf:jose foaf:depiction <http://www.example/jose/jose.jpg>.
    myfoaf:jose foaf:schoolHomepage <http://www.edu.example/>.
    ?s ?p ?o.
  }
FROM <http://www.w3.org/2001/sw/DataAccess/proto-tests/data/construct/simple-data.rdf>
WHERE
  {
    ?s ?p ?o. myfoaf:jose foaf:nick "Jo".
    FILTER ( ! (?s = myfoaf:kendall && ?p = foaf:knows && ?o = myfoaf:edd )
    && ! ( ?s = myfoaf:julia && ?p = foaf:mbox && ?o = <mailto:julia@mail.example> )
    && ! ( ?s = myfoaf:julia && ?p = rdf:type && ?o = foaf:Person))
  }

Execute the GET command with the above query added as parameter with encoded value:

GET -e -s http://host:port/sparql/?query=PREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0D%0APREFIX+foaf%3A+%3Chttp%3A%2F%2Fxmlns.com%2Ffoaf%2F0.1%2F%3E%0D%0APREFIX+myfoaf%3A+%3Chttp%3A%2F%2Fwww.example%2Fjose%2Ffoaf.rdf%23%3E%0D%0A%0D%0ACONSTRUCT+%7B+myfoaf%3Ajose+foaf%3Adepiction+%3Chttp%3A%2F%2Fwww.example%2Fjose%2Fjose.jpg%3E.%0D%0A++++++++++++myfoaf%3Ajose+foaf%3AschoolHomepage+%3Chttp%3A%2F%2Fwww.edu.example%2F%3E.%0D%0A++++++++++++%3Fs+%3Fp+%3Fo.%7D%0D%0AFROM+%3Chttp%3A%2F%2Fwww.w3.org%2F2001%2Fsw%2FDataAccess%2Fproto-tests%2Fdata%2Fconstruct%2Fsimple-data.rdf%3E%0D%0AWHERE+%7B+%3Fs+%3Fp+%3Fo.+myfoaf%3Ajose+foaf%3Anick+%22Jo%22.%0D%0A+++++++FILTER+%28+%21+%28%3Fs+%3D+myfoaf%3Akendall+%26%26+%3Fp+%3D+foaf%3Aknows+%26%26+%3Fo+%3D+myfoaf%3Aedd+%29%0D%0A++++++++++++++%26%26+%21+%28+%3Fs+%3D+myfoaf%3Ajulia+%26%26+%3Fp+%3D+foaf%3Ambox+%26%26+%3Fo+%3D+%3Cmailto%3Ajulia%40mail.example%3E+%29%0D%0A++++++++++%26%26+%21+%28+%3Fs+%3D+myfoaf%3Ajulia+%26%26+%3Fp+%3D+rdf%3Atype+%26%26+%3Fo+%3D+foaf%3APerson%29%29%0D%0A%7D%0D%0A&format=application%2Frdf%2Bxml

As result the response will be:

200 OK
Connection: close
Date: Fri, 28 Dec 2007 10:06:14 GMT
Accept-Ranges: bytes
Server: Virtuoso/05.00.3023 (Win32) i686-generic-win-32  VDB
Content-Length: 2073
Content-Type: application/rdf+xml; charset=UTF-8
Client-Date: Fri, 28 Dec 2007 10:06:14 GMT
Client-Peer: 83.176.40.177:port
Client-Response-Num: 1

<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#juan"><ns0pred:mbox xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="mailto:juan@mail.example"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:schoolHomepage xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.edu.example/"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:type xmlns:ns0pred="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:resource="http://xmlns.com/foaf/0.1/Person"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:homepage xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.example/jose/"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#juan"><ns0pred:type xmlns:ns0pred="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:resource="http://xmlns.com/foaf/0.1/Person"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:workplaceHomepage xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.corp.example/"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:nick xmlns:ns0pred="http://xmlns.com/foaf/0.1/">Jo</ns0pred:nick></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:depiction xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.example/jose/jose.jpg"/></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:name xmlns:ns0pred="http://xmlns.com/foaf/0.1/">Jose Jime?+ez</ns0pred:name></rdf:Description>
<rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:knows xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.example/jose/foaf.rdf#juan"/></rdf:Description>
</rdf:RDF>
Done

15.11.11. Implementation Notes

This service has been implemented using Virtuoso Server.


15.11.12. Virtuoso Semantic Bank end point

What is Piggy Bank?

Piggy Bank is an extension to the Firefox Web browser that turns it into a “Semantic Web browser, letting you make use of existing information on the Web in more useful and flexible ways not offered by the original Web sites.

What is Semantic Bank?

Semantic Bank is the server companion of Piggy Bank that lets you persist, share and publish data collected by individuals, groups or communities. Here is a screen shot of one in action:

What can I do with this?

A Semantic Bank allows you to:

persist your information remotely on a server. This is useful, for example, if you want to share data between two of your computers or to avoid losing it due to mistakes or failure.

share information with other people. The ability to tag resources creates a powerful serendipitous categorization (as proven by things like del.icio.us or Flickr).

lets you publish your information, both in the "pure" RDF form (for those who know how to make use of it) or to regular web pages, with the usual Longwell faceted browsing view of it

How can I help?

Semantic Bank is an open source software and built around the spirit of open participation and collaboration.

There are several ways you can help:

Licensing and Legal Issues

Semantic Bank is open source software and is licensed under the BSD license.

Note, however, that this software ships with libraries that are not released under the same license; that we interpret their licensing terms to be compatible with ours and that we are redistributing them unmodified. For more information on the licensing terms of the libraries Semantic Bank depends on, please refer to the source code.

Download location:

"http://simile.mit.edu/dist/semantic-bank/

The Virtuoso Semantic Bank end point.

Before you can publish, you must register with one or more Semantic Banks:

What is the Graph Name used by Virtuoso for the Triples from PiggyBank?

http://simile.org/piggybank/<piggybank-generated-name>

The piggybank-generated-name is Virtuoso DAV user.


15.11.13. Making RDF View Dereferenceable -- Northwind example

Consider an application that makes some relational data available for SPARQL requests, as described in first part of Northwind RDF View example. This may be sufficient for some clients but IRIs of described subjects are not dereferenceable. This means that external SPARQL processors can not retrieve that data using Virtuoso Sponger or the like. This also means that if some external resource refer to IRI of some Northwind subject and a user browses that resource then he can not look at application's data by clicking on the subject link.

To make RDF access complete, application can do the following:

The following sequence of operations demonstrate how to implement the listed features without writing any special web pages. All requests (except the application-specific index/sitemap) will be handled by existing web service endpoints.

As a precaution, we erase url rewrite rule list that may be in the database after previous run of the script:

DB.DBA.URLREWRITE_DROP_RULELIST ('demo_nw_rule_list1', 1)
;

Same for individual rewrite rules:

DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule1', 1)
;
DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule2', 1)
;
DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule3', 1)
;
DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule4', 1)
;

As a sanity check we ensure that there are no more rules named like our rules

select signal ('WEIRD', sprintf ('Rewrite rule "%s" found', URR_RULE))
from DB.DBA.URL_REWRITE_RULE where URR_RULE like 'demo_nw%'
;

Now we create URI rewrite rules based on regular expressions by calling DB.DBA.URLREWRITE_CREATE_REGEX_RULE, so same path will be redirected to different places depending on MIME types the client can accept.

This rule is to construct TURTLE or RDF/XML output of CONSTRUCT. Note dots in regexp for MIME type (rdf.n3 and rdf.xml instead of fixed chars) because there exist SPARQL web clients published before the related W3C recommendation, they will produce slightly incorrect "Accept:" string.

DB.DBA.URLREWRITE_CREATE_REGEX_RULE (
    'demo_nw_rule2',
    1,
    '(/[^#]*)',
    vector('path'),
    1,
    '/sparql?query=CONSTRUCT+{+%%3Chttp%%3A//^{URIQADefaultHost}^%U%%23this%%3E+%%3Fp+%%3Fo+}+FROM+%%3Chttp%%3A//^{URIQADefaultHost}^/Northwind%%3E+WHERE+{+%%3Chttp%%3A//^{URIQADefaultHost}^%U%%23this%%3E+%%3Fp+%%3Fo+}&format=%U',
    vector('path', 'path', '*accept*'),
    null,
    '(text/rdf.n3)|(application/rdf.xml)',
    0,
    null
    );
Note:

The request URL for SPARQL web service looks terrible due to encoding, the sprintf format string for it is even worse. The easiest way of composing strings of that sort is to open the endpoint page, type desired CONSTRUCT or DESCRIBE statement in the form (using some sample IRI), execute, cut the URL of the page with results from the address line of browser window, paste it to the script and then replace the host name with ^{URIQADefaultHost}^, every percent with double percent, some parts of sample IRI with %U and value after &format= with %U; adjust the vector of replacement parameters so that its length is equal to the number of %U or other format specifiers in the template.

Next rule is to redirect to the RDF browser that will show the subject description and let the user to explore related subjects.

DB.DBA.URLREWRITE_CREATE_REGEX_RULE (
    'demo_nw_rule1',
    1,
    '(/[^#]*)',
    vector('path'),
    1,
    '/rdfbrowser/index.html?uri=http%%3A//^{URIQADefaultHost}^%U%%23this',
    vector('path'),
    null,
    '(text/html)|(\\*/\\*)',
    0,
    303
    );

This rule is to remove trailing slash from path. Note that \x24 is $ for end of line regex pattern, it is written escaped because dollar sign indicates the beginning of macro for ISQL.

DB.DBA.URLREWRITE_CREATE_REGEX_RULE (
    'demo_nw_rule3',
    1,
    '(/[^#]*)/\x24',
    vector('path'),
    1,
    '%s',
    vector('path'),
    null,
    null,
    0,
    null
    );

This allow the server to describe proper ontology even when the requested IRI contain wrong host name and even if the ontology for http://demo.openlinksw.com/schemas/northwind# is actualy loaded in the database in graph with different IRI (http://demo.openlinksw.com/schemas/NorthwindOntology/1.0/) and the URI of downloadable ontology file differs from both (the file is /DAV/VAD/demo/sql/nw.owl) .

create procedure DB.DBA.LOAD_NW_ONTOLOGY_FROM_DAV()
{
  declare content1, urihost varchar;
  select cast (RES_CONTENT as varchar) into content1 from WS.WS.SYS_DAV_RES where RES_FULL_PATH = '/DAV/VAD/demo/sql/nw.owl';
  DB.DBA.RDF_LOAD_RDFXML (content1, 'http://demo.openlinksw.com/schemas/northwind#', 'http://demo.openlinksw.com/schemas/NorthwindOntology/1.0/');
  urihost := cfg_item_value(virtuoso_ini_path(), 'URIQA','DefaultHost');
  if (urihost = 'demo.openlinksw.com')
  {
    DB.DBA.VHOST_REMOVE (lpath=>'/schemas/northwind');
    DB.DBA.VHOST_DEFINE (lpath=>'/schemas/northwind', ppath=>'/DAV/VAD/demo/sql/nw.owl', vsp_user=>'dba', is_dav=>1, is_brws=>0);
    DB.DBA.VHOST_REMOVE (lpath=>'/schemas/northwind#');
    DB.DBA.VHOST_DEFINE (lpath=>'/schemas/northwind#', ppath=>'/DAV/VAD/demo/sql/nw.owl', vsp_user=>'dba', is_dav=>1, is_brws=>0);
  }
};

DB.DBA.LOAD_NW_ONTOLOGY_FROM_DAV();

drop procedure DB.DBA.LOAD_NW_ONTOLOGY_FROM_DAV;

DB.DBA.URLREWRITE_CREATE_REGEX_RULE (
    'demo_nw_rule4',
    1,
    '/schemas/northwind#(.*)',
    vector('path'),
    1,
    '/sparql?query=DESCRIBE%20%3Chttp%3A//demo.openlinksw.com/schemas/northwind%23%U%3E%20FROM%20%3Chttp%3A//demo.openlinksw.com/schemas/NorthwindOntology/1.0/%3E',
    vector('path'),
    null,
    '(text/rdf.n3)|(application/rdf.xml)',
    0,
    null
    );

Then we create the rulelist and define virtual directory /Northwind. Requests that match rewriting rules will be properly redirected and produce the requested data, access to the root will execute default page of the application, namely sfront.vspx.

DB.DBA.URLREWRITE_CREATE_RULELIST (
    'demo_nw_rule_list1',
    1,
    vector (
                'demo_nw_rule1',
                'demo_nw_rule2',
                'demo_nw_rule3',
                'demo_nw_rule4'
          ));

VHOST_REMOVE (lpath=>'/Northwind');
DB.DBA.VHOST_DEFINE (lpath=>'/Northwind', ppath=>'/DAV/home/demo/', vsp_user=>'dba', is_dav=>1, def_page=>'sfront.vspx',
          is_brws=>0, opts=>vector ('url_rewrite', 'demo_nw_rule_list1'));

Finally, to register the namespace prefix northwind as persistent we execute:

DB.DBA.XML_SET_NS_DECL ('northwind', 'http://demo.openlinksw.com/schemas/northwind#', 2);

15.11.14. RDF proxy service

In certain cases like for Ajax applications, it's prohibited to issue HTTP requests to another server that origin server. In other cases it is needed to transform the content of target to an RDF format. To this purpose the Virtuoso Server provide a RDF proxy service. This service takes as argument target URL and may return content as-is or will try to transform with SPARQL sponger and return RDF data representing the target. In case of transformation to RDF the serialization of the output can be forced by a URL parameter of by content negotiation.

When the rdf_mappers package is installed, Virtuoso reserves the path '/about/[rdf|html]/' for RDF proxy service. In the current implementation, Virtuoso defines virtual directories for HTTP requests that come to the port specified as 'ServerPort' in the '[HTTPServer]' section of Virtuoso configuration file and refer to the above path string. So if the Virtuoso installation on host example.com listens for HTTP requests on port 8080 then client applications should use the 'service endpoint' string equal to 'http://example.com:8080/about/[rdf|html]/'.

If the rdf_mappers package is not installed, then the path '/proxy/rdf/' is used for RDF proxy service.

The old pattern '/proxy/' for RDF proxy service is deprecated.

Note: In order the RDF proxy service to work correctly, in case you do not have the rdf_mappers package installed, you need to enable SPARQL_UPDATE and grant RDF_SPONGE_UP for SPARQL user:

enable SPARQL_UPDATE using Conductor UI:

grant RDF_SPONGE_UP:

grant execute on DB.DBA.RDF_SPONGE_UP to "SPARQL";

The RDF proxy service takes following URL parameters when using the style: http://host:port/proxy?..:

When no 'output-format' is given and RDF data is asked, the result will be serialized with MIME type depending of 'Accept' header i.e. the proxy service will do content negotiation.

Example: rdf file with URL: http://www.w3.org/People/Berners-Lee/card

-- Access the url in order to view the result in html format:
http://host:port/about/html/http://www.w3.org/People/Berners-Lee/card
-- Access the url in order to view the result in rdf:
http://host:port/about/rdf/http://www.w3.org/People/Berners-Lee/card
-- or use the style:
http://host:port/proxy/rdf/http://www.w3.org/People/Berners-Lee/card
-- or use the style:
http://host:port/proxy?url=http://www.w3.org/People/Berners-Lee/card&force=rdf

Note: It is not allowed when using the style http://host:port/proxy/rdf to pass url parameters to the proxy.

Now go to the sparql endpoint, i.e. http://host:port/sparql

Enter for Default Graph URI the url of the rdf file: http://www.w3.org/People/Berners-Lee/card

Enter for Query:

SELECT * WHERE {?s ?p ?o}

As result will be shown the saved triples:

s  	                                        p  	                                           o
http://www.w3.org/People/Berners-Lee/card 	http://www.w3.org/1999/02/22-rdf-syntax-ns#type    http://xmlns.com/foaf/0.1/PersonalProfileDocument
http://www.w3.org/People/Berners-Lee/card 	http://purl.org/dc/elements/1.1/title 	           Tim Berners-Lee's FOAF file
http://www.w3.org/People/Berners-Lee/card 	http://creativecommons.org/ns#license 	           http://creativecommons.org/licenses/by-nc/3.0/
http://www.w3.org/People/Berners-Lee/card 	http://xmlns.com/foaf/0.1/maker 	           http://www.w3.org/People/Berners-Lee/card#i
etc ...

15.11.15. SPARQL ini service

The SPARQL INI section values can be get as RDF via http://cname/sparql?ini

Example: http://demo.openlinksw.com/sparql?ini

<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:MaxQueryCostEstimationTime xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">1000</ns0pred:MaxQueryCostEstimationTime></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:ExternalXsltSource xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">1</ns0pred:ExternalXsltSource></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:DefaultQuery xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">select ?Subject ?Concept where {?Subject a ?Concept}</ns0pred:DefaultQuery></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:ResultSetMaxRows xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">100000</ns0pred:ResultSetMaxRows></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:MaxQueryExecutionTime xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">30</ns0pred:MaxQueryExecutionTime></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:ExternalQuerySource xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">1</ns0pred:ExternalQuerySource></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:DefaultGraph xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">http://demo.openlinksw.com/dataspace/person/demo</ns0pred:DefaultGraph></rdf:Description>
<rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:PingService xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">http://rpc.pingthesemanticweb.com/</ns0pred:PingService></rdf:Description>
</rdf:RDF>

15.11.16. SPARQL OAuth Endpoint

OAuth provides a secure data transmmission level mechanism for your SPARQL endpoint. It enables you to securely interact with your RDF database from a variety of locations. It also allows you to provide controlled access to private data to select user profiles.

Virtuoso OAuth server can be installed by installing the oauth_dav.vad package and the OAuth UI is accessible from the URL http://cname:port/oauth

The user must have SQL privileges in order to run secured SPARQL statements.

Here is a sample scenario:

  1. Install the conductor_dav.vad and oauth_dav.vad packages.
  2. From the Conductor UI create user test1 by setting SQL and DAV login enable. Also set SPARQL_UPDATE role to it:
    1. Go to http://cname:port/conductor
    2. Log in as dba user
    3. Go to System Admin->User Account and click the "Create New Account" link
      Conductor UI
      Figure: 15.11.16.1. Conductor UI
    4. In the shown form:
      1. Enter user name for ex. test1, password and confirm password
      2. Check "Allow DAV Logins"
      3. Check "Allow SQL/ODBC Logins"
      4. Add Role "SPARQL_UPDATE" from the list of available Roles to the "Selected" box.
        Conductor UI
        Figure: 15.11.16.1. Conductor UI
    5. Click the "Save" button.
    6. As result the user test1 will be created.
      Conductor UI
      Figure: 15.11.16.1. Conductor UI
  3. Go to http://cname:port/oauth/
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  4. Click the "OAuth keys" link
  5. Log in as user test1
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  6. As result will be shown the OAuth application registration form.
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  7. Generate key for SPARQL by selecting it from the list of "Application name" and click the "Generate Keys" button.
  8. As result for SPARQL will be generated Consumer Key for ex.:
    cf92411e17f59960a4189451bfb5bf6b92c856e3
    
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  9. Click the "Back to main menu" link.
  10. Click the "Protected SPARQL Endpoint" link.
  11. As result will be shown the OpenLink Virtuoso SPARQL Query form.
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  12. Enter for Default Graph URI this:
    http://myopenlink.net/dataspace/person/kidehen#this
    
  13. Enter for "OAuth token" field the value:
    cf92411e17f59960a4189451bfb5bf6b92c856e3
    
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  14. Click the "Run Query" button.
  15. In the shown OAuth Authorization Service form enter the password for user test1 and click the "Login" button.
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  16. In the shown form click the "Authorize" button.
    OAuth UI
    Figure: 15.11.16.1. OAuth UI
  17. As results will be shown the found results:
    OAuth UI
    Figure: 15.11.16.1. OAuth UI

15.11.17. SPARQL Endpoint with Excel mime-type output option

The SPARQL Endpoint offers an Excel mime-type output option.

From http://cname:host/sparql select for "Display Results As:" Spreadsheet and click the "Run Query" button.

SPARQL Endpoint with Excel mime-type output
Figure: 15.11.17.1. SPARQL Endpoint with Excel mime-type output

As result URL containg as parameter the format application/vnd.ms-excel for ex. this one will be generated, and can be opened directly with Excel.

SPARQL Endpoint with Excel mime-type output
Figure: 15.11.17.2. SPARQL Endpoint with Excel mime-type output

15.11.18. SPARQL Endpoint with JSON+RDF

The SPARQL Endpoint offers JSON+RDF output option.

From http://cname:host/sparql select for "Display Results As:" JSON and click the "Run Query" button.

SPARQL Endpoint with JSON+RDF output
Figure: 15.11.18.1. SPARQL Endpoint with JSON+RDF output

As result URL containg as parameter the format application/sparql-results+json will be generated and the content should look like:

SPARQL Endpoint with JSON+RDF
Figure: 15.11.18.2. SPARQL Endpoint with JSON+RDF