Has anybody else hit this?

I just did. Its not tricky to alter resultset-seq to return maps with
qualified keys:

(defn resultset-seq
 "Creates and returns a lazy sequence of structmaps corresponding to
  the rows in the java.sql.ResultSet rs"
  [#^java.sql.ResultSet rs]
    (let [rsmeta (. rs (getMetaData))
          idxs (range 1 (inc (. rsmeta (getColumnCount))))
          keys (map (comp keyword (memfn toLowerCase))
-                    (map (fn [i] (. rsmeta (getColumnName i))) idxs))
+                   (map (fn [i] (str (. rsmeta (getTableName i)) "."
(. rsmeta (getColumnName i)))) idxs))
          row-struct (apply create-struct keys)
          row-values (fn [] (map (fn [#^Integer i] (. rs (getObject i))) idxs))
          rows (fn thisfn []
                   (when (. rs (next))
                     (lazy-cons (apply struct row-struct (row-values))
(thisfn))))]
      (rows)))

Of course now all keys come back as qualified, breaking anything that
relied on the old behaviour. It also wouldn't be too hard to make this
return qualified keys only when there are duplicate column names, as
demonstrated by Allen.

Another thought I had would be to pass a flag to specify if you want
qualified keys which defaults to false--this way you get the old
behaviour unless you ask for/need qualified keys.

Rich, would you consider a patch to make resultset-seq more robust to
handle cases with duplicate column names?

/mike.

On Sat, Oct 11, 2008 at 12:21 PM, Allen Rohner <[EMAIL PROTECTED]> wrote:
>
> If you create a SQL query that returns duplicate names, resultset-seq
> throws an exception: "java.lang.RuntimeException:
> java.lang.IllegalArgumentException: Too many arguments to struct
> constructor"
>
> i.e.
>
> (let [rs (query "select description,description from table")]
>   (resultset-seq rs)
>
> The following patch adds a method duplicate-col-names? which returns
> true if the resultset contains duplicate column names, and modifies
> resultset-seq to throw an exception if there are duplicate column
> names.
>
> As an aside, now that clojure has real libraries, it seems that
> boot.clj is not the best place for the resultset code.
>
> Allen
>
> Index: src/clj/clojure/boot.clj
> ===================================================================
> --- src/clj/clojure/boot.clj    (revision 1060)
> +++ src/clj/clojure/boot.clj    (working copy)
> @@ -1901,10 +1901,26 @@
>                 (clojure.lang.LineNumberingPushbackReader.))]
>     (load-reader rdr)))
>
> +(defn set
> +  "Returns a set of the distinct elements of coll."
> +  [coll] (apply hash-set coll))
> +
> +(defn duplicate-col-names? [#^java.sql.ResultSet rs]
> +  "returns true if the columns in the result set contain duplicate
> names"
> +  (let [rsmeta (. rs (getMetaData))
> +       idxs (range 1 (inc (. rsmeta (getColumnCount))))
> +       keys (map (comp keyword (memfn toLowerCase))
> +                 (map (fn [i] (. rsmeta (getColumnName i))) idxs))
> +       unique-keys (set keys)]
> +    (not (= (count keys) (count unique-keys)))))
> +
> +
>  (defn resultset-seq
>   "Creates and returns a lazy sequence of structmaps corresponding to
>   the rows in the java.sql.ResultSet rs"
>   [#^java.sql.ResultSet rs]
> +  (when (duplicate-col-names? rs)
> +    (throw (Exception. "resultset-seq does not handle queries with
> duplicate column names")))
>     (let [rsmeta (. rs (getMetaData))
>           idxs (range 1 (inc (. rsmeta (getColumnCount))))
>           keys (map (comp keyword (memfn toLowerCase))
> @@ -1916,10 +1932,6 @@
>                     (lazy-cons (apply struct row-struct (row-values)) 
> (thisfn))))]
>       (rows)))
>
> -(defn set
> -  "Returns a set of the distinct elements of coll."
> -  [coll] (apply hash-set coll))
> -
>  (defn #^{:private true}
>   filter-key [keyfn pred amap]
>     (loop [ret {} es (seq amap)]
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to