             column-types (get-column-types rows)
             client-types (map :client column-types)
             psql-types (map :psql column-types)
-            transformed-rows (map #(transform-row % client-types) rows)]
+            transformed-rows (transform-rows rows client-types)]
         (jdbc/db-do-commands tenant-conn
           (jdbc/create-table-ddl table-name
                                  (apply vector [:rnum :serial :primary :key]

        (if file-on-disk?
          (str file-upload-path
            "/resumed/"
            (last (s/split url #"\/"))
            "/file")
          url))))


            [clojure.data.csv :as csv]
            [clojure.java.io :as io]
            [clojure.java.jdbc :as jdbc]
            [cuerdas.core :as string])
  (:import com.ibm.icu.text.CharsetDetector))


(defn transform-value
  "Transforms the given value according to its associated type label.
  Numeric strings are cast to numbers, only if the type label is 'number'"
  [[value type-label]]
  (cond
    (string/blank? value) nil
    (and (string/numeric? value) (= "number" type-label)) (Double/parseDouble value)
    :else value))

(defn transform-rows
  "Transform values in the given rows based on the given column types"
  [rows column-types]
  (let [value-type-pairs (map #(map vector % column-types) rows)]
    (map #(map transform-value %) value-type-pairs)))

(defn get-column-names
  "Returns a seq of alphanumeric column names of the form
  c1, c2, c3, ... for the given number of columns"
  [num-cols]
  (let [num-range (range 1 (inc num-cols))]
    (->> (map vector (repeat \c) num-range)
         (map string/join))))

(defn get-column-titles
  "Returns a seq of alphanumeric column titles of the form
  Column 1, Column 2, Column 3, ... for the given number of columns"
  [num-cols]
  (let [num-range (range 1 (inc num-cols))]
    (->> (map vector (repeat "Column ") num-range)
         (map string/join))))

(defn get-type-label
  "Returns a keyword label representing the type of the given value.
  Defaults to `:text`."
  [value]
  (condp #(%1 %2) value
    string/blank? :nil
    ;; TODO date-string? :date
    string/numeric? :number
    :text))

(defn all-of-type?
  "Determines if all type labels for the given column are the same or `:nil`"
  [coll type-kw]
  {:pre [(contains? #{:date :number :text} type-kw)]}
  (every? true? (map #(contains? #{:nil type-kw} %) coll)))
