Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/sparql-results-json-columns-streaming.lisp

KindCoveredAll%
expression6180 3.3
branch020 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; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 
5
 ;;; results+json serializer as streamed columns.
6
 ;;; each solution is a single vector. there is no column-name header, no count at the close,
7
 ;;; and no separator ',' between solutions as there is no outer object.
8
 ;;; ideosyncratic to dydra
9
 
10
 ;;; no reading
11
 
12
 
13
 ;;; writing - either boolean or bindings                             
14
 
15
 (defgeneric write-sparql-results+json-columns-streaming (results stream)
16
   (:documentation "Encode the result field to the stream as results+json.
17
  The results are a sequence of lists. Each is a solution set.
18
  There is _no_ header, and there is no separating ',' between the solution sets.
19
  If a variable is unbound, the solution element is nil.")
20
   
21
   (:method ((result symbol) (stream t))
22
     (write-string "[" stream)
23
     (encode-json-term result stream)
24
     (write-string "]" stream)
25
     (incf-stat *statements-returned*))
26
   
27
   (:method ((results cons) (stream t))
28
     (let* ((solutions (rest results))
29
            (index 0)
30
            (start (or (response-offset) 0))
31
            (end (response-end)))
32
       (dolist (result solutions)
33
         (when (>= index start)
34
           (when (and end (>= index end))
35
             (return))
36
           (write-char #\[ stream)
37
           (loop for value in result
38
                 for first = t then nil
39
                 do (progn (unless first
40
                             (write-string ", " stream))
41
                           (case value
42
                             ((nil etf:nil)
43
                              (write-string "{}" stream))
44
                             (t
45
                              (encode-json-term value stream)))))
46
           (write-char #\] stream))
47
         (incf index)
48
         (terpri stream))
49
       (incf-stat *statements-returned* index)))
50
   
51
   (:method ((results boolean-generator) (stream t))
52
     (let* ((channel (boolean-generator-channel results)))
53
       (write-string  "[" stream)
54
       (write-string (spocq:literal-lexical-form (if (get-field-page channel) spocq.a:|true| spocq.a:|false|)) stream)
55
       (write-string "]" stream)
56
       (incf-stat *statements-returned*)))
57
   
58
   (:method ((results solution-generator) (stream t))
59
     (let* ((dimensions (solution-generator-dimensions results))
60
            (channel (solution-generator-channel results))
61
            (variable-count (length dimensions))
62
            (index 0)
63
            (start (or (response-offset) 0))
64
            (end (response-end)))
65
       (flet ((term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
66
                (encode-json-term-aspects term-type term-literal term-language-tag term-datatype stream)))
67
         (declare (dynamic-extent #'term-aspect-encoder))
68
         (let ((term-deconstructor (repository-term-deconstructor *transaction*)))
69
           (do-pages (page channel)
70
             (if (and end (>= index end))
71
               (return)
72
               (if (>= (+ index (array-dimension page 0)) start)
73
                 (cond ((= variable-count (array-dimension page 1))
74
                        (dotimes (page-index (array-dimension page 0))
75
                          (when (>= index start)
76
                            (when (and end (>= index end))
77
                              (return))
78
                            (write-string "[" stream)
79
                            (loop for value-index from 0 below variable-count
80
                                  do (progn (unless (zerop value-index) (write-string ", " stream))
81
                                            (let ((term-id (aref page page-index value-index)))
82
                                              (cond ((= term-id +null-term-id+)
83
                                                     (write-string "{}" stream))
84
                                                    (t
85
                                                     (funcall term-deconstructor #'term-aspect-encoder *transaction* term-id))))))
86
                            (write-string "]" stream)
87
                            (terpri stream))
88
                          (incf index)))
89
                       (t
90
                        (log-warn "field width mismatch: ~s : ~s."
91
                                  dimensions (array-dimension page 1))
92
                        (incf index (array-dimension page 0))))
93
                 ; otherwise skip the entire page
94
                 (incf index (array-dimension page 0)))))))
95
       (incf-stat *statements-returned* index))))
96
 
97
 
98
 
99
 (defmethod send-error-message ((body t) (stream t) (content-type mime:application/sparql-results+json-columns-streaming))
100
   "Send an error response encoded as xml"
101
   (send-error-message body stream mime:application/sparql-query+sse))
102
 
103
 
104
 (defmethod send-response-message (operation (message-body t) (stream t)
105
                                             (content-type mime:application/sparql-results+json-columns-streaming))
106
   "Given a MESSAGE, and a STREAM with the application/sparql-results+json-columns CONTENT-TYPE, encode as json, streamed"
107
   (when *encoding-trace-output*
108
     (setf stream (make-broadcast-stream *encoding-trace-output* stream)))
109
   (let ((*package* *spocq-reader-package*))
110
     (write-sparql-results+json-columns-streaming message-body stream)))
111
 
112
 
113
 #|
114
 
115
 (write-sparql-results+json-columns-streaming '((?::a ?::s ?::z) (1 2 3) (<http://example/1> <http://example/2> <http://example/3>))
116
                                    *trace-output*)
117
 
118
 (write-sparql-results+json-columns 'spocq.a:|true| *trace-output*)
119
 
120
 (send-response-message :test
121
                        '((?::a ?::s ?::z) (1 2 3) (<http://example/1> <http://example/2> <http://example/3>))
122
                        *trace-output*
123
                        mime:application/sparql-results+json-columns-streaming)
124
 |#