 (ns rdf-path-examples.sparql
   (:require [clojure.tools.logging :as log])
-  (:import [org.apache.jena.rdf.model Literal Resource]
+  (:import [org.apache.jena.rdf.model Literal Model Resource]
            [org.apache.jena.query QueryExecutionFactory QueryFactory]
-           [org.apache.jena.query Dataset]))
+           [org.apache.jena.query Dataset]
+           [org.apache.jena.update UpdateAction UpdateFactory]))
 
 ; ----- Protocols -----
 

; ----- Public functions -----

(defn ^Boolean ask-query
  "Execute SPARQL ASK `query` on RDF `dataset`."
  [^Dataset dataset
   ^String query]
  (with-open [qexec (QueryExecutionFactory/create query dataset)]
    (.execAsk qexec)))

(defmulti construct-query
  "Execute SPARQL CONSTRUCT `query` on `datasource`."
  (fn [datasource query] (type datasource)))

(defmethod ^Model construct-query Dataset
  ; Execute SPARQL CONSTRUCT `query` on local RDF `dataset`.
  [^Dataset dataset
   ^String query]
  (with-open [qexec (QueryExecutionFactory/create query dataset)]
    (.execConstruct qexec)))

(defmethod ^Model construct-query String

  "Execute SPARQL SELECT `query` on `datasource`." 
  (fn [datasource query] (type datasource)))

(defmethod select-query Model
  ; Execute SPARQL SELECT `query` on local RDF `model`.
  [^Model model
   ^String query]
  (with-open [qexec (QueryExecutionFactory/create query model)]
    (let [results (.execSelect qexec)
          result-vars (.getResultVars results)]
      (mapv (partial process-select-solution result-vars)
            (iterator-seq results)))))

(defn ^Model update-operation
  "Execute SPARQL Update `operation` on `model`."
  [^Model model
   ^String operation]
  (UpdateAction/execute (UpdateFactory/create operation) model)
  model)
