Changeset version,0.1,4 for version/0.1/xbase.lisp
- Timestamp:
- 10/03/2007 05:21:21 PM (19 years ago)
- branch-nick:
- xbase
- revision id:
- dsowen@fugue88.ws-20071003172121-56qbaz5sxe3k71ys
- File:
-
- 1 edited
-
version/0.1/xbase.lisp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
version/0.1/xbase.lisp
r3 r4 1 (require '#:asdf) 2 (require '#:cl-ppcre) 3 4 (use-package '#:cl-ppcre) 5 6 7 1 8 ;;; Fairly generic file-reading stuff. 2 9 … … 130 137 ,@(mapcar #'slot-from-field descs))) 131 138 139 (defstruct dbf-desc 140 name 141 filename 142 sql-create) 143 144 (defvar *dbfs* (make-hash-table :test 'eq)) 145 146 (defun sql-escape-fieldname (name) 147 (let ((name (string-downcase name))) 148 (if (member name '("user") :test 'equal) 149 (concatenate 'string "\"" name "\"") 150 name))) 151 152 (defun sql-escape-data (value) 153 (if (string= value "") 154 "null" 155 (format nil "'~A'" (cl-ppcre:regex-replace-all "'" value "''")))) 156 132 157 (defun sql-column (desc) 133 158 (with-slots (name type size precision) desc 134 159 (format nil "~A ~A" 135 name160 (sql-escape-fieldname name) 136 161 (cond 137 162 ((string= type "C") … … 156 181 (mapcar 'sql-column descs))) 157 182 158 (defstruct dbf-desc 159 name 160 filename 161 sql-create) 162 163 (defvar *dbfs* (make-hash-table :test 'eq)) 183 (defun make-sql-function (type name descs) 184 `(defmethod sql-insert ((obj ,type)) 185 (format 186 nil 187 ,(format nil "INSERT INTO ~A(~{~A~@{,~A~}~}) VALUES(~{~A~@{,~A~}~})" 188 name 189 (mapcar (lambda (desc) 190 (sql-escape-fieldname (field-desc-name desc))) 191 descs) 192 (mapcar (lambda (d) 193 (declare (ignore d)) 194 "~A") 195 descs)) 196 ,@(mapcar (lambda (desc) 197 `(sql-escape-data 198 (slot-value obj ',(intern (field-desc-name desc))))) 199 descs)))) 164 200 165 201 (defmacro define-dbf-struct (name filename) … … 170 206 :filename ,filename 171 207 :sql-create ,(sql-create name descs))) 172 ,(struct-from-field-descs name descs)))) 208 ,(struct-from-field-descs name descs) 209 ,(make-sql-function name name descs)))) 173 210 174 211 … … 193 230 (define-dbf-struct phone "/home/dsowen/scott/local/bent-data/bentphon.dbf") 194 231 (define-dbf-struct tenent-change "/home/dsowen/scott/local/bent-data/benttchg.dbf") 232 233 234 235 (defun import-dbf (filename table-name) 236 "Reads the DBF file, analyzing meta-data to create Lisp structures, 237 populating those structures, and constructing descriptive SQL." 238 (let ((field-descs (nth-value 1 (read-dbf-structure filename)))) 239 (setf (gethash 'import-struct *dbfs*) 240 (make-dbf-desc :name 'import-struct 241 :filename filename 242 :sql-create (sql-create table-name field-descs))) 243 (eval (struct-from-field-descs 'import-struct field-descs)) 244 (eval (make-sql-function 'import-struct table-name field-descs)) 245 (read-dbf 'import-struct))) 246 247 (defun split-name (filename) 248 (unless (pathnamep filename) 249 (setf filename (pathname filename))) 250 (let ((name (pathname-name filename))) 251 (values (subseq name 0 4) 252 (subseq name 4)))) 253 254 (defun do-dbf (filename) 255 (multiple-value-bind (db-name table-name) (split-name filename) 256 (let ((recs (import-dbf filename table-name))) 257 (format t "~A;~%~%~%~%" 258 (slot-value (gethash 'import-struct *dbfs*) 'sql-create)) 259 (dolist (rec recs) 260 (format t "~A;~%~%" (sql-insert rec)))))) 261 262 (defun main () 263 (when (/= (length *posix-argv*) 2) 264 (format *error-output* "Usage: xbase dbf-file~%") 265 (quit)) 266 (do-dbf (second *posix-argv*)) 267 (quit))
Note: See TracChangeset
for help on using the changeset viewer.
