Clojure / postgresql: как получить доступ к значениям перечисления из результатов Jdbc4Array? - PullRequest
8 голосов
/ 30 августа 2011

У меня есть перечисление в postgresql, определенное так:

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

И я могу добраться до Jdbc4Array следующим образом:

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

Это показывает объект, подобный этому:

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

Но обычные попытки выдают исключение:

(.getArray colors) => stream closed

Поэтому я считаю, что мне нужно получить доступ к массиву до закрытия соединения:

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

Нов этом случае я получаю это исключение:

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

Зловещий.Что я могу сделать здесь?

1 Ответ

1 голос
/ 10 февраля 2012

В реализации Postgresql Jdbc4Array.getArray () происходит нечто очень странное, я не могу заставить его работать. Но у меня есть некоторый успех с .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>

Теперь доступ к содержимому массива можно получить через стандартный интерфейс ResultSet. Я скопировал некоторый код из clojure.contrib.sql, чтобы сделать это:

(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)))

, который дает (извините за код стиля быстрого взлома)

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...