From 3418113efa0adf41b67fe7c2998614b4d4a9a0aa Mon Sep 17 00:00:00 2001
From: technomancy <technomancy@domU-12-31-39-07-C4-F6.compute-1.internal>
Date: Mon, 17 Oct 2011 21:20:07 +0000
Subject: [PATCH] Accept string or URI in with-connection.

---
 src/main/clojure/clojure/java/jdbc/internal.clj |   18 +++++++++++++++++-
 src/test/clojure/clojure/java/test_jdbc.clj     |   18 +++++++++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/main/clojure/clojure/java/jdbc/internal.clj b/src/main/clojure/clojure/java/jdbc/internal.clj
index 7d41469..4596b98 100644
--- a/src/main/clojure/clojure/java/jdbc/internal.clj
+++ b/src/main/clojure/clojure/java/jdbc/internal.clj
@@ -15,9 +15,10 @@
 ;;  Migrated from clojure.contrib.sql.internal 17 April 2011
 
 (ns clojure.java.jdbc.internal
-  (:require clojure.string)
+  (:require [clojure.string :as str])
   (:import
     (clojure.lang RT)
+    (java.net URI)
     (java.sql BatchUpdateException Connection DriverManager PreparedStatement ResultSet SQLException Statement)
     (java.util Hashtable Map Properties)
     (javax.naming InitialContext Name)
@@ -106,6 +107,17 @@
       (.setProperty p (as-str identity k) (as-str identity v)))
     p))
 
+(defn- parse-properties-uri [^URI uri]
+  (let [host (.getHost uri)
+        port (.getPort uri)
+        path (.getPath uri)]
+    (merge
+     {:subname (str "//" host ":" port path)
+      :subprotocol (.getScheme uri)}
+     (if-let [user-info (.getUserInfo uri)]
+             {:user (first (str/split user-info #":"))
+              :password (second (str/split user-info #":"))}))))
+
 (defn get-connection
   "Creates a connection to a database. db-spec is a map containing values
   for one of the following parameter sets:
@@ -134,6 +146,10 @@
            name environment]
     :as db-spec}]
   (cond
+    (instance? URI db-spec)
+    (get-connection (parse-properties-uri db-spec))
+    (string? db-spec)
+    (get-connection (URI. db-spec))
     factory
     (factory (dissoc db-spec :factory))
     (and subprotocol subname)
diff --git a/src/test/clojure/clojure/java/test_jdbc.clj b/src/test/clojure/clojure/java/test_jdbc.clj
index 33754cc..c77ed48 100644
--- a/src/test/clojure/clojure/java/test_jdbc.clj
+++ b/src/test/clojure/clojure/java/test_jdbc.clj
@@ -45,6 +45,8 @@
 (def hsqldb-db {:subprotocol "hsqldb"
                 :subname "clojure_test_hsqldb"})
 
+(def mysql-str "mysql://clojure_test:clojure_test@localhost:3306/clojure_test")
+
 (defn- test-specs
   "Return a sequence of db-spec maps that should be used for tests"
   []
@@ -58,7 +60,7 @@
   (doseq [db (test-specs)]
     (sql/with-connection
       db
-      (doseq [table [:fruit :fruit2]]
+      (doseq [table [:fruit :fruit2 :veggies :veggies2]]
         (try
           (sql/drop-table table)
           (catch Exception _
@@ -86,6 +88,20 @@
       [:grade :real]
       :table-spec (if (= "mysql" p) "ENGINE=InnoDB" ""))))
 
+(deftest test-string-connection
+  (when (:mysql (set test-databases))
+    (sql/with-connection mysql-str
+      (create-test-table :veggies "mysql")
+      (sql/with-query-results res ["SELECT * FROM veggies"]
+        (is (empty? res))))))
+
+(deftest test-uri-connection
+  (when (:mysql (set test-databases))
+    (sql/with-connection (java.net.URI. mysql-str)
+      (create-test-table :veggies2 "mysql")
+      (sql/with-query-results res ["SELECT * FROM veggies2"]
+        (is (empty? res))))))
+
 (deftest test-create-table
   (doseq [db (test-specs)]
     (sql/with-connection db
-- 
1.7.4.1

