-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
207 additions
and
311 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,19 @@ | ||
{:deps {org.clojure/clojure {:mvn/version "1.10.1"} | ||
org.jooq/jooq {:mvn/version "3.11.11"}} | ||
|
||
:paths ["src"] | ||
:aliases | ||
{:dev {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.4"} | ||
org.clojure/tools.namespace {:mvn/version "0.3.0"} | ||
org.postgresql/postgresql {:mvn/version "42.2.6"} | ||
com.h2database/h2 {:mvn/version "1.4.199"} | ||
cheshire/cheshire {:mvn/version "5.8.1"}} | ||
:extra-paths ["test"]} | ||
:repl {:main-opts ["-m" "rebel-readline.main"]} | ||
:ancient {:main-opts ["-m" "deps-ancient.deps-ancient"] | ||
:extra-deps {deps-ancient {:mvn/version "RELEASE"}}} | ||
:test {:main-opts ["-m" "user"]} | ||
}} | ||
:aliases {:dev {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.4"} | ||
org.clojure/tools.namespace {:mvn/version "0.3.0"} | ||
org.postgresql/postgresql {:mvn/version "42.2.6"} | ||
com.h2database/h2 {:mvn/version "1.4.199"} | ||
cheshire/cheshire {:mvn/version "5.8.1"}} | ||
:extra-paths ["test"]} | ||
:bench {:extra-deps {seancorfield/next.jdbc {:mvn/version "1.0.1"} | ||
criterium/criterium {:mvn/version "0.4.5"}}} | ||
:repl {:main-opts ["-m" "rebel-readline.main"]} | ||
:ancient {:main-opts ["-m" "deps-ancient.deps-ancient"] | ||
:extra-deps {deps-ancient {:mvn/version "RELEASE"}}} | ||
:test {:main-opts ["-m" "user"]} | ||
}} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
= suricatta documentation | ||
Andrey Antukh, <niwi@niwi.nz> | ||
1.3.1 | ||
2.0.0 | ||
:toc: left | ||
:!numbered: | ||
:source-highlighter: pygments | ||
|
@@ -50,62 +50,33 @@ management, transaction isolation flags and sql rendering dialect. | |
|
||
You can create a **context** from: | ||
|
||
- a hash-map dbspec format (plain connection params). | ||
- a datasource instance (connection pool). | ||
- a link:http://funcool.github.io/clojure.jdbc/latest/[clojure.jdbc] connection | ||
instance. | ||
- a valid jdbc url | ||
|
||
.This is a default aspect of one dbspec. | ||
[source,clojure] | ||
---- | ||
(def dbspec {:subprotocol "postgresql" | ||
:subname "//localhost:5432/dbname" | ||
:user "username" ;; Optional | ||
:password "password"} ;; Optional | ||
---- | ||
|
||
==== Create Context from plain dbspec. | ||
==== Create Context from jdbc url | ||
|
||
.Example creating context from dbspec. | ||
[source, clojure] | ||
---- | ||
(require '[suricatta.core :as sc]) | ||
(with-open [ctx (sc/context {:subprotocol "h2" | ||
:subname "mem:"})] | ||
(do-something-with ctx)) | ||
---- | ||
|
||
==== Create Context from _clojure.jdbc_ connection. | ||
|
||
.Example creating context from _clojure.jdbc_ connection instance. | ||
[source, clojure] | ||
---- | ||
(require '[jdbc.core :as jdbc]) | ||
(require '[suricatta.core :as sc]) | ||
(def dbspec {:subprotocol "h2" | ||
:subname "mem:"}) | ||
(with-open [conn (jdbc/connection dbspec) | ||
ctx (sc/context conn)] | ||
(do-something ctx)) | ||
(with-open [ctx (sc/context "h2:mem:")] | ||
(do-something-with ctx)) | ||
---- | ||
|
||
NOTE: when closing the _suricatta_ context, the wrapped connection will also be closed. | ||
|
||
|
||
==== Create Context from DataSource. | ||
|
||
DataSource is the preferd way to connect to the database in production enviroments | ||
and is usually used to implement connection pools. | ||
|
||
In our case we will use *hikaricp* as a datasource with a connection pool. Lets | ||
start by adding hikari's dependency entry to your _project.clj_: | ||
start by adding hikari's dependency entry to your _deps.edn_: | ||
|
||
[source, clojure] | ||
---- | ||
[hikari-cp "0.13.0" :exclusions [com.zaxxer/HikariCP]] | ||
[com.zaxxer/HikariCP-java6 "2.2.5"] | ||
hikari-cp/hikari-cp {:mvn/version "2.7.1"} | ||
---- | ||
|
||
Now create the datasource instance: | ||
|
@@ -114,19 +85,19 @@ Now create the datasource instance: | |
---- | ||
(require '[hikari-cp.core :as hikari]) | ||
(def ^javax.sql.Datasource | ||
datasource (hikari/make-datasource | ||
{:connection-timeout 30000 | ||
:idle-timeout 600000 | ||
:max-lifetime 1800000 | ||
:minimum-idle 10 | ||
:maximum-pool-size 10 | ||
:adapter "postgresql" | ||
:username "username" | ||
:password "password" | ||
:database-name "database" | ||
:server-name "localhost" | ||
:port-number 5432})) | ||
(def ^javax.sql.Datasource datasource | ||
(hikari/make-datasource | ||
{:connection-timeout 30000 | ||
:idle-timeout 600000 | ||
:max-lifetime 1800000 | ||
:minimum-idle 10 | ||
:maximum-pool-size 10 | ||
:adapter "postgresql" | ||
:username "username" | ||
:password "password" | ||
:database-name "database" | ||
:server-name "localhost" | ||
:port-number 5432})) | ||
---- | ||
|
||
Now, having a datasource instace, you can use it like plain dbspec for creating | ||
|
@@ -276,7 +247,7 @@ sequence. Let's see one example: | |
(sc/atomic ctx | ||
(with-open [cursor (sc/fetch-lazy ctx sql {:fetch-size 10})] | ||
(doseq [item (sc/cursor->lazyseq cursor)] | ||
(doseq [item (sc/cursor->seq cursor)] | ||
(println item)))) | ||
;; This should print something similar to: | ||
|
@@ -285,8 +256,8 @@ sequence. Let's see one example: | |
;; ... | ||
---- | ||
|
||
The third parameter of `sc/fetch-lazy` function is the optional default fetch | ||
size (currently 100.) | ||
The third parameter of `sc/fetch-lazy` function is the optional. The | ||
default fetch size is `128`. | ||
|
||
|
||
=== Custom types | ||
|
@@ -357,59 +328,16 @@ contains a work in progress of the new approach. | |
|
||
If you want play with that look tests code to see how it works. | ||
|
||
|
||
== FAQ | ||
|
||
=== Why I should use suricatta instead of clojure.jdbc or java.jdbc? | ||
=== Why I should use suricatta instead of next.jdbc or java.jdbc? | ||
|
||
Unlike any jdbc library, _suricatta_ works at a slightly higher level. It hides a | ||
lot of idiosyncrasies of jdbc under a much *simpler, cleaner and less error prone | ||
api*, with better resource management. | ||
|
||
|
||
=== Where is the async support? | ||
|
||
In previous version _suricatta_ it had come with asynchronous support using | ||
core.async channels as response but since the version 0.4.0 it is removed because | ||
core.async is not a proper abstraction for represent a promise. | ||
|
||
In the jvm world, the proper promise abstraction is introduced in JDK8 so using | ||
that abstraction will force people use JDK8, something that I don't want to do at | ||
this moment. | ||
|
||
The great news is that async support is stil very easy implement, so you can do | ||
it in your own code base defining two additional functions. Here a code snippet | ||
for it: | ||
|
||
[source, clojure] | ||
---- | ||
(require '[suricatta.core :as sc] | ||
'[cats.monad.exception :as exc] | ||
'[promissum.core :as p]) | ||
(defn execute | ||
"Execute a query asynchronously returning a CompletableFuture." | ||
([ctx q] | ||
(execute ctx q {})) | ||
([ctx q opts] | ||
(let [act (.-act ctx) | ||
fun #(% (exc/try-on (sc/execute ctx q)))] | ||
(p/promise | ||
(fn [deliver] | ||
(send-off act (fn [_] (fun deliver)))))))) | ||
(defn fetch | ||
"Execute a query asynchronously returning a CompletableFuture." | ||
([ctx q] | ||
(fetch ctx q {})) | ||
([ctx q opts] | ||
(let [act (.-act ctx) | ||
fun #(% (exc/try-on (sc/fetch ctx q opts)))] | ||
(p/promise | ||
(fn [deliver] | ||
(send-off act (fn [_] (fun deliver)))))))) | ||
---- | ||
|
||
|
||
=== Why another dsl? Is it just yet another dsl? | ||
|
||
First _suricatta_ is not a dsl library, it's a sql toolkit, and one part of the | ||
|
@@ -419,13 +347,14 @@ Secondly, _suricatta_'s dsl's don't intends to be a sql abstraction. The real | |
purpose of _suricatta_'s dsl is make SQL composable while still allowing use all or | ||
almost all vendor specific sql constructions. | ||
|
||
|
||
=== What are some suricatta use cases? | ||
|
||
The _suricatta_ library is very flexible and it can be used in very different ways: | ||
|
||
- You can build queries with _suricatta_ and execute them with _clojure.jdbc_. | ||
- You can build queries with _suricatta_ and execute them with _next.jdbc_. | ||
- You can use _suricatta_ for executing queries with string-based sql. | ||
- You can combine the _suricatta_ library with _clojure.jdbc_. | ||
- You can combine the _suricatta_ library with _next.jdbc_. | ||
- And obviously, you can forget jdbc and use _suricatta_ for both purposes, building | ||
and/or executing queries. | ||
|
||
|
@@ -496,15 +425,15 @@ git clone https://github.com/funcool/suricatta | |
|
||
[source, text] | ||
---- | ||
lein test | ||
clojure -Adev:test | ||
---- | ||
|
||
=== License | ||
|
||
_suricatta_ is licensed under BSD (2-Clause) license: | ||
|
||
---- | ||
Copyright (c) 2014-2015 Andrey Antukh <[email protected]> | ||
Copyright (c) 2014-2019 Andrey Antukh <[email protected]> | ||
All rights reserved. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
;; HOW TO RUN: clojure -J-Xmx128m -Adev:bench scripts/bench.clj | ||
|
||
(require '[criterium.core :as b]) | ||
(require '[next.jdbc :as jdbc]) | ||
(require '[next.jdbc.result-set :as jdbc-rs]) | ||
(require '[suricatta.core :as sc]) | ||
|
||
(def uri "jdbc:postgresql://127.0.0.1/test") | ||
|
||
(def conn1 (jdbc/get-connection uri)) | ||
(def conn2 (sc/context uri)) | ||
|
||
(def sql1 "SELECT x FROM generate_series(1, 1000) as x;") | ||
|
||
(defn test-next-jdbc1 | ||
[] | ||
(let [result (jdbc/execute! conn1 [sql1] {:builder-fn jdbc-rs/as-unqualified-lower-maps})] | ||
(with-out-str | ||
(prn result)))) | ||
|
||
(defn test-suricatta1 | ||
[] | ||
(let [result (sc/fetch conn2 sql1)] | ||
(with-out-str | ||
(prn result)))) | ||
|
||
(println "***** START: next.jdbc (1) *****") | ||
;; (b/with-progress-reporting (b/quick-bench (test-next-jdbc1) :verbose)) | ||
(b/quick-bench (test-next-jdbc1)) | ||
(println "***** END: next.jdbc (1) *****") | ||
|
||
(println "***** START: suricatta (1) *****") | ||
;; (b/with-progress-reporting (b/quick-bench (test-suricatta1) :verbose)) | ||
(b/quick-bench (test-suricatta1)) | ||
(println "***** END: suricatta (1) *****") | ||
|
||
|
Oops, something went wrong.