New table extraction code for full views.
This commit is contained in:
parent
9f47500451
commit
e89800e099
|
@ -1,4 +1,4 @@
|
|||
(defproject views "0.5.0"
|
||||
(defproject views "0.5.1"
|
||||
:description "You underestimate the power of the SQL side"
|
||||
|
||||
:url "https://github.com/diligenceengine/views"
|
||||
|
|
|
@ -38,9 +38,8 @@
|
|||
(defn have-overlapping-tables?
|
||||
"Takes two Honeysql hash-maps, one for action, one for view, and returns
|
||||
boolean value representing whether or not their set of tables intersect."
|
||||
[action view]
|
||||
(->> [action view]
|
||||
(map (comp set #(map first %) vh/extract-tables))
|
||||
(apply intersection)
|
||||
seq
|
||||
boolean))
|
||||
[action view refresh?]
|
||||
(let [a (set (map first (vh/extract-tables action)))]
|
||||
(if refresh?
|
||||
(boolean (seq (intersection a (vh/query-tables view))))
|
||||
(boolean (seq (intersection a (set (map first (vh/extract-tables view)))))))))
|
||||
|
|
|
@ -310,7 +310,7 @@
|
|||
as the original :view-sig the deltas apply to."
|
||||
[persistence namespace schema db all-views action templates]
|
||||
(j/with-db-transaction [t db :isolation :serializable]
|
||||
(let [filtered-views (filterv #(vc/have-overlapping-tables? action (:view %)) all-views)
|
||||
(let [filtered-views (filterv #(vc/have-overlapping-tables? action (:view %) (:refresh-only? %)) all-views)
|
||||
{full-refresh-views true normal-views nil} (group-by :refresh-only? filtered-views)
|
||||
need-deltas (map #(generate-view-delta-map % action) normal-views)
|
||||
table (-> action vh/extract-tables ffirst)
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
(defn process-complex-clause
|
||||
[tables clause]
|
||||
(reduce
|
||||
#(if (coll? %2)
|
||||
#(if (coll? %2)
|
||||
(if (some pred-ops [(first %2)])
|
||||
%1
|
||||
(conj %1 %2))
|
||||
(conj %1 [%2]))
|
||||
tables
|
||||
clause))
|
||||
tables
|
||||
clause))
|
||||
|
||||
(defn extract-tables*
|
||||
[tables clause]
|
||||
|
@ -31,12 +31,6 @@
|
|||
(conj tables [clause]))
|
||||
tables))
|
||||
|
||||
(defn with-op
|
||||
"Takes a collection of things and returns either an nary op of them, or
|
||||
the item in the collection if there is only one."
|
||||
[op coll]
|
||||
(if (> (count coll) 1) (into [op] coll) (first coll)))
|
||||
|
||||
(defn extract-tables
|
||||
"Extracts a set of table vector from a HoneySQL spec hash-map.
|
||||
Each vector either contains a single table keyword, or the
|
||||
|
@ -44,6 +38,74 @@
|
|||
([hh-spec] (extract-tables hh-spec table-clauses))
|
||||
([hh-spec clauses] (reduce #(extract-tables* %1 (%2 hh-spec)) #{} clauses)))
|
||||
|
||||
;; The following is used for full refresh views where we can have CTEs and
|
||||
;; subselects in play.
|
||||
|
||||
(declare query-tables)
|
||||
|
||||
(defn cte-tables
|
||||
[query]
|
||||
(mapcat #(query-tables (second %)) (:with query)))
|
||||
|
||||
(defn isolate-tables
|
||||
"Isolates tables from table definitions in from and join clauses."
|
||||
[c]
|
||||
(if (keyword? c) [c] (let [v (first c)] (if (map? v) (query-tables v) [v]))))
|
||||
|
||||
(defn from-tables
|
||||
[query]
|
||||
(mapcat isolate-tables (:from query)))
|
||||
|
||||
(defn every-second
|
||||
[coll]
|
||||
(map first (partition 2 coll)))
|
||||
|
||||
(defn join-tables
|
||||
[query k]
|
||||
(mapcat isolate-tables (every-second (k query))))
|
||||
|
||||
(defn collect-maps
|
||||
[coll]
|
||||
(let[maps (filterv map? coll)
|
||||
colls (filter #(and (coll? %) (not (map? %))) coll)]
|
||||
(into maps (mapcat collect-maps colls))))
|
||||
|
||||
(defn where-tables
|
||||
"This search for subqueries in the where clause."
|
||||
[query]
|
||||
(mapcat query-tables (collect-maps (:where query))))
|
||||
|
||||
(defn insert-tables
|
||||
[query]
|
||||
(if-let [v (:insert-into query)] [v] []))
|
||||
|
||||
(defn update-tables
|
||||
[query]
|
||||
(if-let [v (:update query)] [v] []))
|
||||
|
||||
(defn delete-tables
|
||||
[query]
|
||||
(if-let [v (:delete-from query)] [v] []))
|
||||
|
||||
(defn query-tables
|
||||
[query]
|
||||
(set (concat
|
||||
(cte-tables query)
|
||||
(from-tables query)
|
||||
(join-tables query :join)
|
||||
(join-tables query :left-join)
|
||||
(join-tables query :right-join)
|
||||
(where-tables query)
|
||||
(insert-tables query)
|
||||
(update-tables query)
|
||||
(delete-tables query))))
|
||||
|
||||
(defn with-op
|
||||
"Takes a collection of things and returns either an nary op of them, or
|
||||
the item in the collection if there is only one."
|
||||
[op coll]
|
||||
(if (> (count coll) 1) (into [op] coll) (first coll)))
|
||||
|
||||
(defn find-table-aliases
|
||||
"Returns the table alias for the supplied table."
|
||||
[action-table tables]
|
||||
|
|
|
@ -34,6 +34,30 @@
|
|||
(is (= (vh/extract-tables join-with-alias-test) #{[:foo] [:bar :b]}))
|
||||
(is (= (vh/extract-tables join-and-from-with-alias-test) #{[:foo :f] [:bar :b]})))
|
||||
|
||||
(def cte-test
|
||||
{:with [[:a {:select [:*] :from [:bar]}]]
|
||||
:select [:*] :from [:foo]})
|
||||
|
||||
(def from-subselect-test
|
||||
{:select [:*] :from [[{:select [:*] :from [:foo]} :a]]})
|
||||
|
||||
(def where-subselect-test
|
||||
{:select [:*] :from [:foo] :where [:in :a {:select [:*] :from [:bar]}]})
|
||||
|
||||
(def nested-where-subselect-test
|
||||
{:select [:*] :from [:foo] :where [:and [:in :a {:select [:*] :from [:bar]}] [:in :a {:select [:*] :from [:baz]}]]})
|
||||
|
||||
(deftest extracts-tables-from-full-refresh-specs
|
||||
(is (= (vh/query-tables simple-test) #{:foo}))
|
||||
(is (= (vh/query-tables insert-test) #{:foo}))
|
||||
(is (= (vh/query-tables join-test) #{:foo :bar}))
|
||||
(is (= (vh/query-tables join-with-alias-test) #{:foo :bar}))
|
||||
(is (= (vh/query-tables join-and-from-with-alias-test) #{:foo :bar}))
|
||||
(is (= (vh/query-tables cte-test) #{:foo :bar}))
|
||||
(is (= (vh/query-tables from-subselect-test) #{:foo}))
|
||||
(is (= (vh/query-tables where-subselect-test) #{:foo :bar}))
|
||||
(is (= (vh/query-tables nested-where-subselect-test) #{:foo :bar :baz})))
|
||||
|
||||
;; Do we really need to test the new version?
|
||||
(deftest merges-where-clauses
|
||||
(is (= (vh/merge-where-clauses [:= :foo 1] [:= :bar 2])
|
||||
|
|
Loading…
Reference in a new issue