In ODBC backend, avoid going through the common lisp universal time
authorRuss Tyndall <russ@acceleration.net>
Mon, 28 Nov 2011 22:44:20 +0000 (17:44 -0500)
committerRuss Tyndall <russ@acceleration.net>
Mon, 28 Nov 2011 22:48:20 +0000 (17:48 -0500)
type (because it lacks support for historic dates) when doing date
conversions.  Instead use CLSQL date/time types.

*time-conversion-function* renamed to *time-format*

Patch from: Francisco Vides Fernandez

ChangeLog
db-odbc/odbc-api.lisp
tests/test-time.lisp

index 005158fa5f0cff7847a2f6c83cf9c7010f7fde96..02d93ca2f40fc5d7602d9ad684333ceeea2b2077 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-11-28  Russ Tyndall  <russ@acceleration.net>
+       * db-odbc/odbc-api.lisp, tests/test-time.lisp
+
+       In ODBC backend, avoid going through the common lisp
+       universal-time type (because it lacks support for historic dates)
+
+       *time-conversion-function* renamed to *time-format*
+
+       Patch from: Francisco Vides Fernandez
+
 2011-10-18  Russ Tyndall  <russ@acceleration.net>
        * db-odbc/odbc-api.lisp
 
index 85411459d00f6185a35342e43b359806b0459b65..9ebdb3e6e506475104869f55624219851192b0e8 100644 (file)
@@ -22,17 +22,12 @@ May be locally bound to something else if a certain type is necessary.")
 
 
 (defvar *binary-format* :unsigned-byte-vector)
-(defvar *time-conversion-function*
-    (lambda (universal-time &optional fraction)
-       (let ((time (clsql-sys:utime->time universal-time)))
-        (setf time (clsql-sys:time+
-                    time
-                    (clsql-sys:make-duration :usec (/ fraction 1000))))
-        (clsql-sys:format-time nil time :format :iso))
-      #+ignore
-      universal-time)
-   "Bound to a function that converts from a Lisp universal time fixnum (and a fractional
-as possible second argument) to the desired representation of date/time/timestamp. By default, returns an iso-timestring.")
+(defvar *time-format*
+  (lambda (time)
+    (clsql-sys:format-time nil time :format :iso))
+   "Bound to a function that converts from a clsql:wall-time to the desired
+    representation of date/time/timestamp.
+    By default, returns an iso-timestring.")
 
 (defvar +null-ptr+ (make-null-pointer :byte))
 (defparameter +null-handle-ptr+ (make-null-pointer :void))
@@ -690,13 +685,11 @@ as possible second argument) to the desired representation of date/time/timestam
                    (t
                     (case c-type
                       ((#.$SQL_C_DATE #.$SQL_C_TYPE_DATE)
-                       (funcall *time-conversion-function* (date-to-universal-time data-ptr)))
+                       (funcall *time-format* (date-to-clsql-time data-ptr)))
                       ((#.$SQL_C_TIME #.$SQL_C_TYPE_TIME)
-                       (multiple-value-bind (universal-time frac) (time-to-universal-time data-ptr)
-                         (funcall *time-conversion-function* universal-time frac)))
+                      (funcall *time-format* (time-to-clsql-time data-ptr)))
                       ((#.$SQL_C_TIMESTAMP #.$SQL_C_TYPE_TIMESTAMP)
-                       (multiple-value-bind (universal-time frac) (timestamp-to-universal-time data-ptr)
-                         (funcall *time-conversion-function* universal-time frac)))
+                      (funcall *time-format* (timestamp-to-clsql-time data-ptr)))
                       (#.$SQL_INTEGER
                        (get-cast-int data-ptr))
                       (#.$SQL_C_FLOAT
@@ -947,17 +940,17 @@ as possible second argument) to the desired representation of date/time/timestam
 (def-type c-time-ptr-type (* (:struct sql-c-time)))
 (def-type c-date-ptr-type (* (:struct sql-c-date)))
 
-(defun timestamp-to-universal-time (ptr)
+(defun timestamp-to-clsql-time (ptr)
   (declare (type c-timestamp-ptr-type ptr))
-  (values
-   (encode-universal-time
-    (get-slot-value ptr 'sql-c-timestamp 'second)
-    (get-slot-value ptr 'sql-c-timestamp 'minute)
-    (get-slot-value ptr 'sql-c-timestamp 'hour)
-    (get-slot-value ptr 'sql-c-timestamp 'day)
-    (get-slot-value ptr 'sql-c-timestamp 'month)
-    (get-slot-value ptr 'sql-c-timestamp 'year))
-   (get-slot-value ptr 'sql-c-timestamp 'fraction)))
+  (clsql-sys:make-time
+   :second (get-slot-value ptr 'sql-c-timestamp 'second)
+   :minute (get-slot-value ptr 'sql-c-timestamp 'minute)
+   :hour (get-slot-value ptr 'sql-c-timestamp 'hour)
+   :day (get-slot-value ptr 'sql-c-timestamp 'day)
+   :month (get-slot-value ptr 'sql-c-timestamp 'month)
+   :year (get-slot-value ptr 'sql-c-timestamp 'year)
+   :usec (let ((frac (get-slot-value ptr 'sql-c-timestamp 'fraction)))
+          (if frac (/ frac 1000) 0))))
 
 (defun universal-time-to-timestamp (time &optional (fraction 0))
   "TODO: Dead function?"
@@ -987,21 +980,20 @@ as possible second argument) to the desired representation of date/time/timestam
           (get-slot-value ptr 'sql-c-timestamp 'fraction) fraction)
       ptr))
 
-(defun date-to-universal-time (ptr)
+(defun date-to-clsql-time (ptr)
   (declare (type c-date-ptr-type ptr))
-  (encode-universal-time
-   0 0 0
-   (get-slot-value ptr 'sql-c-timestamp 'day)
-   (get-slot-value ptr 'sql-c-timestamp 'month)
-   (get-slot-value ptr 'sql-c-timestamp 'year)))
+  (clsql-sys:make-time
+   :second 0 :minute 0 :hour 0
+   :day (get-slot-value ptr 'sql-c-timestamp 'day)
+   :month (get-slot-value ptr 'sql-c-timestamp 'month)
+   :year (get-slot-value ptr 'sql-c-timestamp 'year)))
 
-(defun time-to-universal-time (ptr)
+(defun time-to-clsql-time (ptr)
   (declare (type c-time-ptr-type ptr))
-  (encode-universal-time
-   (get-slot-value ptr 'sql-c-timestamp 'second)
-   (get-slot-value ptr 'sql-c-timestamp 'minute)
-   (get-slot-value ptr 'sql-c-timestamp 'hour)
-   1 1 0))
+  (clsql-sys:make-time
+   :second (get-slot-value ptr 'sql-c-timestamp 'second)
+   :minute (get-slot-value ptr 'sql-c-timestamp 'minute)
+   :hour (get-slot-value ptr 'sql-c-timestamp 'hour)))
 
 
 ;;; Added by KMR
index 374ad9503fa9c5bac2285c86ec44b427f221087d..158ac9ce0d820d6cb476c86f48e9336e45bffbd2 100644 (file)
     #.(iso-timestring (parse-timestring "2008-09-09T14:37:29.000278-04:00"))
     #.(iso-timestring (parse-timestring "2008-09-09T14:37:29.000278-04:00")))
 
+(deftest :time/historic-datetimes
+  (with-dataset *cross-platform-datetest*
+    (let ((time (parse-timestring "1800-09-09T14:37:29")))
+      (clsql-sys:insert-records :into [datetest]
+                                :attributes '([testtime])
+                                :values (list time))
+      (let ((testtime
+              (first (clsql:select [testtime]
+                       :from [datetest] :flatp t
+                       :where [= [testtime] time] ))))
+        (format-time nil (parse-timestring testtime) :format :iso)
+        )))
+  #.(format-time nil (parse-timestring "1800-09-09T14:37:29") :format :iso))
+
 ))
 
 
 
+
+