File: data.lisp

package info (click to toggle)
cl-ixf 20140826-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 92 kB
  • ctags: 73
  • sloc: lisp: 586; makefile: 13
file content (50 lines) | stat: -rw-r--r-- 2,186 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
;;;
;;; Read IBM ixf files data.
;;;

(in-package #:ixf)

(defun parse-ixf-data (data-type nullable pos length data)
  "Read data at given POSITION in DATA, with given LENGTH and DATA-TYPE."

  (unless (and nullable (parse-ixf-null data pos))
    (when nullable (setf pos (+ 2 pos)))
    (case data-type
      (#. +integer+   (parse-ixf-integer data pos))
      (#. +smallint+  (parse-ixf-smallint data pos))
      (#. +bigint+    (parse-ixf-bigint data pos))

      (#. +decimal+   (let* ((length    (format nil "~5,'0d" length))
                             (precision (parse-integer length :end 3))
                             (scale     (parse-integer length :start 3)))
                        (parse-ixf-decimal data pos precision scale)))

      (#. +float+     (parse-ixf-float data pos length))

      (#. +timestamp+ (parse-ixf-timestamp data pos length))
      (#. +time+      (parse-ixf-time data pos))
      (#. +date+      (parse-ixf-date data pos))

      (#. +char+      (parse-ixf-string data pos length))

      (#. +varchar+   (let ((length (parse-ixf-smallint data pos)))
                        ;; The current length indicators are 2-byte integers
                        ;; in a form specified by the IXFTMFRM field.
                        (parse-ixf-string data (+ pos 2) length))))))

(defmethod parse-data-record ((ixf ixf-file) record)
  "Parse given data record and return what we found."
  (let* ((header (ixf-file-header ixf))
         (table  (ixf-file-table ixf))
         (babel:*default-character-encoding* (ixf-header-encoding header)))
    (loop :with data := (get-record-property :IXFDCOLS record)
       :with record := (make-array (ixf-table-ncol table))
       :for i :below (ixf-table-ncol table)
       :for column :across (ixf-table-columns table)
       :do (setf (svref record i)
                 (let ((data-type (ixf-column-type column))
                       (length    (ixf-column-length column))
                       (pos       (- (ixf-column-pos column) 1))
                       (nullable  (ixf-column-nullable column)))
                   (parse-ixf-data data-type nullable pos length data)))
       :finally (return record))))