first pass of caching formatter
needs more documentation. Initial results suggest a speedup for simple queries of 2-3x. Complex queries can see up to 20x speedup.
This commit is contained in:
parent
91e054c58b
commit
826407e9db
5 changed files with 85 additions and 5 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
* 2.2.next in progress
|
||||
* Address #377 by adding `honey.sql/map=` to convert a hash map into an equality condition (for a `WHERE` clause).
|
||||
* Address #351 by adding a `:cache` option to `honey.sql/format` (for Clojure only, not ClojureScript).
|
||||
* Address #281 by adding support for `SELECT * EXCEPT ..` and `SELECT * REPLACE ..` and `ARRAY<>` and `STRUCT<>` column types -- see [SQL Clause Reference - SELECT](https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT/doc/getting-started/sql-clause-reference#select-select-distinct) and [SQL Clause Reference - DDL](https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT/doc/getting-started/sql-clause-reference#ddl-clauses) respectively for more details.
|
||||
* Update `build-clj` to v0.6.7.
|
||||
|
||||
|
|
|
|||
3
deps.edn
3
deps.edn
|
|
@ -16,7 +16,8 @@
|
|||
:test
|
||||
{:extra-paths ["test"]
|
||||
:extra-deps {io.github.cognitect-labs/test-runner
|
||||
{:git/tag "v0.5.0" :git/sha "48c3c67"}}
|
||||
{:git/tag "v0.5.0" :git/sha "48c3c67"}
|
||||
org.clojure/core.cache {:mvn/version "RELEASE"}}
|
||||
:exec-fn cognitect.test-runner.api/test}
|
||||
|
||||
;; various "runners" for tests/CI:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2020-2021 sean corfield, all rights reserved
|
||||
;; copyright (c) 2020-2022 sean corfield, all rights reserved
|
||||
|
||||
(ns honey.sql
|
||||
"Primary API for HoneySQL 2.x.
|
||||
|
|
@ -1374,7 +1374,8 @@
|
|||
as named arguments followed by other options in a hash map."
|
||||
([data] (format data {}))
|
||||
([data opts]
|
||||
(let [dialect? (contains? opts :dialect)
|
||||
(let [cache (:cache opts)
|
||||
dialect? (contains? opts :dialect)
|
||||
dialect (when dialect? (get dialects (check-dialect (:dialect opts))))]
|
||||
(binding [*dialect* (if dialect? dialect @default-dialect)
|
||||
*checking* (if (contains? opts :checking)
|
||||
|
|
@ -1397,7 +1398,16 @@
|
|||
(:quoted-snake opts))
|
||||
*params* (:params opts)
|
||||
*values-default-columns* (:values-default-columns opts)]
|
||||
(mapv #(unwrap % opts) (format-dsl data opts)))))
|
||||
(if cache
|
||||
#?(:clj
|
||||
;; prefer requiring-resolve but that's 1.10+ only:
|
||||
(let [_ (require 'clojure.core.cache.wrapped)
|
||||
through (resolve 'clojure.core.cache.wrapped/lookup-or-miss)]
|
||||
(->> (through cache data (fn [_] (format-dsl data (dissoc opts :cache))))
|
||||
(mapv #(unwrap % opts))))
|
||||
:cljs
|
||||
(throw (ex-info "cached queries are not supported in ClojureScript" opts)))
|
||||
(mapv #(unwrap % opts) (format-dsl data opts))))))
|
||||
([data k v & {:as opts}] (format data (assoc opts k v))))
|
||||
|
||||
(defn set-dialect!
|
||||
|
|
|
|||
68
test/honey/cache_test.clj
Normal file
68
test/honey/cache_test.clj
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
;; copyright (c) 2022 sean corfield, all rights reserved
|
||||
|
||||
(ns honey.cache-test
|
||||
(:refer-clojure :exclude [format group-by])
|
||||
(:require [clojure.core.cache.wrapped :as cache]
|
||||
[clojure.test :refer [deftest is]]
|
||||
[honey.sql :as sut]
|
||||
[honey.sql.helpers
|
||||
:refer [select-distinct from join left-join right-join where
|
||||
group-by having order-by limit offset]]))
|
||||
|
||||
(def big-complicated-map
|
||||
(-> (select-distinct :f.* :b.baz :c.quux [:b.bla "bla-bla"]
|
||||
[[:now]] [[:raw "@x := 10"]])
|
||||
(from [:foo :f] [:baz :b])
|
||||
(join :draq [:= :f.b :draq.x]
|
||||
:eldr [:= :f.e :eldr.t])
|
||||
(left-join [:clod :c] [:= :f.a :c.d])
|
||||
(right-join :bock [:= :bock.z :c.e])
|
||||
(where [:or
|
||||
[:and [:= :f.a "bort"] [:not= :b.baz [:param :param1]]]
|
||||
[:and [:< 1 2] [:< 2 3]]
|
||||
[:in :f.e [1 [:param :param2] 3]]
|
||||
[:between :f.e 10 20]])
|
||||
(group-by :f.a :c.e)
|
||||
(having [:< 0 :f.e])
|
||||
(order-by [:b.baz :desc] :c.quux [:f.a :nulls-first])
|
||||
(limit 50)
|
||||
(offset 10)))
|
||||
|
||||
(deftest cache-tests
|
||||
(let [cache (cache/basic-cache-factory {})]
|
||||
(is (= ["SELECT * FROM table WHERE id = ?" 1]
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id 1]}
|
||||
{:cache cache})
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id 1]}
|
||||
{:cache cache})))
|
||||
(is (= (sut/format {:select [:*] :from [:table] :where [:= :id 1]})
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id 1]}
|
||||
{:cache cache})))
|
||||
(is (= (sut/format big-complicated-map {:params {:param1 "gabba" :param2 2}})
|
||||
(sut/format big-complicated-map {:cache cache :params {:param1 "gabba" :param2 2}})
|
||||
(sut/format big-complicated-map {:cache cache :params {:param1 "gabba" :param2 2}})))
|
||||
(is (= (sut/format big-complicated-map {:params {:param1 "foo" :param2 42}})
|
||||
(sut/format big-complicated-map {:cache cache :params {:param1 "foo" :param2 42}})
|
||||
(sut/format big-complicated-map {:cache cache :params {:param1 "foo" :param2 42}})))
|
||||
(println "Uncached, simple, embedded")
|
||||
(time (dotimes [_ 100000]
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id 1]})))
|
||||
(println "Cached, simple, embedded")
|
||||
(time (dotimes [_ 100000]
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id 1]} {:cache cache})))
|
||||
(println "Uncached, complex, mixed")
|
||||
(time (dotimes [_ 10000]
|
||||
(sut/format big-complicated-map {:params {:param1 "gabba" :param2 2}})))
|
||||
(println "Cached, complex, mixed")
|
||||
(time (dotimes [_ 10000]
|
||||
(sut/format big-complicated-map {:cache cache :params {:param1 "gabba" :param2 2}}))))
|
||||
(let [cache (cache/basic-cache-factory {})]
|
||||
(is (= ["SELECT * FROM table WHERE id = ?" 1]
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id :?id]}
|
||||
{:cache cache :params {:id 1}})
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id :?id]}
|
||||
{:cache cache :params {:id 1}})))
|
||||
(is (= (sut/format {:select [:*] :from [:table] :where [:= :id :?id]}
|
||||
{:params {:id 2}})
|
||||
(sut/format {:select [:*] :from [:table] :where [:= :id :?id]}
|
||||
{:cache cache :params {:id 2}})))))
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2021 sean corfield, all rights reserved
|
||||
;; copyright (c) 2021-2022 sean corfield, all rights reserved
|
||||
|
||||
(ns honey.sql-test
|
||||
(:refer-clojure :exclude [format])
|
||||
|
|
|
|||
Loading…
Reference in a new issue