Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/rdfhdt/result-encoding.lisp

KindCoveredAll%
expression0378 0.0
branch040 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
 (:documentation "SPOCQ rdfhdt extension"
6
                 "Encode results relative to HDT dataset dictionaries")
7
 
8
 (defun encode-json-hdt-term-number (%dictionary term-number stream)
9
   (let ((object (get-registry term-number (repository-store->spocq-term-registry *repository*))))
10
     (if object
11
         (encode-json-term object stream)
12
         (let ((literal (hdt:%term-number-term-literal %dictionary term-number)))
13
           (if (plusp (length literal))
14
               (case (char literal 0)
15
                 (#\" (encode-json-term (parse-term literal) stream))
16
                 (#\_ (format stream "{\"type\":\"bnode\", \"value\":\"~@[~a_~]~a\"}"
17
                              (blank-node-prefix)
18
                              (subseq literal 2)))
19
                 (t (format stream "{\"type\":\"uri\", \"value\":\"~/format-json-iri-namestring/\"}"
20
                            literal)))
21
               (write-string "{}" stream))))))
22
 
23
 (defmethod write-transaction-sparql-results-field+json ((transaction hdt-transaction) page variables stream &optional (index 0) (start 0) end)
24
   (assert (= (length (array-dimensions page)) 2) () "invalid result array dimensions: ~a" (array-dimensions page))
25
   (let* ((%environment (repository-hdt-environment transaction))
26
          (%dictionary (hdt:%hdt-get-dictionary %environment)))
27
     (dotimes (page-index (array-dimension page 0))
28
       (when (>= index start)
29
         (when (and end (>= index end))
30
           (return))
31
         (when (> index start)
32
           (write-char #\, stream))
33
         (format stream "~:[~;~%~] {" *print-pretty*)
34
         (loop for value-index from 0
35
           with first = t
36
           for name in variables
37
           do (let ((term-number (aref page page-index value-index)))
38
                (unless (= term-number +null-term-id+)
39
                  (if first (write-char #\space stream) (format stream ",~:[~;~%~]     " *print-pretty*))
40
                  (setf first nil)
41
                  (format stream "\"~a\": " name)
42
                  (encode-json-hdt-term-number %dictionary term-number stream))))
43
         (write-string " }" stream))
44
       (incf index)))
45
   index)
46
 
47
 (defmethod write-transaction-sparql-results-field+json-columns ((transaction hdt-transaction) page stream &optional (index 0) (start 0) end)
48
   (assert (= (length (array-dimensions page)) 2) () "invalid result array dimensions: ~a" (array-dimensions page))
49
   (let* ((variable-count (array-dimension page 1))
50
          (%environment (repository-hdt-environment transaction))
51
          (%dictionary (hdt:%hdt-get-dictionary %environment)))
52
     (dotimes (page-index (array-dimension page 0))
53
       (when (>= index start)
54
         (when (and end (>= index end))
55
           (return))
56
         (unless (= index start)
57
           (write-char #\, stream)
58
           (terpri stream))
59
         (write-string " [" stream)
60
         (loop for value-index from 0 below variable-count
61
           do (let ((term-number (aref page page-index value-index)))
62
                (unless (zerop value-index)
63
                  (write-string ", " stream)
64
                  (terpri stream))
65
                (cond ((= term-number +null-term-id+)
66
                       (write-string "{}" stream))
67
                      (t
68
                       (encode-json-hdt-term-number %dictionary term-number stream)))))
69
         (write-string "]" stream))
70
       (incf index)))
71
   index)
72
 
73
 (defmethod write-transaction-sparql-results+json-columns-streaming ((transaction hdt-transaction) (results solution-generator) (stream t))
74
   (let* ((%environment (repository-hdt-environment transaction))
75
          (%dictionary (hdt:%hdt-get-dictionary %environment))
76
          (dimensions (solution-generator-dimensions results))
77
          (channel (solution-generator-channel results))
78
          (variable-count (length dimensions))
79
          (index 0)
80
          (start (or (response-offset) 0))
81
          (end (response-end))
82
          (*expand-literal-values* t)
83
          (*encode-json-term.type-members* t))
84
     (do-pages (page channel)
85
               (if (and end (>= index end))
86
                   (return)
87
                   (if (>= (+ index (array-dimension page 0)) start)
88
                       (cond ((= variable-count (array-dimension page 1))
89
                              (dotimes (page-index (array-dimension page 0))
90
                                (when (>= index start)
91
                                  (when (and end (>= index end))
92
                                    (return))
93
                                  (write-string "[" stream)
94
                                  (loop for value-index from 0 below variable-count
95
                                    do (progn (unless (zerop value-index) (write-string ", " stream))
96
                                         (let ((term-number (aref page page-index value-index)))
97
                                           (cond ((= term-number +null-term-id+)
98
                                                  (write-string "{}" stream))
99
                                                 (t
100
                                                  (encode-json-hdt-term-number %dictionary term-number stream))))))
101
                                  (write-string "]" stream)
102
                                  (terpri stream))
103
                                (incf index)))
104
                             (t
105
                              (log-warn "field width mismatch: ~s : ~s."
106
                                        dimensions (array-dimension page 1))
107
                              (incf index (array-dimension page 0))))
108
                       ; otherwise skip the entire page
109
                       (incf index (array-dimension page 0)))))
110
     (incf-stat *statements-returned* index)))
111
 
112
 (defmethod write-sparql-results-transaction+jsonp ((transaction hdt-transaction) results stream &key operation)
113
   (let* ((%environment (repository-hdt-environment transaction))
114
          (%dictionary (hdt:%hdt-get-dictionary %environment))
115
          (dimensions (solution-generator-dimensions results))
116
          (channel (solution-generator-channel results))
117
          (base-width (length dimensions))
118
          (index 0)
119
          (start (or (response-offset) 0))
120
          (end (response-end))
121
          (terms (make-hash-table :test #'equalp)))
122
     (setf (gethash 0 terms) 0)
123
     (write-sparql-results+jsonp-prologue stream dimensions operation)
124
     (format stream "~%  \"rows\": [")
125
     (do-pages (page channel)
126
               (if (and end (>= index end))
127
                   (return)
128
                   (if (>= (+ index (array-dimension page 0)) start)
129
                       (cond ((= base-width (array-dimension page 1))
130
                              ;; this write just the term index references into the eventual table
131
                              (setf index (write-sparql-results-field+jsonp page dimensions stream terms index start end)))
132
                             (t
133
                              (log-warn "field width mismatch: ~s : ~s."
134
                                        dimensions (array-dimension page 1))
135
                              (incf index (array-dimension page 0))))
136
                       ; otherwise skip the entire page
137
                       (incf index (array-dimension page 0)))))
138
     (write-string "]," stream)
139
     ;; emit the remainder of the wrapper: type, prefixes and terms        "columns": ["g", "o", "p", "s"],
140
     (format stream "~%  \"terms\": [")
141
     (loop for (index . term-number) in (sort (loop for term being each hash-key of terms
142
                                                using (hash-value index)
143
                                                collect (cons index term))
144
                                              #'<
145
                                              :key #'first)
146
       for comma = nil then (write-string ", " stream)
147
       do (case term-number
148
            (-1 (write-string "{\"type\":\"uri\", \"value\":\"urn:dydra:default\"}" stream))
149
            (0 (write-string "null" stream))
150
            (t
151
             (encode-json-hdt-term-number %dictionary term-number stream))))
152
     (write-string "]," stream)
153
     (write-sparql-results+jsonp-epilogue stream *namespace-bindings* operation)
154
     (terpri stream)
155
     (incf-stat *statements-returned* index)
156
     index))
157