Changeset main,6
- Timestamp:
- 10/11/2007 10:09:29 PM (19 years ago)
- branch-nick:
- xbase
- revision id:
- dsowen@fugue88.ws-20071011220929-sjjjdjykw7t25k5k
- Location:
- main
- Files:
-
- 2 edited
-
Makefile (modified) (1 diff)
-
xbase.lisp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
main/Makefile
r4 r6 1 1 all: xbase 2 3 clean: 4 rm -f *.fasl *~ xbase 2 5 3 6 %: %.lisp -
main/xbase.lisp
r5 r6 1 1 (require '#:asdf) 2 2 (require '#:cl-ppcre) 3 (require '#:dso-binary-class) 3 4 4 5 (use-package '#:cl-ppcre) 5 6 7 8 ;;; Fairly generic file-reading stuff. 9 10 (defstruct member-def 11 name 12 type 13 format) 14 15 (defun parser-member-def (def) 16 (destructuring-bind (name type format) def 17 (make-member-def :name name :type type :format format))) 18 19 (defun lisp-type-from-file-type (type) 20 (ecase type 21 (unsigned '(integer 0)) 22 (date t) 23 (string 'string))) 24 25 (defun default-from-file-type (type) 26 (ecase type 27 (unsigned 0) 28 (date 0) 29 (string ""))) 30 31 (defgeneric read-binary (type stream &optional format) 32 (:method ((type (eql 'unsigned)) stream &optional (format 1)) 33 (let ((r 0)) 34 (dotimes (i format r) 35 (setf (ldb (byte 8 (* i 8)) r) (read-byte stream))))) 36 (:method ((type (eql 'string)) stream &optional format) 37 (let ((v (make-sequence '(vector (unsigned-byte 8)) format 38 :initial-element 0))) 39 (read-sequence v stream) 40 (string-trim '(#\Nul #\Space) (map 'string #'code-char v)))) 41 (:method ((type (eql 'date)) stream &optional format) 42 (assert (stringp format)) 43 (cond 44 ((string= format "YYMMDD") 45 (let* ((year (read-binary 'unsigned stream)) 46 (month (read-binary 'unsigned stream)) 47 (day (read-binary 'unsigned stream))) 48 (encode-universal-time 0 0 0 day month year))) 49 ((string= format "YYYYMMDD") 50 (let* ((year (read-binary 'unsigned stream 2)) 51 (month (read-binary 'unsigned stream)) 52 (day (read-binary 'unsigned stream))) 53 (encode-universal-time 0 0 0 day month year)))))) 54 55 (defmacro define-file-struct (name &body defs) 56 (let ((defs (mapcar #'parser-member-def defs))) 57 `(progn 58 (defstruct ,name 59 ,@(mapcar (lambda (def) 60 (with-slots (name type) def 61 `(,name ,(default-from-file-type type) 62 :type ,(lisp-type-from-file-type type)))) 63 (remove-if #'null defs :key #'member-def-type))) 64 (defmethod read-binary ((type (eql ',name)) stream &optional format) 65 (declare (ignore format)) 66 (let ((rec (make-instance ',name))) 67 ,@(mapcar (lambda (def) 68 (with-slots (name type format) def 69 (if name 70 `(setf (slot-value rec ',name) 71 (read-binary ',type stream ,format)) 72 `(read-binary 'unsigned stream ,format)))) 73 defs) 74 rec))))) 6 (use-package '#:binary-class) 75 7 76 8 … … 79 11 80 12 (define-file-struct dbf-header 81 (version unsigned 1)82 (last-update date "YYMMDD")83 (record-count unsigned 4)84 (header-length unsigned 2)85 (record-length unsigned 2)13 (version :unsigned 1) 14 (last-update :date "YYMMDD") 15 (record-count :unsigned 4) 16 (header-length :unsigned 2) 17 (record-length :unsigned 2) 86 18 (nil nil 2) 87 (incomplete-transaction unsigned 1)88 (encrypted unsigned 1)19 (incomplete-transaction :unsigned 1) 20 (encrypted :unsigned 1) 89 21 (nil nil 12) 90 (mdx-flag unsigned 1)91 (language unsigned 1)22 (mdx-flag :unsigned 1) 23 (language :unsigned 1) 92 24 (nil nil 2)) 93 25 94 26 (define-file-struct field-desc 95 (name string 11)96 (type string 1)27 (name :string 11) 28 (type :string 1) 97 29 (nil nil 4) 98 (size unsigned 1)99 (precision unsigned 1)30 (size :unsigned 1) 31 (precision :unsigned 1) 100 32 (nil nil 5) 101 (set-fields-flag unsigned 1)33 (set-fields-flag :unsigned 1) 102 34 (nil nil 7) 103 (is-indexed unsigned 1))35 (is-indexed :unsigned 1)) 104 36 105 37 (defun peek-byte (in) … … 125 57 (with-slots (name type size) desc 126 58 (let ((type (cond 127 ((string= type "C") 'string)128 ((string= type "N") 'string)129 ((string= type "D") 'string)130 ((string= type "M") 'string)131 ((string= type "L") 'string)59 ((string= type "C") :string) 60 ((string= type "N") :string) 61 ((string= type "D") :string) 62 ((string= type "M") :string) 63 ((string= type "L") :string) 132 64 (t (abort))))) 133 65 `(,(intern name) ,type ,size)))) … … 135 67 (defun struct-from-field-descs (name descs) 136 68 `(define-file-struct ,name 137 (%deleted unsigned 1)69 (%deleted :unsigned 1) 138 70 ,@(mapcar #'slot-from-field descs))) 139 71 … … 151 83 name))) 152 84 85 (defun recode (str) 86 (let (r 87 e) 88 (dotimes (i (length str)) 89 (let* ((ch (aref str i)) 90 (code (char-code ch))) 91 (cond 92 ((or (<= (char-code #\Space) code (char-code #\[)) 93 (<= (char-code #\]) code (char-code #\~))) 94 (push (string ch) r)) 95 ((<= 0 code 255) 96 (push (format nil "\\x~2,'0X" code) r) 97 (setf e t)) 98 (t 99 (error "Bad character!"))))) 100 (values 101 (apply #'concatenate 'string (nreverse r)) 102 e))) 103 153 104 (defun sql-escape-data (value) 154 105 (if (string= value "") 155 106 "null" 156 (let ((value 157 (concatenate 'string "'" (regex-replace-all "'" value "''") "'"))) 158 (when (find #\\ value :test 'char=) 159 (setf value (concatenate 'string 160 "E" 161 (regex-replace-all "\\\\" 162 value 163 "\\\\\\\\")))) 164 value))) 107 (multiple-value-bind (s recoded) (recode value) 108 (concatenate 'string 109 (if recoded "E'" "'") 110 (regex-replace-all "'" s "''") 111 "'")))) 165 112 166 113 (defun sql-column (desc) … … 192 139 (mapcar 'sql-column descs))) 193 140 141 (defgeneric sql-insert (obj)) 142 194 143 (defun make-sql-function (type name descs) 195 144 `(defmethod sql-insert ((obj ,type)) … … 237 186 (read-records in type)))))) 238 187 239 (define-dbf-struct unit-type "/home/dsowen/scott/local/bent-data/bentutyp.dbf")240 (define-dbf-struct vendor "/home/dsowen/scott/local/bent-data/bentvend.dbf")241 (define-dbf-struct phone "/home/dsowen/scott/local/bent-data/bentphon.dbf")242 (define-dbf-struct tenent-change "/home/dsowen/scott/local/bent-data/benttchg.dbf")243 244 188 245 189 … … 269 213 (slot-value (gethash 'import-struct *dbfs*) 'sql-create)) 270 214 (dolist (rec recs) 271 (format t "~A;~%~%" (sql-insert rec)))))) 215 (unless (/= (slot-value rec '%deleted) 32) 216 (format t "~A;~%~%" (sql-insert rec))))))) 272 217 273 218 (defun main ()
Note: See TracChangeset
for help on using the changeset viewer.
