Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/sparql-results-json-columns.lisp
| Kind | Covered | All | % |
| expression | 0 | 372 | 0.0 |
| branch | 0 | 38 | 0.0 |
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+json-columns serializer
6
;;; ideosyncratic to dydra
11
;;; writing - either boolean or bindings
13
(defgeneric write-sparql-results+json-columns (results stream)
14
(:documentation "Encode the result field to the stream as results+json-columns.
15
The results are a list of lists. The first element is a header, which specifies the variable names.
16
The remaining entries are solutions sets. if a variable is unbound, the solution element is etf:nil.")
18
(:method ((result symbol) (stream t))
19
(format stream "{\"columns\": [\"result\"], \"rows\": [ [")
20
(encode-json-term result stream)
21
(format stream "] ], \"total\": 1}~%")
22
(incf-stat *statements-returned*))
24
(:method ((results cons) (stream t))
25
(let* ((variables (first results))
26
(solutions (rest results))
28
(start (or (response-offset) 0))
30
(format stream "{\"columns\": [~{\"~a\"~^, ~}]," variables)
31
(format stream "~% \"rows\": [")
32
(dolist (result solutions)
33
(when (>= index start)
34
(when (and end (>= index end))
36
(unless (= index start)
37
(write-char #\, stream)
39
(write-string " [" stream)
40
(loop for value in result
42
do (progn (unless (shiftf first nil) (write-string ", " stream))
43
(encode-json-term value stream)))
44
(write-string "]" stream))
46
(format stream " ],~% \"total\": ~d}~%" index)
47
(incf-stat *statements-returned* index)))
49
(:method ((results boolean-generator) (stream t))
50
(let* ((channel (boolean-generator-channel results)))
51
(write-string "{\"columns\": [\"result\"], \"rows\": [ [" stream)
52
(write-string (spocq:literal-lexical-form (if (get-field-page channel) spocq.a:|true| spocq.a:|false|)) stream)
53
(write-string "] ], \"total\": 1}" stream)
54
(incf-stat *statements-returned*)))
56
(:method ((results solution-generator) (stream t))
57
(let* ((dimensions (solution-generator-dimensions results))
58
(channel (solution-generator-channel results))
59
(variable-count (length dimensions))
61
(start (or (response-offset) 0))
63
(format stream "{\"columns\": [~{\"~a\"~^, ~}]," dimensions)
64
(format stream "~% \"rows\": [")
65
(do-pages (page channel)
66
(if (and end (>= index end))
68
(if (>= (+ index (array-dimension page 0)) start)
69
(cond ((= variable-count (array-dimension page 1))
70
(trace-data write-sparql-results+json-columns dimensions (term-value-field page))
71
(setf index (write-sparql-results-field+json-columns page stream index start end)))
73
(log-warn "field width mismatch: ~s : ~s."
74
dimensions (array-dimension page 1))
75
(incf index (array-dimension page 0))))
76
; otherwise skip the entire page
77
(incf index (array-dimension page 0)))))
78
(format stream " ],~% \"total\": ~d}~%" index)
79
(incf-stat *statements-returned* index)))
81
(:method ((result-field true-matrix-field) (stream t))
82
(format stream "{\"columns\": [\"result\"], \"rows\": [ [ ~a ] ], \"total\": 1}"
83
(spocq:literal-lexical-form spocq.a:|true|))
84
(incf-stat *statements-returned*))
86
(:method ((result-field false-matrix-field) (stream t))
87
(format stream "{\"columns\": [\"result\"], \"rows\": [ [ ~a ] ], \"total\": 1}"
88
(spocq:literal-lexical-form spocq.a:|false|))
89
(incf-stat *statements-returned*))
91
(:method ((result-field matrix-field) (stream t))
92
(flet ((term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
93
(encode-json-term-aspects term-type term-literal term-language-tag term-datatype stream)))
94
(declare (dynamic-extent #'term-aspect-encoder))
95
(let ((term-deconstructor (repository-term-deconstructor *transaction*)))
96
(let* ((dimensions (solution-field-dimensions result-field))
97
(base-width (length dimensions))
98
(start (or (response-offset) 0))
102
(with-input-fields (result-field)
103
(format stream "{\"columns\": [~{\"~a\"~^, ~}]," (remove-if-not #'distinguished-variable-p dimensions))
104
(format stream "~% \"rows\": [")
105
(let ((%source-data (cffi::null-pointer))
107
(setf (values %source-data source-row) (first-field-row result-field))
108
(loop until (and end (>= result-count (the fixnum end)))
109
until (cffi:null-pointer-p %source-data)
111
(trace-matrix "~& write-sparql-results+json-columns.next ~@{~a ~}" :source-row source-row)
112
(when (> (incf result-count) start)
113
(format stream "~:[,~;~]~% " (shiftf first nil))
114
(write-string " [" stream)
116
for term-offset from (* base-width source-row)
117
for name in dimensions
118
when (distinguished-variable-p name)
119
do (let ((term-id (#.+matrix-accessor+ (the sb-sys:system-area-pointer %source-data)
120
(the fixnum (* #.(cffi:foreign-type-size +matrix-element-type+) term-offset)))))
121
(if (shiftf first nil) (write-char #\space stream) (format stream ", "))
122
(cond ((= term-id +null-term-id+)
123
(write-string "{}" stream))
125
(funcall term-deconstructor #'term-aspect-encoder *transaction* term-id)))))
126
(write-string " ]" stream))
127
(setf (values %source-data source-row) (next-field-row result-field)))))
128
(incf-stat *statements-returned* (- result-count start))
129
(format stream " ],~% \"total\": ~d}~%" (- result-count start))
131
(incf-stat *statements-returned* (- result-count start))))))
138
(defun write-sparql-results-field+json-columns (page stream &optional (index 0) (start 0) end)
139
(assert (= (length (array-dimensions page)) 2) () "invalid result array dimensions: ~a" (array-dimensions page))
140
(flet ((term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
141
(encode-json-term-aspects term-type term-literal term-language-tag term-datatype stream)))
142
(declare (dynamic-extent #'term-aspect-encoder))
143
(let ((term-deconstructor (repository-term-deconstructor *transaction*)))
144
(let ((variable-count (array-dimension page 1)))
145
(dotimes (page-index (array-dimension page 0))
146
(when (>= index start)
147
(when (and end (>= index end))
149
(unless (= index start)
150
(write-char #\, stream)
152
(write-string " [" stream)
153
(loop for value-index from 0 below variable-count
154
do (let ((term-id (aref page page-index value-index)))
155
(unless (zerop value-index)
156
(write-string ", " stream)
158
(cond ((= term-id +null-term-id+)
159
(write-string "{}" stream))
161
(funcall term-deconstructor #'term-aspect-encoder *transaction* term-id)))))
162
(write-string "]" stream))
167
(defmethod send-error-message ((body t) (stream t) (content-type mime:application/sparql-results+json-columns))
168
"Send an error response encoded as xml"
169
(send-error-message body stream mime:application/sparql-query+sse))
172
(defmethod send-response-message (operation (message-body t) (stream t)
173
(content-type mime:application/sparql-results+json-columns))
174
"Given a MESSAGE, and a STREAM with the application/sparql-results+json-columns CONTENT-TYPE, encode as json"
176
(let ((*package* *spocq-reader-package*))
177
(write-sparql-results+json-columns message-body stream))))
178
(typecase *encoding-trace-output*
182
(with-open-file (log *encoding-trace-output* :if-does-not-exist :create :if-exists :supersede :direction :output)
183
(setf stream (make-broadcast-stream log stream))
186
(setf stream (make-broadcast-stream *encoding-trace-output* stream))
192
(setq *encoding-trace-output* #p"/tmp/rabbit-log.json")
194
(write-sparql-results+json-columns '((?::a ?::s ?::z) (1 2 3) (<http://example/1> <http://example/2> <http://example/3>))
197
(write-sparql-results+json-columns 'spocq.a:|true| *trace-output*)
199
(send-response-message :test
200
'((?::a ?::s ?::z) (1 2 3) (<http://example/1> <http://example/2> <http://example/3>))
202
mime:application/sparql-results+json-columns)