Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/sparql-results-nquads.lisp
| Kind | Covered | All | % |
| expression | 107 | 269 | 39.8 |
| branch | 10 | 26 | 38.5 |
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)
5
;;; results as nquads; serializer only
7
(defparameter *ntriples-unbound-term-mode* 'spocq:unbound-variable) ;; 'error)
8
(defparameter *nquads-default-graph-term* nil) ; |urn:dydra|:|default|)
11
;;; writing sparql results and terms
13
(defun nquads-eol (stream)
14
(write-string (load-time-value (coerce #(#\return #\linefeed) 'string)) stream))
16
(defgeneric write-rdf-nquads (results stream)
17
(:documentation "Encode the result field to the stream as ntriples.
18
The results must have three or four dimensions - if four, then treat the elemnents as quads.
19
Allow the first element to be a list of dimensions.
20
The remaining entries aer solutions sets. if a variable is unbound, the solution element is etf:nil.")
22
(:method ((results list-solution-field) (stream stream))
23
(write-rdf-nquads (cons (solution-field-dimensions results)
24
(solution-field-solutions results))
27
(:method ((results cons) (stream stream))
28
(let* ((variables (if (every #'variable-p (first results))
30
(solutions (if (eq variables (first results)) (rest results) results))
32
(start (or (response-offset) 0))
34
(default-graph-term (iri-lexical-form *nquads-default-graph-term*)))
36
(unless (typep (length variables) '(integer 3 4))
37
(spocq.e:request-error "Invalid n-triples/n-quads field: ~s ..." variables))
39
(case (length (first solutions))
41
(t (triple-dimensions)))))
43
(setf solutions (nthcdr start solutions))
46
(dolist (result solutions)
47
(when (and end (>= index end))
49
(loop for value in result
50
for value-index from 0
52
;; emit non-null values and enable commas
53
((or null spocq:unbound-variable (member etf:nil))
55
(when default-graph-term
56
(write-string default-graph-term stream))
57
(ecase *ntriples-unbound-term-mode*
58
(spocq:unbound-variable
59
(format stream "<urn:dydra:unbound~@[:~a~]>" (nth value-index variables)))
61
(spocq.e:request-error "invalid null ntriples/nquads term: ~s" value)))))
62
(t (encode-turtle-object value stream)
63
(write-char #\space stream))))
64
(write-char #\. stream)
67
(incf-stat *statements-returned* index)
70
(:method ((results solution-generator) (stream stream))
71
(let* ((dimensions (solution-generator-dimensions results))
72
(channel (solution-generator-channel results))
73
(base-width (length dimensions))
75
(start (or (response-offset) 0))
77
(case (length dimensions)
80
(do-pages (page channel)
81
(when (and end (>= index end))
83
(if (>= (+ index (array-dimension page 0)) start)
84
(cond ((= base-width (array-dimension page 1))
85
(trace-data write-rdf-ntriples dimensions (term-value-field page))
86
(setf index (write-rdf-field-nquads page dimensions stream index start end)))
88
(log-warn "field width mismatch: ~s : ~s."
89
dimensions (array-dimension page 1))
90
(incf index (array-dimension page 0))))
91
; otherwise skip the entire page
92
(incf index (array-dimension page 0))))
93
(incf-stat *statements-returned* index))
95
;; this should not happen, as other arity should not parse
96
(spocq.e:request-error "Invalid ntriples/nquads field: ~s ..." dimensions)))
99
(defun write-rdf-field-nquads (page variables stream &optional (index 0) (start 0) end)
100
(assert (= (length (array-dimensions page)) 2) () "invalid result array dimensions: ~a" (array-dimensions page))
101
(flet ((term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
102
(encode-turtle-term-aspects term-type term-literal term-language-tag term-datatype stream)))
103
(declare (dynamic-extent #'term-aspect-encoder))
104
(let ((term-deconstructor (repository-term-deconstructor *transaction*))
105
(width (array-dimension page 1))
106
(default-graph-term (when *nquads-default-graph-term* (iri-lexical-form *nquads-default-graph-term*))))
107
(dotimes (page-index (array-dimension page 0))
108
(when (>= index start)
109
(when (and end (>= index end))
111
(loop for value-index from 0 below width
112
do (let ((term-id (aref page page-index value-index)))
113
;; (print (list page-index value-index term-id))
116
(if (= value-index 3)
117
(when default-graph-term
118
(format stream "<~a>" default-graph-term))
119
(ecase *ntriples-unbound-term-mode*
120
(spocq:unbound-variable
121
(format stream "<urn:dydra:unbound~@[:~a~]>" (nth value-index variables)))
123
(error "invalid null ntriples/nquads term.")))))
125
;; suppress the term as the graph designator
126
(if (= value-index 3)
127
(when default-graph-term
128
(format stream "<~a>" default-graph-term))))
130
(write-string "<urn:dydra:named>" stream))
132
(funcall term-deconstructor #'term-aspect-encoder *transaction* term-id)))
133
(write-char #\space stream)))
134
(write-char #\. stream)
141
(defmethod send-response-message (operation (message t) (stream t) (content-type mime:text/plain))
142
"Given a MESSAGE, and a STREAM with the text/plain CONTENT-TYPE, encode as ntriples"
143
(when *encoding-trace-output*
144
(setf stream (make-broadcast-stream *encoding-trace-output* stream)))
145
(let ((*package* *spocq-reader-package*))
146
(write-rdf-nquads message stream)))
148
(defmethod send-response-message (operation (message t) (stream t) (content-type mime:application/n-triples))
149
"Given a MESSAGE, and a STREAM with the application/n-triples CONTENT-TYPE, encode as ntriples"
150
(when *encoding-trace-output*
151
(setf stream (make-broadcast-stream *encoding-trace-output* stream)))
152
(let ((*package* *spocq-reader-package*))
153
(write-rdf-nquads message stream)))
155
(defmethod send-response-message (operation (message t) (stream t) (content-type mime:application/n-quads))
156
"Given a MESSAGE, and a STREAM with the application/n-quads CONTENT-TYPE, encode as nquads"
157
(when *encoding-trace-output*
158
(setf stream (make-broadcast-stream *encoding-trace-output* stream)))
159
(let ((*package* *spocq-reader-package*))
160
(write-rdf-nquads message stream)))
163
(test-sparql "describe ?s where { ?s <http://example.org/identifier> 'c878cd60-0e0b-11e9-9fc2-010203040506'}"
164
:repository-id "jhacker/test"
165
:response-content-type mime:application/n-quads)