This page discusses using Clojure to interact with Stardog.
<details open markdown="block"> <summary> Page Contents </summary> 1. TOC </details>The stardog-clj source code is available under the Apache 2.0 license.
Stardog-clj provides a set of functions as API wrappers to the native SNARL API. These functions provide the basis for working with Stardog, starting with connection management, connection pooling, and the core parts of the API, such as executing a SPARQL query or adding and removing RDF from the Stardog database. Over time, other parts of the Stardog API will be appropriately wrapped with Clojure functions and idiomatic Clojure data structures.
Stardog-clj provides the following features:
SELECT, ASK, CONSTRUCT, and SPARQL Update queries respectively.The API with source docs can be found in the stardog.core and stardog.values namespaces.
Stardog-clj is available from Clojars. To use, just include the following dependency:
[stardog-clj "7.4.0"]
Starting with Stardog 6.0.1, the stardog-clj version always matches the latest release of Stardog.
The API provides a natural progression of functions for interacting with Stardog
(create-db-spec "testdb" "http://localhost:5820/" "admin" "admin" "none")
This creates a connection space for use in connect or make-datasource with the potential parameters:
Create a single Connection using the database spec. Can be used with with-open, with-transaction, and with-connection-tx macros.
(connect db-spec)
Creates a data source, i.e. ConnectionPool, using the database spec. Best used within the with-connection-pool macro.
(make-datasource db-spec)
Executes the body with a transaction on each of the connections. Or establishes a connection and a transaction to execute the body within.
(with-transaction [connection...] body)
(with-connection-tx binding-forms body)
Evaluates body in the context of an active connection obtained from the connection pool.
(with-connection-pool [con pool] .. con, body ..)
Here are some examples of using stardog-clj:
=> (use 'stardog.core)
=> (def c (connect))
=> (def results (query c "select ?n { .... }"))
=> (take 5 results)
()
=> (def string-results (query c "select ?n { .... }"))
=> (take 5 string-results)
()
(let [c (connect test-db-spec)]
(with-transaction [c]
(insert! c ["urn:test" "urn:test:clj:prop2" "Hello World"])
(insert! c ["urn:test" "urn:test:clj:prop2" "Hello World2"]))
myapp.core=> (use 'stardog.core)
nil
myapp.core=> (def db-spec (create-db-spec "testdb" "snarl://localhost:5820/" "admin" "admin" "none"))
#'myapp.core/db-spec
myapp.core=> (def ds (make-datasource db-spec))
myapp.core=> (with-connection-pool [conn ds]
#_=> (query conn "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 2"))
()
;; First, add a triple
;; Then run an udpate query, which is its own transaction
;; Finally, confirm via ask
(with-open [c (connect test-db-spec)]
(with-transaction [c]
(insert! c ["urn:testUpdate:a1" "urn:testUpdate:b" "aloha world"]))
(update c "DELETE { ?a ?b \"aloha world\" } INSERT { ?a ?b \"shalom world\" } WHERE { ?a ?b \"aloha world\" }"
})
(ask c "ask { ?s ?p \"shalom world\" }") => truthy)
;; Graph results converted into Clojure data using the values methods
(with-open [c (connect test-db-spec)]
(let [g (graph c "CONSTRUCT { <urn:test> ?p ?o } WHERE { <urn:test> ?p ?o } ")]
g) => (list [(as-uri "urn:test") (as-uri "urn:test:clj:prop3") "Hello World"]))
;; Ask returns a Boolean
(with-open [c (connect test-db-spec)]
(ask c "ask { ?s <http://www.lehigh.edu/~zhp2/2004/0401/univ-bench.owl#teacherOf> ?o }")) => truthy)