-
Notifications
You must be signed in to change notification settings - Fork 26
/
resultset.clj
72 lines (67 loc) · 2.88 KB
/
resultset.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
;; Copyright 2014-2015 Andrey Antukh <niwi@niwi.be>
;;
;; Licensed under the Apache License, Version 2.0 (the "License")
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
(ns jdbc.resultset
"ResultSet conversion functions."
(:require [clojure.string :as str]
[jdbc.proto :as proto])
(:import java.sql.PreparedStatement
java.sql.ResultSetMetaData
java.sql.ResultSet))
(defn result-set->lazyseq
"Function that wraps result in a lazy seq. This function
is part of public api but can not be used directly (you should pass
this function as parameter to `query` function).
Required parameters:
rs: ResultSet instance.
Optional named parameters:
:identifiers -> function that is applied for column name
when as-arrays? is false
:as-rows? -> by default this function return a lazy seq of
records (map), but in certain circumstances you
need results as a lazy-seq of vectors. With this keywork
parameter you can enable this behavior and return a lazy-seq
of vectors instead of records (maps).
"
[conn ^ResultSet rs {:keys [identifiers as-rows? header?]
:or {identifiers str/lower-case
as-rows? false
header? false}
:as options}]
(let [^ResultSetMetaData metadata (.getMetaData rs)
idseq (range 1 (inc (.getColumnCount metadata)))
labels (mapv (fn [^long i] (.getColumnLabel metadata i)) idseq)
keyseq (mapv (comp keyword identifiers) labels)
values (fn []
(mapv (fn [^long i]
(-> (.getObject rs i)
(proto/from-sql-type conn metadata i)))
idseq))
rows (fn thisfn []
(when (.next rs)
(cons (values) (lazy-seq (thisfn)))))
records (fn thisfn []
(when (.next rs)
(-> (zipmap keyseq (values))
(cons (lazy-seq (thisfn))))))
header (mapv identifiers labels)]
(if-not as-rows?
(records)
(if-not header?
(rows)
(cons header (lazy-seq (rows)))))))
(defn result-set->vector
"Function that evaluates a result into one clojure persistent
vector. Accept same parameters as `result-set->lazyseq`."
[conn ^ResultSet rs options]
(vec (result-set->lazyseq conn rs options)))