Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/sparql-results-jsonld.lisp
| Kind | Covered | All | % |
| expression | 50 | 125 | 40.0 |
| branch | 4 | 6 | 66.7 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
3
(in-package :org.datagraph.spocq.implementation)
6
;;; http://www.ietf.org/rfc/rfc4627.txt
8
;;; note that the json-ld serialization recommendation describes three profile indicators
9
;;; (http://www.w3.org/TR/json-ld/#iana-considerations), the namespace vocabulary
10
;;; (http://www.w3.org/ns/json-ld) includes single-term combinations
14
(defgeneric write-sparql-results+json-ld (results stream frame &rest args)
15
(:documentation "Encode the result field to the stream as ld+json.
16
The results are one of
17
- a solution generator
18
- a solution field instance, which comprises dimensions and a list of lists.
19
- an s-expression, wihc is interpreted as a query.")
21
(:method ((results symbol) (stream t) (frame t) &rest args)
22
"Given a boolean, emit a simple json result"
23
(declare (ignore args))
24
(write-sparql-results+json results stream))
26
(:method ((query cons) (stream t) (frame t) &rest args)
27
"Given an s-expression, delegate to frame-sparql, !!!which interprets it as a query!!!"
28
(declare (dynamic-extent args))
29
(apply #'frame-sparql query frame :stream stream args))
31
(:method ((results boolean-generator) (stream t) (frame t) &rest args)
32
"Given a boolean, emit a simple json result"
33
(declare (ignore args))
34
(write-sparql-results+json results stream))
36
(:method ((results solution-generator) (stream t) (frame json-ld:frame) &rest args)
37
(declare (dynamic-extent args))
38
(apply #'frame-sparql results frame :stream stream args))
40
(:method ((results list-solution-field) (stream t) (frame json-ld:frame) &rest args)
41
"Given a symbolic solution field, fabricate a query context, interpose
42
a bindings clause and serialize it as the result.
43
The query context is constructed to target system/null with a select
44
operation in order to provide the read-only transaction for term interning."
45
(declare (dynamic-extent args))
46
(flet ((run-bindings-thread (result-channel solutions dimensions)
47
(let ((*thread-operations* (cons (list 'spocq.a:|bindings| solutions dimensions)
48
*thread-operations*)))
49
(process-bindings result-channel solutions dimensions)
50
'spocq.a:|bindings|)))
51
(let* ((dimensions (solution-field-dimensions results))
52
;; need the task transaction context in order to intern any new terms
54
(make-query :repository-id "system/null"
55
:sse-expression `(spocq.a:|select| nil ,dimensions))))
56
(result-channel (make-channel :name (list 'spocq.a:|bindings| (task-id task))
57
:dimensions dimensions
58
:size *channel-sliced-size-limit*))
59
(generator-expression (list #'run-bindings-thread result-channel
60
(solution-field-solutions results)
62
(generator (make-solution-generator :operator 'spocq.a:|bindings|
63
:dimensions dimensions
64
:expression generator-expression
65
:channel result-channel
68
(query-run-in-thread task generator-expression)
69
(apply #'frame-sparql generator frame :stream stream args))))
71
(:method ((result-field t) (stream t) (frame t) &rest args)
72
"For an unexpected field type, just warn and ignore it"
73
(declare (ignore args))
74
(log-warn "NYI: write-sparql-results+json-ld: ~s."
75
(type-of result-field)))
78
#+(or) ;; test emitting json-ld from a symbolic field
79
(let ((id (intern-uuid (dydra:make-task-id))))
80
(write-sparql-results+json-ld
81
(spocq.i::make-list-solution-field
82
:dimensions spocq.i::*construct-dimensions*
83
:solutions `((,id |as|:|id| ,id)
84
(,id |rdf|:|type| |as|:|Update|)))
86
(json-ld:make-frame json-ld:*context*)))
92
(defmethod send-error-message ((body t) (stream t) (content-type mime:application/ld+json))
93
"Send an error response encoded as xml"
94
(send-error-message body stream mime:application/sparql-query+sse))
96
;;; need to handle profile http://www.w3.org/ns/json-ld#context == |json-ld|:|context|
98
(defmethod send-response-message ((operation t) (message t) (stream stream) (content-type mime:application/ld+json))
99
"Given a MESSAGE, and a STREAM with the application/ld+json CONTENT-TYPE, encode the content as json-ld.
100
Permit either solution field or graph content - as distinguished from the field dimensions.
102
Extract configuration from the media type to override any global configuration
103
See https://www.w3.org/TR/json-ld-syntax/#iana-considerations "
104
(when *encoding-trace-output*
105
(setf stream (make-broadcast-stream *encoding-trace-output* stream)))
106
;; extract parameters
107
(let* ((frame (json-ld:make-frame json-ld:*context*))
108
(compact (cond ((or (mime-type-profile-p content-type |json-ld|:|compacted|)
109
(mime-type-profile-p content-type |json-ld|:|compacted-flattened|))
111
((or (mime-type-profile-p content-type |json-ld|:|expanded|)
112
(mime-type-profile-p content-type |json-ld|:|expanded-flattened|))
114
(t json-ld:*compact*)))
115
(embed (cond ((or (mime-type-profile-p content-type |json-ld|:|flattened|)
116
(mime-type-profile-p content-type |json-ld|:|compacted-flattened|)
117
(mime-type-profile-p content-type |json-ld|:|expanded-flattened|))
119
(t json-ld:*embed*))))
120
(log-notice "send-response-message: (json-ld) ~s compact ~s embed ~s"
121
(mime-type-namestring content-type)
123
(write-sparql-results+json-ld message stream frame