+ (find-if #'(lambda (f) (string-equal filename (fil f))) *umls-files*))
+
+(defun find-ucols-for-filename (filename)
+ "Returns list of umls-cols for a file structure"
+ (loop for colname in (fields (find-ufile filename))
+ collect (find-ucol colname filename)))
+
+(defun umls-field-string-to-list (fmt)
+ "Converts a comma delimited list of fields into a list of field names. Will
+append a unique number (starting at 2) onto a column name that is repeated in the list"
+ (let ((col-counts (make-hash-table :test 'equal)))
+ (loop for colname in (delimited-string-to-list (escape-column-name fmt) #\,)
+ collect
+ (multiple-value-bind (value found) (gethash col col-counts)
+ (cond
+ (found
+ (incf (gethash col col-counts))
+ (concatenate 'string colname (write-to-string (1+ value))))
+ (t
+ (setf (gethash col col-counts) 1)
+ colname))))))
+
+(defun make-ufile (fil des table cls rws bts fields)
+ (let ((ufile
+ (make-instance
+ 'ufile :fil fil :des des :table table :cls cls :rws rws :bts bts
+ :fields fields)))
+ (setf (ucols ufile) (find-ucols-for-filename fil))
+ ufile))
+
+(defun datatype-for-colname (colname)
+"Return datatype for column name"
+ (second (find colname +col-datatypes+ :key #'car :test #'string-equal)))
+
+(defun ensure-ucol-datatype (col datatype)
+"Add data type information to column"
+ (setf (datatype col) datatype)
+ (case datatype
+ (sql-u (setf (sqltype col) "INTEGER"
+ (parse-fun col) #'parse-ui
+ (quote-str col) ""))
+ (sql-s (setf (sqltype col) "SMALLINT"
+ (parse-fun col) #'parse-integer
+ (quote-str col) ""))
+ (sql-l (setf (sqltype col) "BIGINT"
+ (parse-fun col) #'parse-integer
+ (quote-str col) ""))
+ (sql-i (setf (sqltype col) "INTEGER"
+ (parse-fun col) #'parse-integer
+ (quote-str col) ""))
+ (sql-f (setf (sqltype col) "NUMERIC"
+ (parse-fun col) #'read-from-string
+ (quote-str col) ""))
+ (t ; Default column type, optimized text storage
+ (setf (parse-fun col) #'add-sql-quotes
+ (quote-str col) "'")
+ (when (and (cmax col) (av col))
+ (if (> (cmax col) 255)
+ (setf (sqltype col) "TEXT")
+ (if (< (- (cmax col) (av col)) 4)
+ (setf (sqltype col) "CHAR") ; if average bytes wasted < 4
+ (setf (sqltype col) "VARCHAR")))))))
+
+(defun escape-column-name (name)
+ (substitute #\_ #\/ name))