tmore
tmore

Reputation: 693

Error Thrown While Processing DB Query Resultset

Can anyone help me understand why my code (see below) is resulting in the following error:

Exception in thread "main" java.lang.UnsupportedOperationException: nth not supported on this type: PersistentStructMap

(defn search [query]
  (with-connection db 
    (with-query-results rs [query] 
      (doseq [[k v] rs] 
        (println v)))))

(search (nth *command-line-args* 0))

Upvotes: 2

Views: 672

Answers (1)

Brian Carper
Brian Carper

Reputation: 72926

rs is a sequence (list), representing all the records in your resultset. Each element of rs is a hashmap representing a single record, with key/value pairs in the map representing field names and values for that record. You're trying to do the equivalent of this:

user> (let [rs [{:id 1 :val "foo"} {:id 2 :val "bar"}]]
        (doseq [[k v] rs]
          (println v)))
; Evaluation aborted.
; nth not supported on this type: PersistentArrayMap

This is trying to destructure each map into [k v], doing the rough equivalent of this:

user> (let [k (nth {:id 1 :val "foo"} 0)
            v (nth {:id 1 :val "foo"} 1)])
; Evaluation aborted.
; nth not supported on this type: PersistentArrayMap

If you're trying to print the value for every field in every record, you need to do this:

user> (let [rs [{:id 1 :val "foo"} {:id 2 :val "bar"}]]
        (doseq [record rs
                [k v] record]
          (println v)))
foo
1
bar
2

"For each record in the resultset, for each key/value in that record, print the value."

If your resultset contains only a single record (or you only care about one of them) and you're trying to iterate over the fields of that single record, then pass doseq only the first:

user> (let [rs [{:id 1 :val "foo"}]]
        (doseq [[k v] (first rs)]
          (println v)))
foo
1

"For every key/value in the first record of the resultset, print the value."

Upvotes: 3

Related Questions