about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn/db/mysql.scm7
-rwxr-xr-x[-rw-r--r--]gn/db/sparql.scm83
-rw-r--r--web/webserver.scm36
3 files changed, 77 insertions, 49 deletions
diff --git a/gn/db/mysql.scm b/gn/db/mysql.scm
index 623a726..8da7b60 100644
--- a/gn/db/mysql.scm
+++ b/gn/db/mysql.scm
@@ -37,9 +37,10 @@
     )))
 
 (define (call-with-db thunk)
-  (let [(db (db-open))]
-    (thunk db)
-    (dbi-close db)))
+  (let* [(db (db-open))
+         (result (thunk db))]
+    (dbi-close db)
+    result))
 
 (define (ensure db msg1)
   "Use DBI-style handle to report an error. On error the program will stop."
diff --git a/gn/db/sparql.scm b/gn/db/sparql.scm
index bd7a306..8722966 100644..100755
--- a/gn/db/sparql.scm
+++ b/gn/db/sparql.scm
@@ -18,10 +18,11 @@ the case.
   #:use-module (json)
   #:use-module (srfi srfi-1)
   #:use-module (web client)
+  #:use-module (web http)
   #:use-module (web gn-uri)
   #:use-module (web request)
+  #:use-module (web response)
   #:use-module (web uri)
-
   #:export (memo-sparql-species
             memo-sparql-species-meta
             sparql-species-meta
@@ -37,9 +38,11 @@ the case.
             strip-lang
             make-table
             make-pairs
-            )
-)
+	    sparql-http-get
+	    sparql-by-term))
 
+(define virtuoso-endpoint
+  (or (getenv "SPARQL-ENDPOINT") "http://localhost:8890/sparql/"))
 
 (define (strip-lang s)
   "Strip quotes and language tag (@en) from RDF entries"
@@ -58,9 +61,9 @@ the case.
 (define (gn-sparql-prefix query)
   (string-append
   "
-PREFIX gn:  <http://genenetwork.org/id/>
-PREFIX gnt: <http://genenetwork.org/term/>
-PREFIX gnc: <http://genenetwork.org/category/>
+PREFIX gn:  <http://rdf.genenetwork.org/v1/id/>
+PREFIX gnt: <http://rdf.genenetwork.org/v1/term/>
+PREFIX gnc: <http://rdf.genenetwork.org/v1/category/>
 PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
 
 " query))
@@ -108,46 +111,7 @@ Note this procedure works for GN, but does not yet work for wikidata"
 (define (tsv->scm text)
   "Split a TSV string into a list of fields. Returns list of names header) and rows"
   (let ([lst (map (lambda (f) (string-split f #\tab) ) (delete "" (string-split text #\newline)))])
-    (values (car lst) (cdr lst))
-  ))
-
-#!
-(define-values (names res) (sparql-species-meta))
-(define table (get-rows names res))
-(define recs '())
-(define h (compile-species recs table))
-(assoc "http://genenetwork.org/species_drosophila_melanogaster" h)
-(assoc-ref h "http://genenetwork.org/id/Drosophila_melanogaster")
-(define d (car h))
-(assoc-ref (list d) "http://genenetwork.org/species_drosophila_melanogaster")
-
-(scm->json #(1  (("2" . 3))))
-;; [1,{"2":3}]
-(scm->json #("http://genenetwork.org/species_drosophila_melanogaster" (("http://genenetwork.org/menuName" . "Drosophila") ("http://genenetwork.org/binomialName" . "Drosophila melanogaster") )))
-;; ["http://genenetwork.org/species_drosophila_melanogaster",{"http://genenetwork.org/menuName":"Drosophila","http://genenetwork.org/binomialName":"Drosophila melanogaster"}]
-l
-;; (("http://genenetwork.org/menuName" "Drosophila") ("http://genenetwork.org/name" "Drosophila") ("http://genenetwork.org/binomialName" "Drosophila melanogaster"))
-(scm->json (map (lambda (i) (cons (car i) (car (cdr i)))) l))
-;; {"http://genenetwork.org/menuName":"Drosophila","http://genenetwork.org/name":"Drosophila","http://genenetwork.org/binomialName":"Drosophila melanogaster"}
-
-
-curl -G https://query.wikidata.org/sparql -H "Accept: application/json; charset=utf-8" --data-urlencode query="SELECT DISTINCT * where {
-  wd:Q158695 wdt:P225 ?o .
-} limit 5"
-{
-  "head" : {
-    "vars" : [ "o" ]
-  },
-  "results" : {
-    "bindings" : [ {
-      "o" : {
-        "type" : "literal",
-        "value" : "Arabidopsis thaliana"
-      }
-    } ]
-  }
-}
-!#
+    (values (car lst) (cdr lst))))
 
 (define (sparql-wd-species-info species)
   "Returns wikidata entry for species, e.g.:
@@ -326,3 +290,30 @@ dump-species-metadata.ttl:gn:Axbxa gnt:belongsToSpecies gn:Mus_musculus .
             " gnid " ?key ?value .
             # FILTER ( !EXISTS{ " gnid " gnt:hasTissue ?value })
 }")))
+
+
+(define* (sparql-http-get endpoint-url query #:optional (mime-type "text/microdata+html"))
+  (receive (response-status response-body)
+      (http-request
+       (format #f "~a?default-graph-uri=&query=~a&format=~a"
+	       endpoint-url (uri-encode query) (uri-encode mime-type))
+       #:method 'GET)
+    (values
+     (build-response
+      #:code (response-code response-status)
+      #:headers `((content-type . ,(parse-header 'content-type mime-type))))
+     response-body)))
+
+(define (sparql-by-term prefix val)
+  (let ((url-alist '((gn . "<http://rdf.genenetwork.org/v1/id/>")
+		     (gnc . "<http://rdf.genenetwork.org/v1/category/>")
+		     (gnt . "<http://rdf.genenetwork.org/v1/term/>"))))
+    (format #f "PREFIX ~a: ~a
+
+CONSTRUCT {
+  ~a:~a ?p ?o .
+} FROM <http://rdf.genenetwork.org/v1>
+WHERE {
+  ~a:~a ?p ?o .
+  ?s ?p ?o .
+}" prefix (assoc-ref url-alist prefix) prefix val prefix val)))
diff --git a/web/webserver.scm b/web/webserver.scm
index 0c0bdd1..6a0bd37 100644
--- a/web/webserver.scm
+++ b/web/webserver.scm
@@ -202,6 +202,24 @@ otherwise search for set/group data"
                                   `(("error" . ,key)
                                     ("msg" . ,msg)))))))
 
+(define (render-sparql request prefix val)
+  (let* ((mime (negotiate-mime request))
+	 (resp-mime (if (or (string-contains (symbol->string mime) "html")
+			    (string-contains (symbol->string mime) "microdata"))
+			'text/html
+			mime)))
+    (receive (sparql-header sparql-resp)
+	(sparql-http-get
+	 (or (getenv "SPARQL-ENDPOINT") "http://localhost:8890/sparql/")
+	 (sparql-by-term prefix val)
+	 (symbol->string mime))
+      (list `((content-type ,resp-mime))
+	    (lambda (port)
+	      (let ((resp (if (string? sparql-resp)
+			      sparql-resp
+			      (utf8->string sparql-resp))))
+		(put-string port resp)))))))
+
 (define (invalid-data? data target)
   (if (string? (assoc-ref data target))
       (if (string-null? (assoc-ref data target))
@@ -244,6 +262,14 @@ otherwise search for set/group data"
                                   `(("error" . ,key)
                                     ("msg" . ,msg)))))))
 
+(define (negotiate-mime request)
+  (let* ((headers (request-headers request))
+	 (accept (caar (assoc-ref headers 'accept))))
+    (if (or (eq? (string->symbol "*/*") accept)
+	    (eq? (string->symbol "text/html") accept))
+	'application/x-nice-microdata
+	accept)))
+
 (define (controller request body)
   (match-lambda
     (('GET)
@@ -327,6 +353,16 @@ otherwise search for set/group data"
                 #\n)
           (render-json (get-id-data (list->string name))))
          (rest (render-json "NOP")))))
+    ;; RDF End-points
+    (('GET "v1" "id" id)
+     (render-sparql request 'gn id))
+
+    (('GET "v1" "category" category)
+     (render-sparql request 'gnc category))
+
+    (('GET "v1" "term" term)
+     (render-sparql request 'gnt term))
+
     (_ (not-found (request-uri request)))))
 
 (define (request-path-components request)