2011-08-30 48 views
8

像這樣:Clojure/postgresql:如何從Jdbc4Array結果中訪問枚舉值?我在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

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 [email protected]> 

現在,數組的內容可以通過標準的Res​​ultSet接口來訪問。我複製了一些代碼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>