Skip to content

Commit

Permalink
check if jdbc driver supports getGeneratedKeys
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Wurzer committed Aug 29, 2011
1 parent a5f4d45 commit f2f99b4
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ pom.xml
lib
classes
build
.lein-failures
logfile
27 changes: 20 additions & 7 deletions src/clojureql/internal.clj
Original file line number Diff line number Diff line change
Expand Up @@ -360,22 +360,35 @@
(with-open [rset (.executeQuery stmt)]
(func (result-seq rset))))))

(defn supports-generated-keys [conn]
(try (.supportsGetGeneratedKeys (.getMetaData conn))
(catch AbstractMethodError _ false)))

(defn generated-keys [stmt]
{:last-index
(when (supports-generated-keys (.getConnection stmt))
(let [ks (.getGeneratedKeys stmt)]
(and
(.next ks)
(.getInt ks 1))))})

(defn prepare-statement [conn sql]
(if (supports-generated-keys conn)
(jdbc/prepare-statement conn sql :return-keys true)
(jdbc/prepare-statement conn sql)))

(defn exec-prepared
"Executes an (optionally parameterized) SQL prepared statement on the
open database connection. Each param-group is a seq of values for all of
the parameters."
([sql param-group]
(with-open [stmt (jdbc/prepare-statement (:connection jdbcint/*db*)
sql :return-keys true)]
(with-open [stmt (prepare-statement (:connection jdbcint/*db*) sql)]
(doseq [[idx v] (map vector (iterate inc 1) param-group)]
(.setObject stmt idx v))
(jdbc/transaction
(let [retr (.execute stmt)
ks (.getGeneratedKeys stmt)]
(let [retr (.execute stmt)]
(with-meta [(.getUpdateCount stmt)]
{:last-index (and
(.next ks)
(.getInt ks 1))})))))
(generated-keys stmt))))))
([sql param-group & param-groups]
(with-open [stmt (jdbc/prepare-statement (:connection jdbcint/*db*) sql)]
(doseq [param-group (cons param-group param-groups)]
Expand Down
8 changes: 6 additions & 2 deletions test/clojureql/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

(if (find-ns 'cake)
(refer 'cake :only ['*opts*])
(def *opts* {:integration (System/getProperty "integration")}))
(def *opts* {:integration true :show-sql true}))

(when (:show-sql *opts*)
(alter-var-root #'clojureql.core/*debug* (constantly true)))
Expand Down Expand Up @@ -46,7 +46,7 @@
:user "dba"
:password "sql"})

(def databases [mysql postgresql sqlite3 sa-jodbc])
(def databases [sa-jodbc])

(defn mysql? []
(isa? (class (connection)) com.mysql.jdbc.JDBC4Connection))
Expand All @@ -60,6 +60,10 @@
(defn sa-jodbc? []
(isa? (class (connection)) ianywhere.ml.jdbcodbc.IConnection))

(defn supports-join-jusing? [] (not sa-jodbc?))

(defn supports-generated-keys? [] (not sa-jodbc?))

(defn drop-if [table]
(try (drop-table table) (catch Exception _)))

Expand Down
24 changes: 14 additions & 10 deletions test/clojureql/test/integration.clj
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
{:wage 400, :id 8}))))

(database-test test-generated-keys
(is (= 5 (-> (conj! salary {:wage 1337})
meta :last-index)))
(is (= 6 (-> (update-in! salary (where (= :id 512))
(when (supports-generated-keys?)
(is (= 5 (-> (conj! salary {:wage 1337})
meta :last-index)))
(is (= 6 (-> (update-in! salary (where (= :id 512))
{:wage 1337})
meta :last-index))))
meta :last-index)))))

(database-test test-join-explicitly
(is (= @(join users salary (where (= :users.id :salary.id)))
Expand All @@ -39,11 +40,12 @@
{:wage 400, :title "Engineer", :name "Frank", :id 4}))))

(database-test test-join-using
(is (= @(join users salary :id)
'({:wage 100, :title "Dev", :name "Lau Jensen", :id 1}
{:wage 200, :title "Design Guru", :name "Christophe", :id 2}
{:wage 300, :title "Mr. Macros", :name "sthuebner", :id 3}
{:wage 400, :title "Engineer", :name "Frank", :id 4}))))
(when (supports-join-jusing?)
(is (= @(join users salary :id)
'({:wage 100, :title "Dev", :name "Lau Jensen", :id 1}
{:wage 200, :title "Design Guru", :name "Christophe", :id 2}
{:wage 300, :title "Mr. Macros", :name "sthuebner", :id 3}
{:wage 400, :title "Engineer", :name "Frank", :id 4})))))

(database-test test-case
(is (= @(-> (project salary
Expand Down Expand Up @@ -88,6 +90,8 @@
'({:avg 250.0000M})))
(sqlite3?) (is (= @(-> (table :salary) (project [[:avg/wage :as :avg]]))
'({:avg 250.0})))
(sa-jodbc?) (is (= @(-> (table :salary) (project [[:avg/wage :as :avg]]))
'({:avg 250.0})))
:else true))

(database-test test-select-with-nil-and-value
Expand All @@ -98,7 +102,7 @@
(is (empty? @(select (table :users) (where (= nil nil))))))

(database-test test-select-is-null
(when (or (postgresql?) (mysql?)) ; (where true) not supported by sqlite3
(when (or (postgresql?) (mysql?) (sa-jodbc?)) ; (where true) not supported by sqlite3
(let [[alice bob] @(-> (disj! users (where true))
(conj! [{:name "Alice" :title "Developer"}
{:name "Bob"}]))]
Expand Down

0 comments on commit f2f99b4

Please sign in to comment.