From d8c78fe40dcb3c927bc5ab4f74b759adaa96e5a8 Mon Sep 17 00:00:00 2001 From: nathaniel Date: Wed, 20 Dec 2017 15:19:31 +0100 Subject: [PATCH 1/3] Add option for explicit rdf:type declarations Sometimes it's useful to have rdf:types explicitly declared in property and relation queries. This is implemented, and can be turned on using the parameter *declare-resource-types-p*. --- configuration/settings.lisp | 4 ++++ framework/call-implementation.lisp | 34 +++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/configuration/settings.lisp b/configuration/settings.lisp index b4a8c31..2494150 100644 --- a/configuration/settings.lisp +++ b/configuration/settings.lisp @@ -29,3 +29,7 @@ (defparameter *supply-cache-headers-p* nil "when non-nil, cache headers are supplied. this works together with mu-cache.") +(defparameter *declare-resource-types-p* + (let ((env (uiop:getenv "MU_DECLARE_RESOURCE_TYPES"))) + (and env (or (equal "true" env) (equal env "TRUE")))) + "when true, explicitly declare rdf:type for all resources in property and relation queries.") diff --git a/framework/call-implementation.lisp b/framework/call-implementation.lisp index 62c9cfd..8eb7fea 100644 --- a/framework/call-implementation.lisp +++ b/framework/call-implementation.lisp @@ -375,9 +375,26 @@ (setf (gethash property (solution-fields solution)) value)) (defun solution-field-p (solution property) - "returns non-nil if has been fetched for ." + "Returns non-nil if has been fetched for ." (second (multiple-value-list (solution-value solution property)))) +(defun resource-type-declaration (resource-url resource) + "Returns an rdf:type declaration if *declare-resource-types-p* is t, + otherwise the empty string." + (if *declare-resource-types-p* + (format nil "~A a ~A. " + (s-url resource-url) (ld-class resource)) + "")) + +(defun relation-resource-type-declaration (resource-url resource link) + "Returns an rdf:type declaration for linked resources if + *declare-resource-types-p* is t, otherwise the empty string." + (if *declare-resource-types-p* + (format nil "~A a ~A. ~A a ~A.~%" + resource-url (ld-class resource) "?resource" + (ld-class (find-resource-by-name (resource-name link)))) + "")) + (defgeneric complete-solution (solution item-spec) (:documentation "Completes for the settings requested in .") @@ -407,7 +424,8 @@ (sparql:select "*" (format nil - "~{~&~:[OPTIONAL {~A ~{~A~,^/~} ~A.}~;~A ~{~A~,^/~} ~A.~]~}" + "~A~{~&~:[OPTIONAL {~A ~{~A~,^/~} ~A.}~;~A ~{~A~,^/~} ~A.~]~}" + (resource-type-declaration resource-url resource) (loop for slot in missing-single-value-properties append (list (required-p slot) (s-url resource-url) @@ -664,9 +682,11 @@ :resource (referred-resource link) :sparql-body (filter-body-for-search :sparql-body (format nil - (s+ "~A ~{~A~,^/~} ?resource. " + (s+ "~A" + "~A ~{~A~,^/~} ?resource. " "?resource mu:uuid ?uuid. " "~@[~A~] ") + (relation-resource-type-declaration resource-url resource link) resource-url (ld-property-list link) (authorization-query resource :show resource-url)) @@ -693,9 +713,11 @@ (let* ((resource-url (s-url (node-url item-spec))) (query-results (first (sparql:select (s-var "uuid") - (format nil (s+ "~A ~{~A~,^/~} ?resource. " + (format nil (s+ "~A" + "~A ~{~A~,^/~} ?resource. " "?resource mu:uuid ?uuid. " "~@[~A~] ") + (relation-resource-type-declaration resource-url (resource item-spec) link) resource-url (ld-property-list link) (authorization-query item-spec :show resource-url))))) @@ -708,9 +730,11 @@ (let* ((resource-url (s-url (node-url item-spec))) (query-results (sparql:select (s-var "uuid") - (format nil (s+ "~A ~{~A~,^/~} ?resource. " + (format nil (s+ "~A" + "~A ~{~A~,^/~} ?resource. " "?resource mu:uuid ?uuid. " "~@[~A~] ") + (relation-resource-type-declaration resource-url resource link) resource-url (ld-property-list link) (authorization-query item-spec :show resource-url)))) From f5cf77717d8972fb9c3d760774c3149fd94d7ad8 Mon Sep 17 00:00:00 2001 From: nathaniel Date: Fri, 22 Dec 2017 11:42:22 +0100 Subject: [PATCH 2/3] Fix invalid SPARQL expression in uuid pagination query Although it's accepted by Virtuoso, technically `MAX(?__name1) AS ?__name1` is invalid SPARQL, since it omits the surrounding parentheses. The select clause should be `SELECT DISTINCT ?uuid (MAX(?__name1) AS ?__name1)`. --- framework/response-generation.lisp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/response-generation.lisp b/framework/response-generation.lisp index 6e82c21..537f25c 100644 --- a/framework/response-generation.lisp +++ b/framework/response-generation.lisp @@ -56,7 +56,7 @@ ;; between having to sort (order-info) and not having ;; to sort. some logic is shared. (let ((sparql-variables (if order-info - (format nil "DISTINCT ~A~{ ~{MAX(~A) AS ~A~}~}" + (format nil "DISTINCT ~A~{ ~{(MAX(~A) AS ~A)~}~}" (s-var "uuid") (mapcar (lambda (a) (list a a)) order-variables)) (format nil "DISTINCT ~A" (s-var "uuid")))) (sparql-body (if order-info From b21eb38a17f8577c8b872a80de50964cf2e79bfd Mon Sep 17 00:00:00 2001 From: nathaniel Date: Tue, 29 May 2018 20:57:53 +0200 Subject: [PATCH 3/3] Add feature type declaration for single included query --- configuration/settings.lisp | 2 +- framework/call-implementation.lisp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/configuration/settings.lisp b/configuration/settings.lisp index 2494150..9ff0c1d 100644 --- a/configuration/settings.lisp +++ b/configuration/settings.lisp @@ -31,5 +31,5 @@ (defparameter *declare-resource-types-p* (let ((env (uiop:getenv "MU_DECLARE_RESOURCE_TYPES"))) - (and env (or (equal "true" env) (equal env "TRUE")))) + (and env (or (equal env "true") (equal env "TRUE") (equal env "True") (equal env T)))) "when true, explicitly declare rdf:type for all resources in property and relation queries.") diff --git a/framework/call-implementation.lisp b/framework/call-implementation.lisp index 8eb7fea..28fda03 100644 --- a/framework/call-implementation.lisp +++ b/framework/call-implementation.lisp @@ -381,7 +381,7 @@ (defun resource-type-declaration (resource-url resource) "Returns an rdf:type declaration if *declare-resource-types-p* is t, otherwise the empty string." - (if *declare-resource-types-p* + (if (or 4 *declare-resource-types-p*) (format nil "~A a ~A. " (s-url resource-url) (ld-class resource)) "")) @@ -929,10 +929,11 @@ (loop for new-uuid in (jsown:filter (sparql:select (s-distinct (s-var "target")) - (format nil (s+ "?s mu:uuid ~A. " + (format nil (s+ "?s mu:uuid ~A" "~A. " "?s ~{~A/~}mu:uuid ?target. " "~@[~A~] ") (s-str uuid) + (if *declare-resource-types-p* (format nil "; a ~A" (ld-class resource)) "") (ld-property-list relation) (authorization-query resource :show (s-var "s")))) map "target" "value")