8

I have an enum in postgresql defined like so:

create type color as enum ('yellow', 'purple', 'white', 'black');

And I can get to the Jdbc4Array like so:

(def colors 
  ((first (sql/with-connection db/db 
    (sql/with-query-results res 
      ["select enum_range(null::color)"]
      (doall res)))) :enum_range))

This shows an object like this:

#<Jdbc4Array {yellow,purple,white,black}>

But trying the usual things throws an exception:

(.getArray colors) => stream closed

So I figure I need to access the array before the connection is closed:

(def colors 
  ((sql/with-connection db/db 
    (sql/with-query-results res 
      ["select enum_range(null::color)"]
      (.getArray ((first (doall res)) :enum_range))))))

But in this case I get this exception:

Method org.postgresql.jdbc4.Jdbc4Array.getArrayImpl(long,int,Map)
is not yet implemented.

Sinister. What can I do here?

1 Answer 1

1

There is something very strange going on with the Postgresql Jdbc4Array.getArray() implementation, I couldn't get it to work. But, I have some success with .getResultSet() :

user=> (with-connection db (with-query-results rs ["select enum_range(null::color)"]     
           (.getResultSet (get (first(doall rs)) :enum_range))))
#<Jdbc4ResultSet org.postgresql.jdbc4.Jdbc4ResultSet@17cff66>

Now, array's contents could be accessed via standard ResultSet interface. I've copied some code from clojure.contrib.sql to do it:

(defn resultset-seq
  [^java.sql.ResultSet rs]
  (let [rsmeta (. rs (getMetaData))
    idxs (range 1 (inc (. rsmeta (getColumnCount))))
    keys (map (fn [i] (. rsmeta (getColumnLabel i))) idxs)
    check-keys (or (apply distinct? keys)
               (throw (Exception. "ResultSet must have unique column labels")))
    row-struct (apply create-struct keys)
    row-values (fn [] (map (fn [^Integer i] (. rs (getObject i))) idxs))
    rows (fn thisfn []
           (when (. rs (next))
         (cons (apply struct row-struct (row-values)) (lazy-seq (thisfn)))))]
  (rows)))

which gives (sorry for quick-hack style code)

user=> (with-connection db 
         (with-query-results rs ["select enum_range(null::color)"] 
                            (get (first (resultset-seq 
                                           (.getResultSet (get (first(doall rs))
                                                              :enum_range))))
                                 "VALUE")))
#<PGobject yellow>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.