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

KindCoveredAll%
expression6021217 49.5
branch2954 53.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; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 
5
 (:documentation "terms"
6
   "data manipulation for terms")
7
 
8
 
9
 (defparameter *term-lock* nil)
10
 (defun term-lock ()
11
   (or *term-lock* (setf *term-lock* (bt:make-lock "fetch-term"))))
12
 
13
 (defmacro rdfcache-fetch-term (transaction-pointer term-number term-pointer)
14
   `(bt:with-lock-held ((term-lock)) (rdfcache:fetch-term* ,transaction-pointer ,term-number ,term-pointer)))
15
 
16
 
17
 (defun getcache (id table)
18
   (gethash id table))
19
 
20
 (defun setcache (id table value)
21
   (setf (gethash id table) value))
22
 
23
 
24
 ;;; generic interface
25
 
26
 ;;;
27
 ;;; term number<->object operators
28
 
29
 (defun term-datatype-id (term-number)
30
   (rlmdb:term-datatype-id term-number))
31
 
32
 (defun term-number-lang (term-number)
33
   (repository-term-number-lang (or *transaction* *repository*) term-number))
34
 
35
 (defun term-number-object (term-number)
36
   (repository-term-number-object (or *transaction* *repository*) term-number))
37
 
38
 (defun term-number-type (term-number)
39
   (repository-term-number-type (or *transaction* *repository*) term-number))
40
 
41
 (defun context-term-number (term)
42
   "return the term number for the current evaluation context with allowance
43
   for special context terms"
44
   (repository-context-term-number (or *transaction* *repository*) term))
45
 
46
 (defun object-term-number (object)
47
   "special-case true and false as results from intermediate operations"
48
   (case object
49
     ((t) (repository-object-term-number (or *transaction* *repository*) spocq.a:|true|))
50
     ((nil) (repository-object-term-number (or *transaction* *repository*) spocq.a:|false|))
51
     (t (repository-object-term-number (or *transaction* *repository*) object))))
52
 
53
 (defun lookup-object-term-number (object)
54
   "special-case trun and fals as results from intermediate operations"
55
   (case object
56
     ((t) (repository-lookup-object-term-number *transaction* spocq.a:|true|))
57
     ((nil) (repository-lookup-object-term-number *transaction* spocq.a:|false|))
58
     (t (repository-lookup-object-term-number *transaction* object))))
59
 
60
 (defun graph-term-number (term &key (allow-all nil))
61
   (repository-graph-term-number (or *transaction* *repository*) term :allow-all allow-all))
62
 
63
 (defgeneric repository-graph-term-number (transaction term &key allow-all)
64
   (:documentation
65
   "if the term designates the default graph return that special term number.
66
  Otherwise, if it designates either all or all named graphs, that is not a legitimate target.
67
  Otherwise, retrieve the term number.")
68
   (:method ((repository null) object &key (allow-all nil))
69
     (rlmdb:graph-term-number object :allow-all allow-all))
70
   (:method ((repository shard-repository) (object t) &key (allow-all nil))
71
     (rlmdb:graph-term-number object :allow-all allow-all))
72
   (:method ((transaction shard-transaction) (object t) &key (allow-all nil))
73
     (rlmdb:graph-term-number object :allow-all allow-all)))
74
 
75
 (defun intern-property-path (path)
76
   (repository-intern-property-path (or *transaction* *repository*) path))
77
 
78
 
79
 (defgeneric repository-object-term-number (repository object)
80
   (:argument-precedence-order object repository)
81
   (:method ((repository null) object)
82
     (rlmdb:value-term-number object))
83
   (:method ((repository shard-repository) (object t))
84
     (rlmdb:value-term-number object))
85
   (:method ((transaction shard-transaction) (object t))
86
     (rlmdb:value-term-number object)))
87
 
88
 (defgeneric repository-lookup-object-term-number (repository object)
89
   (:argument-precedence-order object repository)
90
   (:method ((repository null) object)
91
     (rlmdb:value-term-number object :if-does-not-exist nil))
92
   (:method ((repository shard-repository) (object t))
93
     (rlmdb:value-term-number object :if-does-not-exist nil))
94
   (:method ((transaction shard-transaction) (object t))
95
     (rlmdb:value-term-number object :if-does-not-exist nil)))
96
 
97
 (defgeneric repository-term-number-object (repository term-number)
98
   (:method ((repository null) (id t))
99
     (rlmdb:term-number-value id))
100
   (:method ((repository shard-repository) (id t))
101
     (rlmdb:term-number-value id))
102
   (:method ((transaction shard-transaction) (id t))
103
     (rlmdb:term-number-value id)))
104
 
105
 (defgeneric repository-term-number-lang (repository term-number)
106
   (:method ((repository null) (id t))
107
     (rlmdb:term-language id))
108
   (:method ((repository shard-repository) (id t))
109
     (rlmdb:term-language id))
110
   (:method ((transaction shard-transaction) (id t))
111
     (rlmdb:term-language id)))
112
 
113
 (defgeneric repository-term-number-object-list (repository term-number-list)
114
   (:method ((repository null) (id-list t))
115
     (loop for id in id-list
116
       collect (rlmdb:term-number-value id)))
117
   (:method ((repository shard-repository) (id-list list))
118
     (loop for id in id-list
119
       collect (rlmdb:term-number-value id)))
120
   (:method ((transaction shard-transaction) (id-list list))
121
     (loop for id in id-list
122
       collect (rlmdb:term-number-value id))))
123
 
124
 (defgeneric repository-term-number-type (repository term-number)
125
   (:method ((repository null) (term-number t))
126
     (rlmdb:term-type term-number))
127
   (:method ((repository shard-repository) (term-number t))
128
     (rlmdb:term-type term-number))
129
   (:method ((transaction shard-transaction) (term-number t))
130
     (rlmdb:term-type term-number)))
131
 
132
 (defgeneric repository-term-is-iri (repository term-number)
133
   (:method ((repository null) (id t))
134
     (rlmdb:term-is-iri id))
135
   (:method ((repository shard-repository) (id t))
136
     (rlmdb:term-is-iri id))
137
   (:method ((transaction shard-transaction) (id t))
138
     (rlmdb:term-is-iri id)))
139
 
140
 (defgeneric repository-term-is-blank-node (repository term-number)
141
   (:method ((repository null) (id t))
142
     (rlmdb:term-is-blank-node id))
143
   (:method ((repository shard-repository) (id t))
144
     (rlmdb:term-is-blank-node id))
145
   (:method ((transaction shard-transaction) (id t))
146
     (rlmdb:term-is-blank-node id)))
147
 
148
 
149
 ;;; rdfcache term management
150
 ;;; these do not cuse the complete shard term representation.
151
 ;;; the attributes are collected in just the type, literal, language and type fields
152
 
153
 (defgeneric compute-term-initializer (term-variable value)
154
   (:method (variable (object spocq:iri))
155
     (let* ((string (spocq:iri-lexical-form object))
156
            (string-var (gensym "STRING")))
157
       (values `(cffi:with-foreign-string (,string-var ,string))
158
               `((rdfcache:initialize-term ,variable :uri ,string-var :language nil :datatype nil)))))
159
 
160
   (:method (variable (object spocq:date))
161
     (let* ((string (term-lexical-form object))
162
            (string-var (gensym "STRING")))
163
       (values `(cffi:with-foreign-string (,string-var ,string))
164
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
165
                                           :datatype (datatype-foreign-string '|xsd|:|date|))))))
166
 
167
   (:method (variable (object spocq:date-time))
168
     (let* ((string (term-lexical-form object))
169
            (string-var (gensym "STRING")))
170
       (values `(cffi:with-foreign-string (,string-var ,string))
171
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
172
                                           :datatype (datatype-foreign-string '|xsd|:|dateTime|))))))
173
 
174
   (:method (variable (object spocq:time))
175
     (let* ((string (term-lexical-form object))
176
            (string-var (gensym "STRING")))
177
       (values `(cffi:with-foreign-string (,string-var ,string))
178
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
179
                                           :datatype (datatype-foreign-string '|xsd|:|time|))))))
180
 
181
   (:method (variable (object spocq:day-time-duration))
182
     (let* ((string (term-lexical-form object))
183
            (string-var (gensym "STRING")))
184
       (values `(cffi:with-foreign-string (,string-var ,string))
185
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
186
                                           :datatype (datatype-foreign-string '|xsd|:|dayTimeDuration|))))))
187
 
188
   (:method (variable (object spocq:duration))
189
     (let* ((string (term-lexical-form object))
190
            (string-var (gensym "STRING")))
191
       (values `(cffi:with-foreign-string (,string-var ,string))
192
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
193
                                           :datatype (datatype-foreign-string '|xsd|:|duration|))))))
194
 
195
   (:method (variable (object spocq:year-month-duration))
196
     (let* ((string (term-lexical-form object))
197
            (string-var (gensym "STRING")))
198
       (values `(cffi:with-foreign-string (,string-var ,string))
199
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
200
                                           :datatype (datatype-foreign-string '|xsd|:|yearMonthDuration|))))))
201
 
202
   (:method (variable (object spocq:date-interval))
203
     (let* ((string (term-lexical-form object))
204
            (string-var (gensym "STRING")))
205
       (values `(cffi:with-foreign-string (,string-var ,string))
206
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
207
                                           :datatype (datatype-foreign-string '|time|:|DateInterval|))))))
208
 
209
   (:method (variable (object spocq:date-time-interval))
210
     (let* ((string (term-lexical-form object))
211
            (string-var (gensym "STRING")))
212
       (values `(cffi:with-foreign-string (,string-var ,string))
213
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
214
                                           :datatype (datatype-foreign-string '|time|:|DateTimeInterval|))))))
215
 
216
   (:method (variable (object spocq:time-interval))
217
     (let* ((string (term-lexical-form object))
218
            (string-var (gensym "STRING")))
219
       (values `(cffi:with-foreign-string (,string-var ,string))
220
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
221
                                           :datatype (datatype-foreign-string '|time|:|TimeInterval|))))))
222
 
223
 
224
   (:method (variable (object spocq:blank-node))
225
     (let* ((string (spocq:blank-node-label object))
226
            (string-var (gensym "STRING")))
227
       (values `(cffi:with-foreign-string (,string-var ,string))
228
               `((rdfcache:initialize-term ,variable :node ,string-var :language nil :datatype nil)))))
229
 
230
   (:method (variable (object symbol))
231
     (let ((uri-namestring (symbol-uri-namestring object))
232
           (string-var (gensym "STRING")))
233
       (cond (uri-namestring
234
              (values `(cffi:with-foreign-strings ((,string-var ,uri-namestring)))
235
                      `((rdfcache:initialize-term ,variable :uri ,string-var :language nil :datatype nil))))
236
             (t
237
              (error "Attempt to initialize a term from an invalid symbol: ~s." object)))))
238
 
239
   (:method (variable (object spocq:plain-literal))
240
     (let ((language-tag (string-downcase (spocq:plain-literal-language-tag object)))
241
           (language-var (gensym "LANGUAGE"))
242
           (string (spocq:literal-lexical-form object))
243
           (string-var (gensym "STRING")))
244
       (values `(cffi:with-foreign-strings ((,string-var ,string) (,language-var ,language-tag)))
245
               `((rdfcache:initialize-term ,variable :literal ,string-var :language ,language-var :datatype nil)))))
246
 
247
   (:method (variable (object string))
248
     (let ((string-var (gensym "STRING")))
249
       (values `(cffi:with-foreign-string (,string-var ,object))
250
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
251
                                           :datatype ,(datatype-foreign-string '|xsd|:|string|)
252
                                           ;; :datatype nil
253
                                           )))))
254
 
255
   (:method (variable (object spocq:atomic-typed-literal))
256
     (let ((string (term-lexical-form object))
257
           (string-var (gensym "STRING"))
258
           (datatype-string (iri-lexical-form (spocq:literal-datatype-uri object)))
259
           (datatype-var (gensym "DATATYPE")))
260
       (values `(cffi:with-foreign-strings ((,string-var ,string) (,datatype-var ,datatype-string)))
261
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil :datatype ,datatype-var)))))
262
 
263
   (:method (variable (object spocq:unsupported-typed-literal))
264
     (let ((string (spocq:literal-lexical-form object))
265
           (string-var (gensym "STRING"))
266
           (datatype-string (iri-lexical-form (spocq:unsupported-typed-literal-datatype-uri object)))
267
           (datatype-var (gensym "DATATYPE")))
268
       (values `(cffi:with-foreign-strings ((,string-var ,string) (,datatype-var ,datatype-string)))
269
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil :datatype ,datatype-var)))))
270
 
271
   #-rdfcache-native-integers
272
   (:method (variable (object integer))
273
     (let ((string (format nil "~f" object))
274
           (string-var (gensym "STRING")))
275
       (values `(cffi:with-foreign-string (,string-var ,string))
276
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
277
                                           :datatype ,(datatype-foreign-string '|xsd|:|decimal|))))))
278
 
279
   #+rdfcache-native-integers
280
   (:method (variable (object integer))
281
     (let ((string (princ-to-string object))
282
           (string-var (gensym "STRING")))
283
       (values `(cffi:with-foreign-string (,string-var ,string))
284
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
285
                                           :datatype ,(datatype-foreign-string '|xsd|:|integer|))))))
286
 
287
   (:method (variable (object double-float))
288
     (if (or (eq object dsu.codecs:double-float-nan)
289
             (eq object dsu.codecs:double-float-positive-infinity)
290
             (eq object dsu.codecs:double-float-negative-infinity))
291
       (error "Invalid float value: ~a" object)
292
       (let* ((*read-default-float-format* 'double-float)
293
              (string (xsd-lexical-representation object))
294
              (string-var (gensym "STRING")))
295
         (values `(cffi:with-foreign-string (,string-var ,string))
296
                 `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
297
                                    :datatype ,(datatype-foreign-string '|xsd|:|double|)))))))
298
 
299
   (:method (variable (object single-float))
300
     (if (or (eq object nan) (eq object +inf) (eq object -inf))
301
       (error "Invalid float value: ~a" object)
302
       (let* ((*read-default-float-format* 'single-float)
303
              (string (xsd-lexical-representation object))
304
              (string-var (gensym "STRING")))
305
         (values `(cffi:with-foreign-string (,string-var ,string))
306
                 `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
307
                                    :datatype ,(datatype-foreign-string '|xsd|:|float|)))))))
308
 
309
   (:method (variable (object rational))
310
     (let* ((*read-default-float-format* 'single-float)
311
            ;;(string (format nil "~d/~d" (numerator object) (denominator object)))
312
            (string (format nil "~f" (float object 1.0s0)))
313
            (string-var (gensym "STRING")))
314
       (values `(cffi:with-foreign-string (,string-var ,string))
315
               `((rdfcache:initialize-term ,variable :literal ,string-var :language nil
316
                                  :datatype ,(datatype-foreign-string '|xsd|:|decimal|)))))))
317
 
318
 
319
 (undefun rdfcache-constrain-string-length (string)
320
   "constrain the string to be of a length less than any configured limit."
321
   (cond ((and *rdf-string-length-maximum*
322
               (> (length string) *rdf-string-length-maximum*))
323
          (log-error "string ~s exceeds length limit of ~s"
324
                     (type-of string) *rdf-string-length-maximum*)
325
          (error "string ~s exceeds length limit of ~s"
326
                 (type-of string) *rdf-string-length-maximum*))
327
         (t
328
          string)))
329
 
330
 (defun rdfcache-intern-object (%transaction-record object)
331
   (if (spocq::unbound-variable-p object)
332
     ;; guard against cases where compiled operations do not preclude this
333
     0
334
     (with-term-record (%term)
335
       ;; proactively clear - otherwise the unwind may fail on initial content
336
       (rdfcache::%clear-term %term)
337
       ;; apply any constraints
338
       (typecase object
339
         (string (constrain-string-length object)))
340
       (unwind-protect
341
         (progn (set-optional-term %term object)
342
                ;; (print-term-strings %term)
343
                (if (integerp object)
344
                  (flet ((when-plusp (number)
345
                           (when (and (integerp number) (plusp number)) number)))
346
                    ;; implicitly promote int/integer to rational
347
                    (or (when-plusp (rdfcache:lookup-term %transaction-record
348
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
349
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
350
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
351
                                                          (datatype-foreign-string '|xsd|:|integer|)))
352
                        #+(or) ;; do not promote integers to decimal
353
                        (when-plusp (rdfcache:lookup-term %transaction-record
354
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
355
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
356
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
357
                                                          (datatype-foreign-string '|xsd|:|decimal|)))
358
                        (when-plusp (rdfcache:lookup-term %transaction-record
359
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
360
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
361
                                                          (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
362
                                                          (datatype-foreign-string '|xsd|:|int|)))
363
                        (rdfcache:intern-term %transaction-record
364
                                              (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
365
                                              (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
366
                                              (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
367
                                              (datatype-foreign-string '|xsd|:|integer|))))
368
                  (rdfcache:intern-term %transaction-record
369
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
370
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
371
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
372
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype))))
373
         (clear-optional-term %term)))))
374
 
375
 
376
 (defgeneric rdfcache-object-term-number (context object)
377
   (:documentation "given a context and a term, return the current term number respective the context.
378
  If the context is a transaction and the term is not yet in the store, this entails generating a
379
  transaction-relative ephemeral term number. If the context is null, then either return the number for an
380
  existing term or signal an error. see also rdfcache-lookup-object-term-number, which returns nil in that case.")
381
   (:argument-precedence-order object context)
382
 
383
   (:method ((repository rdfcache-repository) (object t))
384
     (rdfcache-object-term-number *transaction* object))
385
 
386
   (:method ((context null) (object t))
387
     ;; w/o transaction do a context-free lookup
388
     (or (rdfcache-find-object-term-number object)
389
         (error "unknown term: ~s." object)))
390
 
391
   (:method ((context rdfcache-transaction) (object t))
392
     (or (gethash object *spocq->store-term-registry*)
393
         (setf (gethash object *spocq->store-term-registry*)
394
               (rdfcache-intern-object (transaction-record context) object))))
395
   
396
   (:method ((context t) (object t))
397
     (or (gethash object *spocq->store-term-registry*)
398
         (let ((term-number (rdfcache-intern-object context object)))
399
           ;; do not cache the mapping for ephemeral terms
400
           (when (> term-number 0)
401
             (setcache object *spocq->store-term-registry* term-number)
402
             (setcache term-number *store->spocq-term-registry* object))
403
           term-number)))
404
 
405
   (:method ((context t) (object symbol))
406
     (or (symbol-term-id object)
407
         (call-next-method)))
408
 
409
   (:method (context (object spocq:term))
410
     (or (spocq:term-id object)
411
         (let ((term-number (rdfcache-intern-object (transaction-record context) object)))
412
           (if (> term-number 0)       ; cache persistent identifiers only
413
             (setf (spocq:term-id object) term-number)
414
             term-number))))
415
   (:method (context (object spocq:unbound-variable))
416
     0))
417
 
418
 (defun rdfcache-find-object-term-number (object)
419
   (rdfcache-lookup-object-term-number object))
420
 
421
 
422
 (defgeneric rdfcache-lookup-object-term-number (object)
423
   (:documentation "given a term, return the global term number in the store.
424
    if the term is not found in the global dictionary, return nil for constants
425
    and 0 for wildcards.")
426
 
427
   (:method ((object t))
428
     ;; do a context-free lookup
429
     (or (gethash object *spocq->store-term-registry*)
430
         (let ((term-number (with-term-record (%term)
431
                              (unwind-protect
432
                                (progn (set-optional-term %term object) 
433
                                       ;; (print-term-strings %term)
434
                                       (rdfcache:lookup-term-number %term)
435
                                       #+(or)         ; until null context is implemented
436
                                       (rdfcache:lookup-term nil
437
                                                             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
438
                                                             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
439
                                                             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
440
                                                             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype)))
441
                                (clear-optional-term %term)))))
442
           (when term-number
443
             (setf (gethash object *spocq->store-term-registry*) term-number))
444
           term-number)))
445
 
446
   (:method ((object spocq:term))
447
     (or (spocq:term-id object)
448
         (let ((term-number (call-next-method)))
449
           (when term-number       ; cache persistent identifiers only
450
             (setf (spocq:term-id object) term-number)
451
             term-number))))
452
 
453
   (:method ((object null))
454
     0)
455
   (:method ((object spocq:unbound-variable))
456
     0))
457
 
458
 (defun rdfcache-lookup-object-term-number! (object)
459
   (with-term-record (%term)
460
     (unwind-protect
461
         (progn (set-optional-term %term object) 
462
           ;; (print-term-strings %term)
463
           (rdfcache:lookup-term-number %term))
464
       (clear-optional-term %term))))
465
 
466
 
467
 (defmethod store-context ((transaction rdfcache-transaction))
468
   (transaction-record transaction))
469
 
470
 
471
 
472
 
473
 
474
 (undefun rdfcache-call-with-numbered-term (operator context term-number)
475
   (declare (dynamic-extent operator))
476
   #|(declare (type (function (t) t) operator)
477
            (type fixnum term-number))
478
   (assert (typep operator 'function) () "Invalid operator: ~s." operator)
479
   (assert (typep term-number 'fixnum) () "Invalid term number: ~s." term-number)|#
480
   (cond ((or (= term-number 0) (= term-number -1))
481
          (with-term-record (%term)
482
            (rdfcache::%clear-term %term)
483
            (funcall operator %term)))
484
         (context
485
          (etypecase context
486
            (rdfcache-transaction (setf context (transaction-record context)))
487
            (cffi:foreign-pointer ))
488
          (with-term-record (%term)
489
            (rdfcache:fetch-term* context term-number %term)
490
            (funcall operator %term)))
491
         (t
492
          (with-term-record (%term)
493
            (rdfcache:fetch-term term-number %term)
494
            (funcall operator %term)))))
495
 
496
 (undefun rdfcache-call-with-numbered-term-aspects (operator context term-number)
497
   (declare (dynamic-extent operator))
498
   #|(declare (type (function (t t t t) t) operator)
499
            (type fixnum term-number))
500
   (assert (typep operator 'function) () "Invalid operator: ~s." operator)
501
   (assert (typep term-number 'fixnum) () "Invalid term number: ~s." term-number)|#
502
   (if (or (rdfcache:ephemeral-term-number-p term-number)
503
           (rdfcache:persistent-term-number-p term-number))
504
     (if (setf context (transaction-record context))
505
       (with-term-record (%term)
506
            (rdfcache:fetch-term* context term-number %term)
507
            (funcall operator
508
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
509
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
510
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
511
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype)))
512
       (with-term-record (%term)
513
            (rdfcache:fetch-term term-number %term)
514
            (funcall operator
515
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
516
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
517
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
518
                     (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype))))
519
     ;; treat an internal term number as the 'null' term
520
     (with-term-record (%term)
521
       (rdfcache::%clear-term %term)
522
       (funcall operator
523
                (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
524
                (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
525
                (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
526
                (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype)))))
527
 
528
 (undefmethod repository-call-with-numbered-term-aspects (operator (transaction rdfcache-transaction) term-number)
529
   (rdfcache-call-with-numbered-term-aspects operator transaction term-number))
530
 
531
 (undefmethod repository-term-deconstructor ((context rdfcache-transaction))
532
   #'rdfcache-call-with-numbered-term-aspects)
533
 
534
 (undefun rdfcache-term-number-object-p (expression)
535
   (and (consp expression)
536
        (eq (first expression) 'rdfcache-term-number-object)))
537
 
538
 ;; (rdfcache-call-with-numbered-term #'print-term-strings nil 829)
539
 
540
 (undefgeneric repository-typed-term-number-object (context number datatype-id)
541
   (:documentation
542
     "Retrieve the data model value for the given (term-number x datatype-term-id) combination.
543
     This will include methods specialized for the immediate typed, which avoid parsing
544
     and interning.")
545
   (:argument-precedence-order datatype-id context number)
546
   (:method ((context t) (number t) (datatype-id t))
547
     "The default method, to be used when nothing is defined for the given datatype id,
548
      uses the generic logic to intern the term and manage a cache of the interned values."
549
     (or (get-registry number *store->spocq-term-registry*)
550
         (repository-cache-term-number-object context number))))
551
 
552
 (undefun repository-cache-term-number-object (context number)
553
   (let ((object (repository-term-number-object context number)))
554
     (cond ((and (spocq:term-p object) (> number 0))
555
            (setf (spocq:term-id object) number)
556
            (setf (get-registry number *store->spocq-term-registry*) object))
557
           ((> number 0)
558
            (setf (get-registry number *store->spocq-term-registry*) object))
559
           (t
560
            object))))
561
 
562
 (defparameter *intern-datatype-operators*
563
   '((|http://www.w3.org/2001/XMLSchema|:|boolean| :term-value-as-boolean)
564
     (|http://www.w3.org/2001/XMLSchema|:|byte| :term-value-as-int32)
565
     (|http://www.w3.org/2001/XMLSchema|:|decimal| :term-value-as-decimal)
566
     (|http://www.w3.org/2001/XMLSchema|:|double| :term-value-as-double)
567
     (|http://www.w3.org/2001/XMLSchema|:|float| :term-value-as-float)
568
     (|http://www.w3.org/2001/XMLSchema|:|int| :term-value-as-int32)
569
     (|http://www.w3.org/2001/XMLSchema|:|integer| :term-value-as-integer)
570
     (|http://www.w3.org/2001/XMLSchema|:|long| :term-value-as-int64)
571
     (|http://www.w3.org/2001/XMLSchema|:|nonNegativeInteger| :term-value-as-integer)
572
     (|http://www.w3.org/2001/XMLSchema|:|nonPositiveInteger| :term-value-as-integer)
573
     (|http://www.w3.org/2001/XMLSchema|:|negativeInteger| :term-value-as-integer)
574
     (|http://www.w3.org/2001/XMLSchema|:|positiveInteger| :term-value-as-integer)
575
     (|http://www.w3.org/2001/XMLSchema|:|short| :term-value-as-int16)
576
     (|http://www.w3.org/2001/XMLSchema|:|unsignedByte| :term-value-as-int8)
577
     (|http://www.w3.org/2001/XMLSchema|:|unsignedInt| :term-value-as-uint32)
578
     (|http://www.w3.org/2001/XMLSchema|:|unsignedLong| :term-value-as-uint64)
579
     (|http://www.w3.org/2001/XMLSchema|:|unsignedShort| :term-value-as-uint16)
580
 
581
     ;; temporal values
582
     ;; not yet (|http://www.w3.org/2001/XMLSchema|:|date| term-value-as-date-from-int64)
583
     (|http://www.w3.org/2001/XMLSchema|:|dateTime| term-value-as-date-time-from-int64)
584
     (|http://www.w3.org/2001/XMLSchema|:|time| term-value-as-time-from-int64)
585
     ))
586
 
587
 
588
 (defun term-value-as-date-from-int64 (number)
589
   (let ((value (rlmdb:term-number-value number)))
590
     (assert (spocq:date-p value) ()
591
             "invalid date term: ~s: ~s" number value)
592
     value))
593
 
594
 (defun term-value-as-date-time-from-int64 (number)
595
   (let ((value (rlmdb:term-number-value number)))
596
     (assert (spocq:date-time-p value) ()
597
             "invalid date-time term: ~s: ~s" number value)
598
     value))
599
 
600
 (defun term-value-as-time-from-int64 (number)
601
   (let ((value (rlmdb:term-number-value number)))
602
     (assert (spocq:time-p value) ()
603
             "invalid time term: ~s: ~s" number value)
604
     value))
605
 
606
 
607
 (undefun define-rdfcache-typed-term-number-object-methods ()
608
   ;; runs at store initialization 
609
   ;; remove old ones
610
   (loop for method in (copy-list (c2mop:generic-function-methods #'rdfcache-typed-term-number-object))
611
     do (when (typep (third (c2mop:method-specializers method)) 'c2mop:eql-specializer)
612
          (remove-method #'rdfcache-typed-term-number-object method)))
613
   ;; add new ones
614
   (loop for (datatype-uri operator-name) in *intern-datatype-operators*
615
         for datatype-id = (symbol-term-id datatype-uri)
616
         for interned-operator-name = (or (find-symbol (string operator-name) :spocq.i)
617
                                          (find-symbol (string operator-name) :dydra-ndk))
618
         if interned-operator-name
619
         do (eval `(defmethod rdfcache-typed-term-number-object ((context t) (number t) (datatype-id (eql ,datatype-id)))
620
                     (or ;; (,interned-operator-name number :junk-allowed t)
621
                      (,interned-operator-name number)
622
                      (call-next-method))))
623
         else do (warn "unimplemented native datatype: ~s ~s" datatype-uri operator-name)))
624
 
625
 (undefun compute-rdfcache-typed-term-number-object-methods ()
626
   (loop for (datatype-uri operator-name) in *intern-datatype-operators*
627
         for datatype-id = (symbol-term-id datatype-uri)
628
         for interned-operator-name = (or (find-symbol (string operator-name) :spocq.i)
629
                                          (find-symbol (string operator-name) :dydra-ndk))
630
         if interned-operator-name
631
         collect `(defmethod rdfcache-typed-term-number-object ((context t) (number t) (datatype-id (eql ,datatype-id)))
632
                     (or ;; (,interned-operator-name number :junk-allowed t)
633
                      (,interned-operator-name number)
634
                      (call-next-method)))
635
         else do (warn "unimplemented native datatype: ~s ~s" datatype-uri operator-name)))
636
 
637
 
638
 (defun clear-optional-term (%term)
639
   "When the term was initialized, the fields may have heap values which should have dynamic extent. If so
640
  free and clear these fields. If the value is a registered foreign string - as for datatyes, then
641
  just clear the field"
642
 
643
   (unless (eq :none (rdfcache:term-type %term))
644
     (contingently-foreign-free (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value))
645
     (contingently-foreign-free (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language))
646
     (contingently-foreign-free (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype))
647
     (setf (rdfcache:term-type %term) :none)
648
     (rdfcache::%clear-term %term))
649
   %term)
650
 
651
 (defun make-rdfcache-term (object)
652
   (let ((%term (cffi:foreign-alloc 'rdfcache::term)))
653
     (set-optional-term %term object)
654
     %term))
655
 
656
 (defgeneric set-optional-term (term value)
657
   (:method (term (object spocq:unbound-variable))
658
     (rdfcache::%clear-term term))
659
 
660
   (:method (term (object spocq:blank-node))
661
     (let* ((string (spocq:blank-node-label object)))
662
              (rdfcache:initialize-term term :node (cffi:foreign-string-alloc string) :language nil :datatype nil))
663
     term)
664
 
665
   (:method (term (object spocq:boolean))
666
     (let* ((string (term-lexical-form object)))
667
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
668
                                  :language nil
669
                                  :datatype (datatype-foreign-string '|xsd|:|boolean|)))
670
     term)
671
 
672
   (:method (term (object spocq:date))
673
     (let* ((string (if (offset-zone-p (date-zone object))
674
                        (with-output-to-string (stream) (spocq:format-date stream object))
675
                        (term-lexical-form object))))
676
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
677
                                 :language nil
678
                                 :datatype (datatype-foreign-string '|xsd|:|date|)))
679
     term)
680
 
681
   (:method (term (object spocq:date-time))
682
     (let* ((string (if (offset-zone-p (date-time-zone object))
683
                        (with-output-to-string (stream) (spocq:format-date-time stream object))
684
                        (term-lexical-form object))))
685
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
686
                                  :language nil
687
                                  :datatype (datatype-foreign-string '|xsd|:|dateTime|)))
688
     term)
689
 
690
   (:method (term (object spocq:day-time-duration))
691
     (let* ((string (term-lexical-form object))) ; no zone offset
692
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
693
                                 :language nil
694
                                 :datatype (datatype-foreign-string '|xsd|:|dayTimeDuration|)))
695
     term)
696
 
697
   (:method (term (object spocq:date-interval))
698
     (let* ((string (term-lexical-form object)))
699
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
700
                                  :language nil
701
                                  :datatype (datatype-foreign-string '|time|:|DateInterval|)))
702
     term)
703
 
704
   (:method (term (object spocq:date-time-interval))
705
     (let* ((string (term-lexical-form object)))
706
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
707
                                  :language nil
708
                                  :datatype (datatype-foreign-string '|time|:|DateTimeInterval|)))
709
     term)
710
 
711
   (:method (term (object spocq:duration))
712
     (let* ((string (term-lexical-form object))) ; no zone offset
713
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
714
                                 :language nil
715
                                 :datatype (datatype-foreign-string '|xsd|:|duration|)))
716
     term)
717
 
718
   (:method (term (object spocq:g-day))
719
     (let* ((string (if (offset-zone-p (g-day-zone object))
720
                        (with-output-to-string (stream) (spocq:format-g-day stream object nil t spocq:+reference-zone+))
721
                        (term-lexical-form object))))
722
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
723
                                 :language nil
724
                                 :datatype (datatype-foreign-string '|xsd|:|gDay|)))
725
     term)
726
 
727
   (:method (term (object spocq:g-month))
728
     (let* ((string (if (offset-zone-p (g-month-zone object))
729
                        (with-output-to-string (stream) (spocq:format-g-month stream object nil t spocq:+reference-zone+))
730
                        (term-lexical-form object))))
731
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
732
                                 :language nil
733
                                 :datatype (datatype-foreign-string '|xsd|:|gMonth|)))
734
     term)
735
 
736
   (:method (term (object spocq:g-month-day))
737
     (let* ((string (if (offset-zone-p (g-month-day-zone object))
738
                        (with-output-to-string (stream) (spocq:format-g-month-day stream object nil t spocq:+reference-zone+))
739
                        (term-lexical-form object))))
740
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
741
                                 :language nil
742
                                 :datatype (datatype-foreign-string '|xsd|:|gMonthDay|)))
743
     term)
744
 
745
   (:method (term (object spocq:g-year))
746
     (let* ((string (if (offset-zone-p (g-year-zone object))
747
                        (with-output-to-string (stream) (spocq:format-g-year stream object nil t spocq:+reference-zone+))
748
                        (term-lexical-form object))))
749
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
750
                                 :language nil
751
                                 :datatype (datatype-foreign-string '|xsd|:|gYear|)))
752
     term)
753
   
754
   (:method (term (object spocq:g-year-month))
755
     (let* ((string (if (offset-zone-p (g-year-month-zone object))
756
                        (with-output-to-string (stream) (spocq:format-g-year-month stream object nil t spocq:+reference-zone+))
757
                        (term-lexical-form object))))
758
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
759
                                 :language nil
760
                                 :datatype (datatype-foreign-string '|xsd|:|gYearMonth|)))
761
     term)
762
   
763
   (:method (term (object spocq:time))
764
     (let* ((string (if (offset-zone-p (time-zone object))
765
                        (with-output-to-string (stream) (spocq:format-time stream object nil t spocq:+reference-zone+))
766
                        (term-lexical-form object))))
767
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
768
                                  :language nil
769
                                  :datatype (datatype-foreign-string '|xsd|:|time|)))
770
     term)
771
 
772
   (:method (term (object spocq:time-interval))
773
     (let* ((string (term-lexical-form object)))
774
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
775
                                  :language nil
776
                                  :datatype (datatype-foreign-string '|time|:|TimeInterval|)))
777
     term)
778
 
779
   (:method (term (object spocq:year-month-duration))
780
     (let* ((string (term-lexical-form object))) ; no zone offset
781
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
782
                                  :language nil
783
                                  :datatype (datatype-foreign-string '|xsd|:|yearMonthDuration|)))
784
     term)
785
 
786
   (:method (term (object spocq:iri))
787
     (let* ((string (spocq:iri-lexical-form object)))
788
       (rdfcache:initialize-term term :uri (cffi:foreign-string-alloc string) :language nil :datatype nil))
789
     term)
790
 
791
   (:method (term (object symbol))
792
     (case object
793
       ((nil) (set-optional-term term spocq.a:|false|))
794
       ((t) (set-optional-term term spocq.a:|true|))
795
       (t
796
        (let ((uri-namestring (symbol-uri-namestring object)))
797
          (cond (uri-namestring
798
                 (rdfcache:initialize-term term :uri (cffi:foreign-string-alloc uri-namestring) :language nil :datatype nil))
799
                (t
800
                 (rdfcache::%clear-term term)
801
                 (error "Attempt to initialize a term from an invalid symbol: ~s." object))))
802
        term)))
803
 
804
   (:method (term (object spocq:plain-literal))
805
     (let ((language-tag (string-downcase (spocq:plain-literal-language-tag object)))
806
           (string (spocq:literal-lexical-form object)))
807
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
808
                                 :language (cffi:foreign-string-alloc language-tag)
809
                                 :datatype nil ;; (datatype-foreign-string '|rdf|:|langString|)
810
                                 ))
811
     term)
812
 
813
   (:method (term (object string))
814
     (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc object)
815
                               :language nil
816
                               :datatype  (datatype-foreign-string '|xsd|:|string|)
817
                               ;; :datatype  (cffi:foreign-string-alloc (symbol-uri-namestring |xsd|:|string|))
818
                               )
819
     term)
820
 
821
   (:method (term (object spocq:atomic-typed-literal))
822
     (let ((string (term-lexical-form object))
823
           (datatype-string (iri-lexical-form (spocq:literal-datatype-uri object))))
824
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
825
                                 :language nil
826
                                 :datatype (cffi:foreign-string-alloc datatype-string)))
827
     term)
828
 
829
  (:method (term (object spocq:unsupported-typed-literal))
830
     (let ((string (spocq:literal-lexical-form object))
831
           (datatype-string (iri-lexical-form (spocq:unsupported-typed-literal-datatype-uri object))))
832
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string)
833
                                 :language nil
834
                                 :datatype (cffi:foreign-string-alloc datatype-string)))
835
     term)
836
 
837
   #-rdfcache-native-integers
838
   (:method (term (object integer))
839
     (let ((string (spocq.e:string object))) ; do not format directly to avoid problem with 0.0 
840
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string) :language nil
841
                                 :datatype (datatype-foreign-string |xsd|:|decimal|)))
842
     term)
843
 
844
   #+rdfcache-native-integers
845
   (:method (term (object integer))
846
     (let ((string (princ-to-string object)))
847
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string) :language nil
848
                                 :datatype (datatype-foreign-string |xsd|:|integer|)))
849
     term)
850
 
851
   (:method (term (object double-float))
852
     (cond ((or *permit-float-special-values*
853
                (not (or (eql object dsu.codecs:double-float-nan)
854
                         (eql object dsu.codecs:double-float-positive-infinity)
855
                         (eql object dsu.codecs:double-float-negative-infinity))))
856
            (let* ((*read-default-float-format* 'double-float)
857
                   (string (xsd-lexical-representation object)))
858
              (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string) :language nil
859
                                        :datatype (datatype-foreign-string '|xsd|:|double|))))
860
           (t
861
            (rdfcache::%clear-term term)
862
            (error "Invalid float value: ~a" object)))
863
     term)
864
 
865
   (:method (term (object single-float))
866
     (cond ((or *permit-float-special-values*
867
                (not (or (eql object nan) (eql object +inf) (eq object -inf))))
868
            (let* ((*read-default-float-format* 'single-float)
869
                   (string (xsd-lexical-representation object)))
870
              (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string) :language nil
871
                                        :datatype (datatype-foreign-string '|xsd|:|float|))))
872
           (t
873
            (rdfcache::%clear-term term)
874
            (error "Invalid float value: ~a" object)))
875
     term)
876
 
877
   (:method (term (object rational))
878
     (let* ((*read-default-float-format* 'single-float)
879
            ;; (string (format nil "~d/~d" (numerator object) (denominator object)))
880
            ;; special case test for unit denominator which woudl cause the float operator
881
            ;; to fail for sbcl
882
            (string (format nil "~f" (float object 1.0s0))))
883
       (rdfcache:initialize-term term :literal (cffi:foreign-string-alloc string) :language nil
884
                                  :datatype (datatype-foreign-string '|xsd|:|decimal|)))
885
     term))
886
 
887
 #+(or)
888
 (defun call-with-term-string (op %term-string)
889
   "use rdfcache decoder to handle utf8 decoding."
890
   (declare (type rdfcache::foreign-pointer %term-string))
891
   (let* ((intended-count (rdfcache::%%utf8-get-length %term-string))
892
          (result-string (make-string intended-count)))
893
     (sb-sys:with-pinned-objects (result-string)
894
       (cffi:with-pointer-to-vector-data (%buffer result-string)
895
         (let ((count (rdfcache::%%utf8-to-utf32 %term-string -1 %buffer (* intended-count 4))))
896
           (assert (= count intended-count) ()
897
                   "Decoded length != counted length: ~d != ~d: ~s." count intended-count result-string))
898
         (funcall op result-string)))))
899
 (defun call-with-term-string (op %term-string)
900
     (declare (type rdfcache::foreign-pointer %term-string))
901
     (let ((string (cffi:foreign-string-to-lisp %term-string)))
902
       (funcall op string)))
903
 
904
 (defun intern-term (%term)
905
   ;; (print-term %term)
906
   (assert (rdfcache::pointerp %term) ()
907
           "Invalid term pointer: ~a." %term)
908
   (with-term-attributes (type literal language-tag datatype) %term
909
     ; (print (list type literal language-tag datatype))
910
     (when (integerp type)
911
       (setf type (ecase type (0 :none) (1 :uri) (2 :node) (5 :literal) (255 :id))))
912
     (intern-term-aspects type literal datatype language-tag)))
913
 
914
 
915
 (defun call-with-term-number-type (op term-number)
916
   (declare (dynamic-extent op))
917
   (funcall op (term-number-type term-number)))
918
 
919
 
920
 (defun print-term (%term &optional (stream *standard-output*))
921
   (print-unreadable-object (%term stream :identity nil :type nil)
922
     (format stream "%term ~8,'0x: type ~s value ~s language ~s datatype ~s"
923
             (cffi:pointer-address %term)
924
             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
925
             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
926
             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
927
             (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype))))
928
 
929
 (defun print-term-strings (%term &optional (stream *standard-output*))
930
   (terpri stream)
931
   (print-unreadable-object (%term stream :identity nil :type nil)
932
     (flet ((string-or-nll (ptr)
933
              (unless (cffi:null-pointer-p ptr)
934
                (cffi:foreign-string-to-lisp ptr))))
935
       (flet ((print-it (%term)
936
                (format stream "~8,'0x: type ~s value ~s language ~s datatype ~s"
937
                        (cffi:pointer-address %term)
938
                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
939
                        (string-or-nll (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value))
940
                        (string-or-nll (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language))
941
                        (string-or-nll (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype)))))
942
         (typecase %term
943
           (null )
944
           (integer (format stream "~8,'0x: ~s" %term (rlmdb:term-elements %term)))
945
           (cffi:foreign-pointer (print-it %term)))))))
946
 
947
 (defgeneric print-term-number-strings (repository-designator term-number)
948
   (:method ((repository shard-transaction) (term-number integer))
949
     (format *standard-output* "~8,'0x: ~s" term-number (rlmdb:term-elements term-number)))
950
   (:method ((repository shard-repository) (term-number integer))
951
     (format *standard-output* "~8,'0x: ~s" term-number (rlmdb:term-elements term-number))))
952
 
953
 
954
 #+(or)
955
 (let ((literal-tagged "w/lang")
956
       (literal-typed "w/type"))
957
   (setf (literal-language-tag literal-tagged) "EN")
958
   (setf (literal-datatype literal-typed) |xsd|:|anyURI|)
959
   
960
   (let ((*print-case* :downcase))
961
     (pprint
962
      (macroexpand-1
963
       `(with-terms ((symbol-datatype-term |xsd|:|anyURI|)
964
                     (uri-term <http://example/q>)
965
                     (string-term "a string")
966
                     (tagged-string-term ,literal-tagged)
967
                     (typed-string-term ,literal-typed)
968
                     (integer-term 1)
969
                     (float-term 1.0)
970
                     (decimal-term 1/3))
971
          (print (list symbol-datatype uri string integer float decimal)))))))
972
 
973
 (defun zero-duration ()
974
   (or *zero-duration*
975
       (with-term-record (%term)
976
         (cffi:with-foreign-string (%lexical-form "PT0S")
977
           (cffi:with-foreign-string (%datatype "http://www.w3.org/2001/XMLSchema#dayTimeDuration")
978
             (rdfcache:initialize-term %term :literal %lexical-form :language nil :datatype %datatype)
979
             ;;(print-term-strings %term)
980
             (let ((id (rdfcache:lookup-term-number %term)))
981
               (unless id
982
                 (log-warn "Interning missing term <~a>." "PT0S")
983
                 (rdfcache::intern-term nil
984
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::type)
985
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::value)
986
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::language)
987
                                        (cffi:foreign-slot-value %term '(:struct rdfcache::term) 'rdfcache::datatype)))
988
               (setf *zero-duration* (intern-term-aspects :literal "PT0S" |xsd|::|dayTimeDuration| nil))
989
               (setf (spocq:term-id *zero-duration*) id)
990
               (unless (plusp (rdfcache-object-term-number nil *zero-duration*))
991
                 (error "Cannot locate PT0S in the store."))
992
               *zero-duration*))))))
993
 
994
 (defun graph-management-argument (term)
995
   (cond ((member term '(nil :default |urn:dydra|:|default|))
996
          rdfcache:*default-context-number*)
997
         ((member term '(t |urn:dydra|:|named| |urn:dydra|:|all|))
998
          (error "invalid graph management argument: ~s" term))
999
         ((iri-p term)
1000
          (iri-lexical-form term))
1001
         (t
1002
          (spocq.e::invalid-graph-error :identifier term))))
1003
 
1004
 
1005