sparql-utils provides some convenient utilities for working with SPARQL queries in Scala. Current functionality includes:
- A string interpolator for embedding and properly formatting/escaping Scala objects within SPARQL.
- Decoding of SPARQL SELECT results to case class instances via automatic typeclass derivation.
SPARQL handling in sparql-utils is based on Apache Jena.
A separate module provides additional support for OWL API types.
sparql-utils depends on two great libraries for its implementation:
propensive/contextual and propensive/magnolia.
libraryDependencies += "org.phenoscape" %% "sparql-utils" % "1.2"For OWL API support:
libraryDependencies += "org.phenoscape" %% "sparql-utils-owlapi" % "1.2"scala> import org.apache.jena.rdf.model.ResourceFactory
import org.apache.jena.rdf.model.ResourceFactory
scala> import org.phenoscape.sparql.SPARQLInterpolation._
import org.phenoscape.sparql.SPARQLInterpolation._
scala> val foafName = ResourceFactory.createResource("http://xmlns.com/foaf/0.1/name")
foafName: org.apache.jena.rdf.model.Resource = http://xmlns.com/foaf/0.1/name
scala> val personName = "Ignatius J. Reilly"
personName: String = Ignatius J. Reilly
scala> val query =
| sparql"""
| SELECT DISTINCT ?person
| WHERE {
| ?person $foafName $personName .
| }
| """
query: org.phenoscape.sparql.SPARQLInterpolation.QueryText =
QueryText(
SELECT DISTINCT ?person
WHERE {
?person <http://xmlns.com/foaf/0.1/name> "Ignatius J. Reilly" .
}
)Various built-in and Jena types are automatically supported for embedding, including
Resource, Property, Node, Literal, String, Boolean, and numeric types.
With the owlapi module you can also embed the various OWL entities (e.g. OWLClass) as URIs,
as well as OWLLiteral instances.
The sparql"" interpolator produces a QueryText object. These can be concatenated using +.
A QueryText can be embedded using the interpolator; in this case no escaping happens, allowing queries to
be built from fragments.
scala> val people = List(ResourceFactory.createResource("http://example.org/Homer"), ResourceFactory.createResource("http://example.org/Marge"), ResourceFactory.createResource("http://example.org/Bart"))
people: List[org.apache.jena.rdf.model.Resource] = List(http://example.org/Homer, http://example.org/Marge, http://example.org/Bart)
scala> val values = people.map(p => sparql"$p ").reduce(_ + _)
values: org.phenoscape.sparql.SPARQLInterpolation.QueryText = QueryText(<http://example.org/Homer> <http://example.org/Marge> <http://example.org/Bart> )
scala> sparql"""
| SELECT ?name
| WHERE {
| VALUES ?person { $values }
| ?person $foafName ?name .
| }
| """
res0: org.phenoscape.sparql.SPARQLInterpolation.QueryText =
QueryText(
SELECT ?name
WHERE {
VALUES ?person { <http://example.org/Homer> <http://example.org/Marge> <http://example.org/Bart> }
?person <http://xmlns.com/foaf/0.1/name> ?name .
}
)You can convert the QueryText to a Jena Query (may throw a QueryParseException):
scala> res0.toQuery
res1: org.apache.jena.query.Query =
SELECT ?name
WHERE
{ VALUES ?person { <http://example.org/Homer> <http://example.org/Marge> <http://example.org/Bart> }
?person <http://xmlns.com/foaf/0.1/name> ?name
}