From 9a04208b03c895521ff21a2ecfd81882e3f1dc28 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Thu, 11 Jun 2015 21:53:15 +0300 Subject: [PATCH 01/20] lein-release plugin: bumped version from 0.6.0 to 0.6.1-SNAPSHOT for next development cycle --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index d52a36b..c9e0262 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject alaisi/postgres.async "0.6.0" +(defproject alaisi/postgres.async "0.6.1-SNAPSHOT" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" From 35247133cbf448470fcdace0cbcfc1c94d62b026 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Thu, 11 Jun 2015 21:54:02 +0300 Subject: [PATCH 02/20] Next is 0.7.0 --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index c9e0262..5afd892 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject alaisi/postgres.async "0.6.1-SNAPSHOT" +(defproject alaisi/postgres.async "0.7.0-SNAPSHOT" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" From be86d5dd81242bd1039ecd7ce8cc7a488868aa33 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Fri, 10 Jul 2015 22:09:25 +0300 Subject: [PATCH 03/20] #17: Support connection validation --- dev/user.clj | 3 ++- project.clj | 2 +- src/postgres/async.clj | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dev/user.clj b/dev/user.clj index 789214a..76db850 100644 --- a/dev/user.clj +++ b/dev/user.clj @@ -6,7 +6,8 @@ (pg/open-db {:hostname "localhost" :database "postgres" :username "postgres" - :password "postgres"})) + :password "postgres" + :validation-query "select 1"})) (defn reload [] (repl/refresh)) diff --git a/project.clj b/project.clj index 5afd892..b53815f 100644 --- a/project.clj +++ b/project.clj @@ -7,7 +7,7 @@ :url "http://github.com/alaisi/postgres.async.git"} :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/core.async "0.1.346.0-17112a-alpha"] - [com.github.alaisi.pgasync/postgres-async-driver "0.6"] + [com.github.alaisi.pgasync/postgres-async-driver "0.7-SNAPSHOT"] [cheshire "5.5.0" :scope "provided"]] :lein-release {:deploy-via :clojars} :global-vars {*warn-on-reflection* true} diff --git a/src/postgres/async.clj b/src/postgres/async.clj index 098fb26..4ee5979 100644 --- a/src/postgres/async.clj +++ b/src/postgres/async.clj @@ -18,7 +18,8 @@ (defn open-db "Creates a db connection pool" - [{:keys [hostname port username password database pool-size ssl] :as config}] + [{:keys [hostname port username password database pool-size ssl validation-query] + :as config}] (doseq [param [:hostname :username :password :database]] (when (nil? (param config)) (throw (IllegalArgumentException. (str param " is required"))))) @@ -30,6 +31,7 @@ (.password password) (.ssl (boolean ssl)) (.poolSize (or pool-size 25)) + (.validationQuery validation-query) (.dataConverter (create-converter)) (.build))) From 2588150975ab3627feec1fe719d2243c68f56f84 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Thu, 3 Sep 2015 22:20:21 +0300 Subject: [PATCH 04/20] Support pipelining in open-db --- src/postgres/async.clj | 4 +++- test/postgres/async_test.clj | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/postgres/async.clj b/src/postgres/async.clj index 4ee5979..1fbcc3a 100644 --- a/src/postgres/async.clj +++ b/src/postgres/async.clj @@ -18,7 +18,8 @@ (defn open-db "Creates a db connection pool" - [{:keys [hostname port username password database pool-size ssl validation-query] + [{:keys [hostname port username password database + pool-size ssl validation-query pipeline] :as config}] (doseq [param [:hostname :username :password :database]] (when (nil? (param config)) @@ -30,6 +31,7 @@ (.username username) (.password password) (.ssl (boolean ssl)) + (.pipeline (boolean pipeline)) (.poolSize (or pool-size 25)) (.validationQuery validation-query) (.dataConverter (create-converter)) diff --git a/test/postgres/async_test.clj b/test/postgres/async_test.clj index df39264..ff42706 100644 --- a/test/postgres/async_test.clj +++ b/test/postgres/async_test.clj @@ -25,6 +25,7 @@ :database (env "PG_DB" "postgres") :username (env "PG_USER" "postgres") :password (env "PG_PASSWORD" "postgres") + :pipeline true :pool-size 1})] (try (create-tables *db*) From fd1200591d5ef672b88949287678a299352a652b Mon Sep 17 00:00:00 2001 From: anttil Date: Wed, 2 Dec 2015 08:12:03 +0200 Subject: [PATCH 05/20] #17: Use connection validation support from postgres-async-driver 0.7 --- project.clj | 4 ++-- src/postgres/async.clj | 2 +- test/postgres/async_test.clj | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/project.clj b/project.clj index b53815f..8796994 100644 --- a/project.clj +++ b/project.clj @@ -6,8 +6,8 @@ :scm {:name "git" :url "http://github.com/alaisi/postgres.async.git"} :dependencies [[org.clojure/clojure "1.6.0"] - [org.clojure/core.async "0.1.346.0-17112a-alpha"] - [com.github.alaisi.pgasync/postgres-async-driver "0.7-SNAPSHOT"] + [org.clojure/core.async "0.2.374"] + [com.github.alaisi.pgasync/postgres-async-driver "0.7"] [cheshire "5.5.0" :scope "provided"]] :lein-release {:deploy-via :clojars} :global-vars {*warn-on-reflection* true} diff --git a/src/postgres/async.clj b/src/postgres/async.clj index 1fbcc3a..d15257a 100644 --- a/src/postgres/async.clj +++ b/src/postgres/async.clj @@ -33,7 +33,7 @@ (.ssl (boolean ssl)) (.pipeline (boolean pipeline)) (.poolSize (or pool-size 25)) - (.validationQuery validation-query) + (.validationQuery (or validation-query "")) (.dataConverter (create-converter)) (.build))) diff --git a/test/postgres/async_test.clj b/test/postgres/async_test.clj index ff42706..41d861d 100644 --- a/test/postgres/async_test.clj +++ b/test/postgres/async_test.clj @@ -25,6 +25,7 @@ :database (env "PG_DB" "postgres") :username (env "PG_USER" "postgres") :password (env "PG_PASSWORD" "postgres") + :validation-query "select 1" :pipeline true :pool-size 1})] (try From 953cd1adcf6e2a51c90dd959e5de37de56fd83a9 Mon Sep 17 00:00:00 2001 From: anttil Date: Fri, 18 Dec 2015 07:41:34 +0200 Subject: [PATCH 06/20] Issue #18: Add support for streaming query rows --- src/postgres/async.clj | 8 ++++++++ src/postgres/async/impl.clj | 36 +++++++++++++++++++++++++++++------- test/postgres/async_test.clj | 17 ++++++++++++++++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/postgres/async.clj b/src/postgres/async.clj index d15257a..c94be20 100644 --- a/src/postgres/async.clj +++ b/src/postgres/async.clj @@ -61,6 +61,14 @@ (execute! db sql (fn [rs err] (f (:rows rs) err))))) +(defn query-rows! + "Executes an sql query with parameters and returns a channel where 0-n rows are emitted." + [^QueryExecutor db [sql & params]] + (let [c (chan)] + (-> (.queryRows db sql (into-array params)) + (.subscribe (pg/row-observer c))) + c)) + (defn insert! "Executes an sql insert and returns update count and returned rows. Spec format is diff --git a/src/postgres/async/impl.clj b/src/postgres/async/impl.clj index cb68264..435f55e 100644 --- a/src/postgres/async/impl.clj +++ b/src/postgres/async/impl.clj @@ -17,20 +17,40 @@ (apply f (concat args [callback])) channel)) -(defn column->value [^Object value] +(defn- column->value [^Object value] (if (and value (-> value .getClass .isArray)) (vec (map column->value value)) value)) +;; TODO: make columns public in the Java driver +(defn- get-columns [^PgRow row] + (-> (doto (.getDeclaredField PgRow "columns") + (.setAccessible true)) + (.get row) + (keys))) + +(defn- row->map [^PgRow row ^Object rowmap ^String col] + (assoc rowmap + (keyword (.toLowerCase col)) + (column->value (.get row col)))) + (defn result->map [^ResultSet result] - (let [columns (.getColumns result) - row->map (fn [^PgRow row rowmap ^String col] - (assoc rowmap (keyword (.toLowerCase col)) - (column->value (.get row col))))] + (let [columns (.getColumns result)] {:updated (.updatedRows result) :rows (vec (map (fn [row] - (reduce (partial row->map row) {} columns)) - result))})) + (reduce (partial row->map row) {} columns)) + result))})) + +(defn ^rx.Observer row-observer [channel] + (reify rx.Observer + (onNext [_ row] + (put! channel (reduce (partial row->map row) + {} (get-columns row)))) + (onError [_ err] + (put! channel err) + (close! channel)) + (onCompleted [_] + (close! channel)))) (defn- list-columns [data] (if (map? data) @@ -68,3 +88,5 @@ " WHERE " (first where) (when returning (str " RETURNING " returning)))) + + diff --git a/test/postgres/async_test.clj b/test/postgres/async_test.clj index 41d861d..f0e7c2c 100644 --- a/test/postgres/async_test.clj +++ b/test/postgres/async_test.clj @@ -1,7 +1,8 @@ (ns postgres.async-test (:require [clojure.test :refer :all] [clojure.core.async :refer [ Date: Fri, 29 Jan 2016 09:10:23 +0200 Subject: [PATCH 07/20] Fixes #19. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b404fb2..17ce1e6 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ See composition below for example. ## Composition -Channel-returning functions can be composed with `dosql` macro that returns result of last form of first exception. +Channel-returning functions can be composed with `dosql` macro that returns result of last form or first exception. ```clojure ( Date: Tue, 3 May 2016 13:12:27 +0300 Subject: [PATCH 08/20] Fixes #21: Override Timestamp using from-pg-value. --- src/postgres/async.clj | 11 +++++++++-- test/postgres/async_test.clj | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/postgres/async.clj b/src/postgres/async.clj index c94be20..9ec8854 100644 --- a/src/postgres/async.clj +++ b/src/postgres/async.clj @@ -6,13 +6,20 @@ [com.github.pgasync.impl.conversion DataConverter])) (defmulti from-pg-value (fn [oid value] oid)) +(defmethod from-pg-value :default [oid value] ::raw-value) + (defprotocol IPgParameter (to-pg-value [value])) (defn- create-converter [] (proxy [DataConverter] [] - (toConvertable [oid value] - (from-pg-value oid value)) + (toObject [oid value] + (when value + (let [val (from-pg-value oid value)] + (if (= ::raw-value val) + (proxy-call-with-super #(.toObject ^DataConverter this oid value) + this "toObject") + val)))) (fromConvertable [value] (to-pg-value value)))) diff --git a/test/postgres/async_test.clj b/test/postgres/async_test.clj index f0e7c2c..59e2c3e 100644 --- a/test/postgres/async_test.clj +++ b/test/postgres/async_test.clj @@ -66,6 +66,21 @@ (is (instance? SqlException ('::xml"]) + ^Throwable ex ( Date: Tue, 3 May 2016 13:19:55 +0300 Subject: [PATCH 09/20] Fixes #22: Boolean not supported by default --- project.clj | 2 +- test/postgres/async_test.clj | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/project.clj b/project.clj index 8796994..8eea89f 100644 --- a/project.clj +++ b/project.clj @@ -7,7 +7,7 @@ :url "http://github.com/alaisi/postgres.async.git"} :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/core.async "0.2.374"] - [com.github.alaisi.pgasync/postgres-async-driver "0.7"] + [com.github.alaisi.pgasync/postgres-async-driver "0.8-SNAPSHOT"] [cheshire "5.5.0" :scope "provided"]] :lein-release {:deploy-via :clojars} :global-vars {*warn-on-reflection* true} diff --git a/test/postgres/async_test.clj b/test/postgres/async_test.clj index 59e2c3e..cc240ee 100644 --- a/test/postgres/async_test.clj +++ b/test/postgres/async_test.clj @@ -40,7 +40,11 @@ (testing "query returns rows as map" (let [rs (wait (query! *db* ["select 1 as x"]))] - (is (= 1 (get-in rs [0 :x])))))) + (is (= 1 (get-in rs [0 :x]))))) + + (testing "query returns oid bool as boolean" + (let [rs (wait (query! *db* ["select true as b"]))] + (is (= true (get-in rs [0 :b])))))) (deftest query-for-array @@ -50,7 +54,11 @@ (testing "nested arrays are converted to vectors" (let [rs (wait (query! *db* ["select '{{1,2},{3,4},{5,NULL}}'::INT[][] as a"]))] - (is (= [[1 2] [3 4] [5 nil]] (get-in rs [0 :a])))))) + (is (= [[1 2] [3 4] [5 nil]] (get-in rs [0 :a]))))) + + (testing "bool arrays are converted to boolean vectors" + (let [rs (wait (query! *db* ["select '{true,false}'::BOOL[] as b"]))] + (is (= [true false] (get-in rs [0 :b])))))) (deftest query-for-rows From 85f65d0b4fae453e573dbb0c834f3f92e379c75e Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Tue, 3 May 2016 20:16:45 +0300 Subject: [PATCH 10/20] Prepare for release. --- project.clj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/project.clj b/project.clj index 8eea89f..858bf78 100644 --- a/project.clj +++ b/project.clj @@ -1,17 +1,17 @@ -(defproject alaisi/postgres.async "0.7.0-SNAPSHOT" +(defproject alaisi/postgres.async "0.7.0" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :scm {:name "git" :url "http://github.com/alaisi/postgres.async.git"} - :dependencies [[org.clojure/clojure "1.6.0"] + :dependencies [[org.clojure/clojure "1.8.0"] [org.clojure/core.async "0.2.374"] - [com.github.alaisi.pgasync/postgres-async-driver "0.8-SNAPSHOT"] - [cheshire "5.5.0" :scope "provided"]] + [com.github.alaisi.pgasync/postgres-async-driver "0.8"] + [cheshire "5.6.1" :scope "provided"]] :lein-release {:deploy-via :clojars} :global-vars {*warn-on-reflection* true} :target-path "target/%s" :profiles {:dev {:source-paths ["dev"] - :dependencies [[org.clojure/tools.namespace "0.2.4"] - [org.clojure/java.classpath "0.2.0"]]}}) + :dependencies [[org.clojure/tools.namespace "0.2.11"] + [org.clojure/java.classpath "0.2.3"]]}}) From d7daee97ba1f418fbd2362d2b25f818581d3397e Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Tue, 3 May 2016 20:24:53 +0300 Subject: [PATCH 11/20] Next is 0.8.0. --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 858bf78..474e0a2 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject alaisi/postgres.async "0.7.0" +(defproject alaisi/postgres.async "0.8.0-SNAPSHOT" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" From 7db941407f619db9ce8e5001aa2094db3a081d70 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Tue, 3 May 2016 20:56:36 +0300 Subject: [PATCH 12/20] Add example of converting dates. --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 17ce1e6..6119162 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,14 @@ Support for custom types can be added by extending `IPgParameter` protocol and ` (.getBytes (str store) "UTF-8"))) (defmethod from-pg-value com.github.pgasync.impl.Oid/HSTORE [oid ^bytes value] - (my-h-store/parse-string (String. value "UTF-8))) + (my-h-store/parse-string (String. value "UTF-8"))) +``` + +`from-pg-value` can also be used for overriding "core" types. This is especially useful with temporal data types that are by default converted to `java.sql.Date`, `java.sql.Time`, `java.sql.Timestamp`. + +```clojure +(defmethod from-pg-value com.github.pgasync.impl.Oid/DATE [oid ^bytes value] + (java.time.LocalDate/parse (String. value "UTF-8"))) ``` ## Dependencies From cbb0c70e51fe3c429c13da3348647d31f792017f Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Tue, 3 May 2016 23:15:19 +0300 Subject: [PATCH 13/20] Fix reflection warning. --- src/postgres/async.clj | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/postgres/async.clj b/src/postgres/async.clj index 9ec8854..caa2c60 100644 --- a/src/postgres/async.clj +++ b/src/postgres/async.clj @@ -13,15 +13,15 @@ (defn- create-converter [] (proxy [DataConverter] [] + (fromConvertable [value] + (to-pg-value value)) (toObject [oid value] (when value - (let [val (from-pg-value oid value)] - (if (= ::raw-value val) - (proxy-call-with-super #(.toObject ^DataConverter this oid value) - this "toObject") - val)))) - (fromConvertable [value] - (to-pg-value value)))) + (let [val (from-pg-value oid value) + this ^DataConverter this] + (if-not (= ::raw-value val) + val + (proxy-super toObject oid value))))))) (defn open-db "Creates a db connection pool" From e857b45e6587509fdde89778ac7df79a64dff221 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Wed, 4 May 2016 10:57:13 +0300 Subject: [PATCH 14/20] Add clojars badge. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6119162..c46b02e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ postgres.async ============== +[![Clojars Project](https://img.shields.io/clojars/v/alaisi/postgres.async.svg)](https://clojars.org/alaisi/postgres.async) + Asynchronous PostgreSQL client for Clojure. ## Download From 5a623e443f9c9a92204d53f51d5ea70ce45ce0dc Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Fri, 10 Jun 2016 20:10:51 +0300 Subject: [PATCH 15/20] Upgrade to postgres-async-driver 0.9 and Netty 4.1 (Fixes #20). --- project.clj | 2 +- src/postgres/async/impl.clj | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/project.clj b/project.clj index 474e0a2..d0ee363 100644 --- a/project.clj +++ b/project.clj @@ -7,7 +7,7 @@ :url "http://github.com/alaisi/postgres.async.git"} :dependencies [[org.clojure/clojure "1.8.0"] [org.clojure/core.async "0.2.374"] - [com.github.alaisi.pgasync/postgres-async-driver "0.8"] + [com.github.alaisi.pgasync/postgres-async-driver "0.9"] [cheshire "5.6.1" :scope "provided"]] :lein-release {:deploy-via :clojars} :global-vars {*warn-on-reflection* true} diff --git a/src/postgres/async/impl.clj b/src/postgres/async/impl.clj index 435f55e..924b9bc 100644 --- a/src/postgres/async/impl.clj +++ b/src/postgres/async/impl.clj @@ -22,12 +22,8 @@ (vec (map column->value value)) value)) -;; TODO: make columns public in the Java driver (defn- get-columns [^PgRow row] - (-> (doto (.getDeclaredField PgRow "columns") - (.setAccessible true)) - (.get row) - (keys))) + (keys (.getColumns row))) (defn- row->map [^PgRow row ^Object rowmap ^String col] (assoc rowmap From 8a88fda9ba0a0c1c896eab8a86fbd1be0794556f Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Fri, 10 Jun 2016 20:14:56 +0300 Subject: [PATCH 16/20] lein-release plugin: preparing 0.8.0 release --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index d0ee363..c4f7029 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject alaisi/postgres.async "0.8.0-SNAPSHOT" +(defproject alaisi/postgres.async "0.8.0" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" From e34d8df3a291971f2d53a01211d4ba67b1cb415e Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Fri, 10 Jun 2016 20:15:19 +0300 Subject: [PATCH 17/20] lein-release plugin: bumped version from 0.8.0 to 0.8.1-SNAPSHOT for next development cycle --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index c4f7029..6b3344d 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject alaisi/postgres.async "0.8.0" +(defproject alaisi/postgres.async "0.8.1-SNAPSHOT" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" From 03f563305d749b918949fc0f0c6c52e0a16b1710 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Fri, 10 Jun 2016 20:16:14 +0300 Subject: [PATCH 18/20] Next is 0.9.0 --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 6b3344d..f78cba8 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject alaisi/postgres.async "0.8.1-SNAPSHOT" +(defproject alaisi/postgres.async "0.9.0-SNAPSHOT" :description "Asynchronous PostgreSQL Clojure client" :url "http://github.com/alaisi/postgres.async" :license {:name "Eclipse Public License" From faf26366fdc5804e2bbaf227c22d7b2a8b64c8a8 Mon Sep 17 00:00:00 2001 From: Antti Laisi Date: Fri, 10 Jun 2016 20:18:23 +0300 Subject: [PATCH 19/20] Touch readme to update clojars version. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index c46b02e..1337097 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ Add the following to your [Leiningen](http://github.com/technomancy/leiningen) ` ![latest postgres.async version](https://clojars.org/alaisi/postgres.async/latest-version.svg) - ## Setting up a connection pool A pool of connections to PostgreSQL backend is created with `open-db`. Each connection *pool* starts a single I/O thread used in communicating with PostgreSQL backend. From ff54a448f9dc20eaae76ece6ffc64af9adb63a5f Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Fri, 9 Sep 2016 12:35:46 +0100 Subject: [PATCH 20/20] Add link to clojars in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1337097..4c6b1bc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Asynchronous PostgreSQL client for Clojure. Add the following to your [Leiningen](http://github.com/technomancy/leiningen) `project.clj`: -![latest postgres.async version](https://clojars.org/alaisi/postgres.async/latest-version.svg) +[![latest postgres.async version](https://clojars.org/alaisi/postgres.async/latest-version.svg)](https://clojars.org/alaisi/postgres.async) ## Setting up a connection pool