Coverage report: /development/source/library/org/datagraph/spocq-shard/src/algebra/operators/xpath-operators.lisp

KindCoveredAll%
expression90332 27.1
branch010 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 "This file defines the GIS extension operators for the 'org.datagraph.spocq' RDF engine."
6
 
7
  (copyright
8
   "Copyright 2010 [james anderson](mailto:james.anderson@setf.de) All Rights Reserved.")
9
 
10
  (long-description
11
   "The file defines the xpath extension operators for SPOCQ as per the xpath recommendations[1,2].
12
    For tests see spocq:src;tests;algebra;operators;xpath-functions.lisp
13
 
14
  ---
15
  [1]: http://www.w3.org/2005/xpath-functions/math/
16
  [2]: http://www.w3.org/TR/xpath-functions-30/
17
 "))
18
 
19
 ;;; math operators
20
 (defgeneric |math.xpath|:|acos| (value)
21
   (:method ((value number))
22
     (acos value))
23
   (:method ((value t))
24
     (acos (spocq.e::number value))))
25
 
26
 (defgeneric |math.xpath|:|asin| (value)
27
   (:method ((value number))
28
     (asin value))
29
   (:method ((value t))
30
     (asin (spocq.e::number value))))
31
 
32
 (defgeneric |math.xpath|:|atan| (value)
33
   (:method ((value number))
34
     (atan value))
35
   (:method ((value t))
36
     (atan (spocq.e::number value))))
37
 
38
 (defgeneric |math.xpath|:|atan2| (value1 value2)
39
   (:method ((value1 number) (value2 number))
40
     (atan value1 value2))
41
   (:method ((value1 t) (value2 t))
42
     (atan (spocq.e::number value1) (spocq.e::number value2))))
43
 
44
 (defgeneric |math.xpath|:|cos| (value)
45
   (:method ((value number))
46
     (cos value))
47
   (:method ((value t))
48
     (cos (spocq.e::number value))))
49
 
50
 (defgeneric |math.xpath|:|exp| (value)
51
   (:method ((value number))
52
     (exp value))
53
   (:method ((value t))
54
     (exp (spocq.e::number value))))
55
 
56
 (defgeneric |math.xpath|:|exp10| (value)
57
   (:method ((value number))
58
     (expt 10.0 value))
59
   (:method ((value t))
60
     (expt 10.0 (spocq.e::number value))))
61
 
62
 (defgeneric |math.xpath|:|log| (value)
63
   (:method ((value number))
64
     (log value))
65
   (:method ((value t))
66
     (log (spocq.e::number value))))
67
 
68
 (defgeneric |math.xpath|:|log10| (value)
69
   (:method ((value number))
70
     (log value 10.0))
71
   (:method ((value t))
72
     (log (spocq.e::number value) 10.0)))
73
 
74
 (defgeneric |math.xpath|:|max| (value1 value2 &rest args)
75
   (:method ((value1 number) (value2 number) &rest args)
76
     (declare (dynamic-extent args))
77
     (if args
78
         (apply #'|math.xpath|:|max| (max value1 value2) args)
79
         (max value1 value2)))
80
   (:method ((value1 number) (value2 t) &rest args)
81
     (declare (dynamic-extent args))
82
     (apply #'|math.xpath|:|max| value1 (spocq.e::number value2) args))
83
   (:method ((value1 t) (value2 t) &rest args)
84
     (declare (dynamic-extent args))
85
      (apply #'|math.xpath|:|max| (spocq.e::number value1) (spocq.e::number value2) args)))
86
 
87
 
88
 (defgeneric |math.xpath|:|min| (value1 value2 &rest args)
89
   (:method ((value1 number) (value2 number) &rest args)
90
     (declare (dynamic-extent args))
91
     (if args
92
         (apply #'|math.xpath|:|min| (min value1 value2) args)
93
         (min value1 value2)))
94
   (:method ((value1 number) (value2 t) &rest args)
95
     (declare (dynamic-extent args))
96
     (apply #'|math.xpath|:|min| value1 (spocq.e::number value2) args))
97
   (:method ((value1 t) (value2 t) &rest args)
98
     (declare (dynamic-extent args))
99
      (apply #'|math.xpath|:|min| (spocq.e::number value1) (spocq.e::number value2) args)))
100
 
101
 (defun |math.xpath|:|pi| ()
102
   pi)
103
 
104
 (defgeneric |math.xpath|:|pow| (value1 value2)
105
   (:method ((value1 number) (value2 number))
106
     (expt value1 value2))
107
   (:method ((value1 t) (value2 t))
108
     (expt (spocq.e::number value1) (spocq.e::number value2))))
109
 
110
 (defgeneric |math.xpath|:|sin| (value)
111
   (:method ((value number))
112
     (sin value))
113
   (:method ((value t))
114
     (sin (spocq.e::number value))))
115
 
116
 (defgeneric |math.xpath|:|sqrt| (value)
117
   (:method ((value number))
118
     (sqrt value))
119
   (:method ((value t))
120
     (sqrt (spocq.e::number value))))
121
 
122
 (defgeneric |math.xpath|:|tan| (value)
123
   (:method ((value number))
124
     (tan value))
125
   (:method ((value t))
126
     (tan (spocq.e::number value))))
127
 
128
 
129
 ;;; xpath operators
130
 ;;; most implemented by the sparql operator. some require special handling for boundarx values
131
 
132
 (defgeneric |fn|:|abs| (value)
133
   (:method ((value number))
134
     (abs value))
135
   (:method ((value t))
136
     (spocq.e:abs value))
137
   (:method ((value string))
138
     (abs (spocq.e::number value))))
139
 
140
 (defgeneric |fn|:|ceil| (value)
141
   (:method ((value number))
142
     (ceiling value))
143
   (:method ((value t))
144
     (spocq.e:ceil value))
145
   (:method ((value string))
146
     (ceiling (spocq.e::number value))))
147
 
148
 (defun |fn|:|concat| (&rest strings)
149
   (declare (dynamic-extent strings))
150
   (apply #'spocq.e:string-concatenate strings))
151
 
152
 (defgeneric |fn|:|compare| (term1 term2 &optional collation)
153
   (:documentation "Compare the arguments and return -1, 0, 1 to indicate order.
154
  Where the arguments are commensurable as strings or iri, permit an optional explicit collation sequence.
155
  Given two simple strings, observe the respective language tags.
156
  Otherwise perform a direct term comparison iff no collation was supplied")
157
   (:method ((term1 string) (term2 string) &optional (collation nil))
158
     (typecase collation
159
       (null (compare-term term1 term2))
160
       (string (if (equal collation "http://www.w3.org/2005/xpath-functions/collation/codepoint")
161
                   (compare-term term1 term2)
162
                   (dydra-ndk::string-collate term1 term2 collation)))
163
       (iri (|fn|:|compare| term1 term2 (iri-lexical-form collation)))
164
       (t (spocq.e:argument-type-error :operator |fn|:|compare| :expected-type |xsd|:|string|
165
                                       :datum collation))))
166
   (:method ((term1 spocq:plain-literal) (term2 spocq:plain-literal) &optional collation)
167
     (|fn|:|compare| (spocq::plain-literal-lexical-form term1) (spocq::plain-literal-lexical-form term2) collation))
168
   (:method ((term1 symbol) (term2 symbol) &optional collation)
169
     (|fn|:|compare| (symbol-uri-namestring term1) (symbol-uri-namestring term2) collation))
170
   (:method ((term1 spocq:iri) (term2 spocq:iri) &optional collation)
171
     (|fn|:|compare| (spocq:iri-lexical-form term1) (spocq:iri-lexical-form term2) collation))
172
   (:method ((term1 t) (term2 t) &optional collation)
173
     (if collation
174
         (spocq.e:argument-type-error :operator |fn|:|compare| :expected-type 'null
175
                                      :datum collation)
176
         (compare-terms term1 term1))))
177
 
178
 (defun |fn|:|contains| (string1 string2 &optional collation)
179
   (if collation
180
       (spocq.e:argument-type-error :operator |fn|:|contains| :expected-type 'null
181
                                    :datum collation)
182
       (spocq.e:contains string1 string2)))
183
 
184
 (defun |fn|:|ends-with| (string1 string2 &optional collation)
185
   (if collation
186
       (spocq.e:argument-type-error :operator |fn|:|ends-with| :expected-type 'null
187
                                    :datum collation)
188
       (spocq.e:string-ends string1 string2)))
189
 
190
 
191
 (defgeneric |fn|:|floor| (value)
192
   (:method ((value number))
193
     (floor value))
194
   (:method ((value t))
195
     (spocq.e:floor value))
196
   (:method ((value string))
197
     (floor (spocq.e::number value))))
198
 
199
 ;;; date / datetime / time format operators are implemented in terms of the generic |dydra|:|format|.
200
 ;;;  nb. C, E, Z, z are not supported
201
 (defun |fn|:|format-date| (value picture &optional language calendar place)
202
   (when (or language calendar place)
203
     (log-warn "|fn|:|format-date| : ignored arguments: language: ~a calendar: ~a place: ~a" language calendar place))
204
   (|dydra|:|format| value picture))
205
 
206
 (defun |fn|:|format-dateTime| (value picture &optional language calendar place)
207
   (when (or language calendar place)
208
     (log-warn "|fn|:|format-dateTime| : ignored arguments: language: ~a calendar: ~a place: ~a" language calendar place))
209
   (|dydra|:|format| value picture))
210
 
211
 (defun |fn|:|format-duration| (value picture &optional language calendar place)
212
   (when (or language calendar place)
213
     (log-warn "|fn|:|format-duration| : ignored arguments: language: ~a calendar: ~a place: ~a" language calendar place))
214
   (|dydra|:|format| value picture))
215
 
216
 (defun |fn|:|format-time| (value picture &optional language calendar place)
217
   (when (or language calendar place)
218
     (log-warn "|fn|:|format-time| : ignored arguments: language: ~a calendar: ~a place: ~a" language calendar place))
219
   (|dydra|:|format| value picture))
220
 
221
 
222
 (defun |fn|:|lower-case| (string)
223
   (spocq.e:lcase string))
224
 
225
 (defun |fn|:|matches| (text pattern &optional (flags nil))
226
   (spocq.a:|regex| text pattern flags))
227
 
228
 (defun |fn|:|not| (value)
229
   (spocq.e:|!| value))
230
 
231
 (defgeneric |fn|:|round| (value)
232
   (:method ((value number))
233
     (round value))
234
   (:method ((value t))
235
     (spocq.e:round value))
236
   (:method ((value string))
237
     (round (spocq.e::number value))))
238
 
239
 (defun |fn|:|replace| (input pattern replacement &optional (flags nil))
240
   (spocq.a:|replace| input pattern replacement flags))
241
 
242
 (defun |fn|:|starts-with| (string1 string2 &optional collation)
243
    (if collation
244
       (spocq.e:argument-type-error :operator |fn|:|starts-with| :expected-type 'null
245
                                    :datum collation)
246
       (spocq.e:string-starts string1 string2)))
247
 
248
 (defun |fn|:|string-length| (string)
249
   (spocq.e:string-length string))
250
 
251
 (defun |fn|:|substring| (value start &optional length)
252
   ;; leave the length, rounding, and error logic to the base implementation
253
   (if length 
254
       (spocq.e:substring value start length)
255
       (spocq.e:substring value start)))
256
 
257
 (defun |fn|:|substring-after| (string substring &optional collation)
258
   (if collation
259
       (spocq.e:argument-type-error :operator |fn|:|substring-after| :expected-type 'null
260
                                    :datum collation)
261
       (spocq.e:substring-after string substring)))
262
 
263
 (defun |fn|:|substring-before| (string substring &optional collation)
264
   (if collation
265
       (spocq.e:argument-type-error :operator |fn|:|substring-before| :expected-type 'null
266
                                    :datum collation)
267
       (spocq.e:substring-before string substring)))
268
 
269
 (defun |fn|:|upper-case| (string)
270
   (spocq.e:ucase string))
271
 
272
 #|
273
 (run-sparql-internal "
274
 prefix math: <http://www.w3.org/2005/xpath-functions/math#>
275
 
276
 select (math:acos(1) as ?acos)
277
        (math:asin(1) as ?asin)
278
        (math:atan(1) as ?atan)
279
        (math:atan2(1, 0) as ?atan2)
280
        (math:cos(math:pi()) as ?cos)
281
        (math:exp(1) as ?exp)
282
        (math:exp10(1) as ?exp10)
283
        (math:log(1) as ?log)
284
        (math:log10(1) as ?log10)
285
        (math:pi() as ?pi)
286
        (math:pow(2, 2) as ?pow)
287
        (math:sin(0) as ?sin)
288
        (math:sqrt(2) as ?sqrt)
289
        (math:tan(1) as ?tan)
290
        (fn:day-from-dateTime(?now) as ?nowDay)
291
        (fn:hour-from-dateTime(?now) as ?nowHour)
292
        (fn:minute-from-dateTime(?now) as ?nowMinute)
293
        (fn:month-from-dateTime(?now) as ?nowMonth)
294
        (fn:second-from-dateTime(?now) as ?nowSecond)
295
        (fn:year-from-dateTime(?now) as ?nowYear)
296
        ((fn:days-from-duration(?now - '2014-01-01T00:00:00Z'^^xsd:dateTime)) as ?dayInYear)
297
 where { bind(now() as ?now) }
298
 "
299
  :repository-id "jhacker/system"
300
  :agent (system-agent))
301
 
302
 
303
 ((0.0 1.5707964 0.7853982 1.5707964 -1.0d0 2.7182817 10.0 0.0 0.0
304
   3.141592653589793d0 4 0.0 1.4142135 1.5574077))
305
 (?::|acos| ?::|asin| ?::|atan| ?::|atan2| ?::|cos| ?::|exp| ?::|exp10| ?::|log|
306
  ?::|log10| ?::|pi| ?::|pow| ?::|sin| ?::|sqrt| ?::|tan|)
307
 
308
 
309
 |#