Author: lgiessmann
Date: Tue Apr 5 07:23:28 2011
New Revision: 414
Log:
changed the behavior of casting string-values to xml-boolean, xml-integer, xml-double and xml-decimal
Modified:
trunk/src/TM-SPARQL/sparql.lisp
trunk/src/unit_tests/sparql_test.lisp
Modified: trunk/src/TM-SPARQL/sparql.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql.lisp (original)
+++ trunk/src/TM-SPARQL/sparql.lisp Tue Apr 5 07:23:28 2011
@@ -477,6 +477,7 @@
(filter-by-given-object construct :revision revision))
(filter-by-special-uris construct :revision revision))))
(map 'list #'(lambda(result)
+ ;(format t "-->~a<--~%" result) ;TODO: remove
(push (getf result :subject) (subject-result construct))
(push (getf result :predicate) (predicate-result construct))
(push (getf result :object) (object-result construct)))
@@ -1235,35 +1236,88 @@
(cond ((string= literal-type *xml-string*)
literal-value)
((string= literal-type *xml-boolean*)
- (when (and (string/= literal-value "false")
- (string/= literal-value "true"))
- (error (make-condition
- 'sparql-parser-error
- :message (format nil "Could not cast from ~a to ~a"
- literal-value literal-type))))
- (if (string= literal-value "false")
- nil
- t))
+ (cast-literal-to-boolean literal-value))
((string= literal-type *xml-integer*)
- (handler-case (parse-integer literal-value)
- (condition ()
- (error (make-condition
- 'sparql-parser-error
- :message (format nil "Could not cast from ~a to ~a"
- literal-value literal-type))))))
- ((or (string= literal-type *xml-decimal*) ;;both types are
- (string= literal-type *xml-double*)) ;;handled the same way
- (let ((value (read-from-string literal-value)))
- (unless (numberp value)
- (error (make-condition
- 'sparql-parser-error
- :message (format nil "Could not cast from ~a to ~a"
- literal-value literal-type))))
- value))
+ (cast-literal-to-integer literal-value))
+ ((string= literal-type *xml-double*)
+ (cast-literal-to-double literal-value))
+ ((string= literal-type *xml-decimal*)
+ (cast-literal-to-decimal literal-value))
(t ; return the value as a string
literal-value)))
+(defun cast-literal-to-decimal (literal-value)
+ "A helper function that casts the passed string value of the literal
+ value to an decimal value."
+ (let ((bad-string
+ (loop for idx to (1- (length literal-value))
+ when (and (not (digit-char-p (elt literal-value idx)))
+ (not (eql (elt literal-value idx) #\.)))
+ return t)))
+ (when bad-string
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value *xml-decimal*)))))
+ ;decimals are handled as single floats
+ (if (find #\. literal-value)
+ (read-from-string literal-value)
+ (read-from-string (concat literal-value ".0"))))
+
+
+(defun cast-literal-to-double (literal-value)
+ "A helper function that casts the passed string value of the literal
+ value to an decimal value."
+ (let ((modified-str ""))
+ (loop for idx to (1- (length literal-value))
+ when (eql (char-downcase (elt literal-value idx)) #\e)
+ do (push-string "d" modified-str)
+ else
+ do (push-string (string (elt literal-value idx)) modified-str))
+ (let ((value
+ (cond ((or (string= "+INF" modified-str)
+ (string= "INF" modified-str))
+ sb-ext:double-float-positive-infinity)
+ ((string= "-INF" modified-str)
+ sb-ext:double-float-negative-infinity)
+ ((find #\d (string-downcase modified-str))
+ (read-from-string modified-str))
+ (t
+ (read-from-string (concat modified-str "d0"))))))
+ (if (typep value 'double-float)
+ value
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value *xml-double*)))))))
+
+
+(defun cast-literal-to-integer (literal-value)
+ "A helper function that casts the passed string value of the literal
+ value to an integer value."
+ (handler-case (parse-integer literal-value)
+ (condition ()
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value *xml-integer*))))))
+
+
+(defun cast-literal-to-boolean (literal-value)
+ "A helper function that casts the passed string value of the literal
+ value to t or nil."
+ (when (and (string/= literal-value "false")
+ (string/= literal-value "true"))
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value *xml-boolean*))))
+ (if (string= literal-value "false")
+ nil
+ t))
+
+
(defmethod initialize-instance :after ((construct SPARQL-Query) &rest args)
(declare (ignorable args))
(parser-start construct (original-query construct))
Modified: trunk/src/unit_tests/sparql_test.lisp
==============================================================================
--- trunk/src/unit_tests/sparql_test.lisp (original)
+++ trunk/src/unit_tests/sparql_test.lisp Tue Apr 5 07:23:28 2011
@@ -2366,10 +2366,11 @@
;; to 12 and "\"abc\"" to "abc
(map 'list #'(lambda(triple)
- (format t "~a - ~a - ~a~%"
+ (format t "~a - ~a - ~a(~a)~%"
(tm-sparql::subject-result triple)
(tm-sparql::predicate-result triple)
- (tm-sparql::object-result triple)))
+ (tm-sparql::object-result triple)
+ (tm-sparql::literal-datatype triple)))
(tm-sparql::select-group (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))