subscribing stores compiled views
This commit is contained in:
parent
e901e70057
commit
3dc546e192
|
@ -11,7 +11,7 @@
|
||||||
[clojure.java.jdbc :as j]
|
[clojure.java.jdbc :as j]
|
||||||
[clojure.tools.logging :refer [debug]]
|
[clojure.tools.logging :refer [debug]]
|
||||||
[views.honeysql :as vh]
|
[views.honeysql :as vh]
|
||||||
[views.subscribed-views :refer [get-subscribed-views broadcast-deltas]]))
|
[views.subscribed-views :refer [subscribed-views broadcast-deltas]]))
|
||||||
|
|
||||||
(defn get-primary-key
|
(defn get-primary-key
|
||||||
"Get a primary key for a table."
|
"Get a primary key for a table."
|
||||||
|
@ -468,7 +468,7 @@
|
||||||
calculate for them and associated with the hash-maps (appropriately
|
calculate for them and associated with the hash-maps (appropriately
|
||||||
called views-with-deltas)."
|
called views-with-deltas)."
|
||||||
[schema db action-map subscribed-views]
|
[schema db action-map subscribed-views]
|
||||||
(let [subbed-views (get-subscribed-views subscribed-views db)
|
(let [subbed-views (subscribed-views subscribed-views db)
|
||||||
transaction-fn #(do-view-transaction schema db subbed-views action-map)]
|
transaction-fn #(do-view-transaction schema db subbed-views action-map)]
|
||||||
(if-let [deltas (:deltas db)] ;; inside a transaction we just collect deltas and do not retry
|
(if-let [deltas (:deltas db)] ;; inside a transaction we just collect deltas and do not retry
|
||||||
(let [{:keys [views-with-deltas result-set]} (transaction-fn)]
|
(let [{:keys [views-with-deltas result-set]} (transaction-fn)]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
(ns views.subscriptions)
|
(ns views.subscriptions
|
||||||
|
(:require
|
||||||
|
[views.db :as vdb]))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; {[:view-sig 1 "arg2"] {:keys [1 2 3 4 ... ] :view-map {:view ...}}}
|
;; {[:view-sig 1 "arg2"] {:keys [1 2 3 4 ... ] :view-map {:view ...}}}
|
||||||
|
@ -18,20 +20,26 @@
|
||||||
(conj view-subs subscriber-key)
|
(conj view-subs subscriber-key)
|
||||||
#{subscriber-key})))
|
#{subscriber-key})))
|
||||||
|
|
||||||
|
(defn- add-compiled-view!
|
||||||
|
[view-sig templates]
|
||||||
|
(swap! compiled-views #(assoc % view-sig (vdb/view-map (get-in templates [(first view-sig) :fn]) view-sig))))
|
||||||
|
|
||||||
(defn add-subscription!
|
(defn add-subscription!
|
||||||
([subscriber-key view-sig]
|
([subscriber-key view-sig templates]
|
||||||
(swap! subscribed-views #(update-in % [view-sig] (add-subscriber-key subscriber-key))))
|
(swap! subscribed-views #(update-in % [view-sig] (add-subscriber-key subscriber-key)))
|
||||||
([subscriber-key view-sig prefix]
|
(add-compiled-view! view-sig templates))
|
||||||
(swap! subscribed-views #(update-in % [prefix view-sig] (add-subscriber-key subscriber-key)))))
|
([subscriber-key view-sig templates prefix]
|
||||||
|
(swap! subscribed-views #(update-in % [prefix view-sig] (add-subscriber-key subscriber-key)))
|
||||||
|
(add-compiled-view! view-sig templates)))
|
||||||
|
|
||||||
(defn add-subscriptions!
|
(defn add-subscriptions!
|
||||||
([subscriber-key view-sigs]
|
([subscriber-key view-sigs templates]
|
||||||
(add-subscriptions! subscriber-key view-sigs nil))
|
(add-subscriptions! subscriber-key view-sigs templates nil))
|
||||||
([subscriber-key view-sigs prefix]
|
([subscriber-key view-sigs templates prefix]
|
||||||
(doseq [vs view-sigs]
|
(doseq [vs view-sigs]
|
||||||
(if prefix
|
(if prefix
|
||||||
(add-subscription! subscriber-key vs prefix)
|
(add-subscription! subscriber-key vs templates prefix)
|
||||||
(add-subscription! subscriber-key vs)))))
|
(add-subscription! subscriber-key vs templates)))))
|
||||||
|
|
||||||
(defn subscribed-to
|
(defn subscribed-to
|
||||||
([view-sig]
|
([view-sig]
|
||||||
|
@ -53,9 +61,10 @@
|
||||||
updated (update-in subbed-views path disj subscriber-key)]
|
updated (update-in subbed-views path disj subscriber-key)]
|
||||||
(if (seq (get-in updated path))
|
(if (seq (get-in updated path))
|
||||||
updated
|
updated
|
||||||
(if prefix
|
(do (swap! compiled-views dissoc view-sig) ; remove the compiled view as well
|
||||||
(update-in updated [prefix] dissoc view-sig)
|
(if prefix
|
||||||
(dissoc updated view-sig))))))
|
(update-in updated [prefix] dissoc view-sig)
|
||||||
|
(dissoc updated view-sig)))))))
|
||||||
|
|
||||||
(defn remove-subscription!
|
(defn remove-subscription!
|
||||||
([subscriber-key view-sig]
|
([subscriber-key view-sig]
|
||||||
|
@ -63,3 +72,7 @@
|
||||||
([subscriber-key view-sig prefix]
|
([subscriber-key view-sig prefix]
|
||||||
(when (subscribed-to? subscriber-key view-sig (if prefix prefix))
|
(when (subscribed-to? subscriber-key view-sig (if prefix prefix))
|
||||||
(swap! subscribed-views (remove-key-or-view subscriber-key view-sig prefix)))))
|
(swap! subscribed-views (remove-key-or-view subscriber-key view-sig prefix)))))
|
||||||
|
|
||||||
|
(defn compiled-view-for
|
||||||
|
[view-sig]
|
||||||
|
(get @compiled-views view-sig))
|
||||||
|
|
|
@ -2,26 +2,12 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.test :refer [use-fixtures deftest is]]
|
[clojure.test :refer [use-fixtures deftest is]]
|
||||||
[honeysql.core :as hsql]
|
[honeysql.core :as hsql]
|
||||||
[views.fixtures :as vf :refer [gen-n-users! database-fixtures!]]
|
[views.fixtures :as vf :refer [gen-n-users! database-fixtures! templates]]
|
||||||
[views.db.core :as vdb]
|
[views.db.core :as vdb]
|
||||||
[clojure.string :refer [upper-case]]))
|
[clojure.string :refer [upper-case]]))
|
||||||
|
|
||||||
(use-fixtures :each database-fixtures!)
|
(use-fixtures :each database-fixtures!)
|
||||||
|
|
||||||
(defn users-tmpl
|
|
||||||
[]
|
|
||||||
(hsql/build :select [:id :name :created_on] :from :users))
|
|
||||||
|
|
||||||
(defn user-posts-tmpl
|
|
||||||
[user_id]
|
|
||||||
(hsql/build :select [:u.user_id :u.name :p.title :p.body :p.created_on]
|
|
||||||
:from {:posts :p}
|
|
||||||
:join [[:users :u][:= :user_id user_id]]))
|
|
||||||
|
|
||||||
(def templates
|
|
||||||
{:users {:fn #'users-tmpl}
|
|
||||||
:user-posts {:fn #'user-posts-tmpl}})
|
|
||||||
|
|
||||||
(defn subscribed-views
|
(defn subscribed-views
|
||||||
[]
|
[]
|
||||||
{[:users] {:view-map ((get-in templates [:users :fn]))}})
|
{[:users] {:view-map ((get-in templates [:users :fn]))}})
|
||||||
|
|
|
@ -52,3 +52,17 @@
|
||||||
(dotimes [n n]
|
(dotimes [n n]
|
||||||
(user-fixture! (dg/string #(rand-nth (seq "abcdefghijklmnopqrstuwvxyz")))))
|
(user-fixture! (dg/string #(rand-nth (seq "abcdefghijklmnopqrstuwvxyz")))))
|
||||||
(j/query db ["SELECT * FROM users"]))
|
(j/query db ["SELECT * FROM users"]))
|
||||||
|
|
||||||
|
(defn users-tmpl
|
||||||
|
[]
|
||||||
|
(hsql/build :select [:id :name :created_on] :from :users))
|
||||||
|
|
||||||
|
(defn user-posts-tmpl
|
||||||
|
[user_id]
|
||||||
|
(hsql/build :select [:u.user_id :u.name :p.title :p.body :p.created_on]
|
||||||
|
:from {:posts :p}
|
||||||
|
:join [[:users :u][:= :user_id user_id]]))
|
||||||
|
|
||||||
|
(def templates
|
||||||
|
{:users {:fn #'users-tmpl}
|
||||||
|
:user-posts {:fn #'user-posts-tmpl}})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns views.subscriptions-test
|
(ns views.subscriptions-test
|
||||||
(:require
|
(:require
|
||||||
[clojure.test :refer [use-fixtures deftest is]]
|
[clojure.test :refer [use-fixtures deftest is]]
|
||||||
|
[views.fixtures :refer [templates user-posts-tmpl]]
|
||||||
[views.subscriptions :as vs]))
|
[views.subscriptions :as vs]))
|
||||||
|
|
||||||
(defn- reset-subscribed-views!
|
(defn- reset-subscribed-views!
|
||||||
|
@ -11,49 +12,55 @@
|
||||||
(use-fixtures :each reset-subscribed-views!)
|
(use-fixtures :each reset-subscribed-views!)
|
||||||
|
|
||||||
(deftest adds-a-subscription
|
(deftest adds-a-subscription
|
||||||
(let [key 1, view-sig [:view 1]]
|
(let [key 1, view-sig [:user-posts 1]]
|
||||||
(vs/add-subscription! key view-sig)
|
(vs/add-subscription! key view-sig templates)
|
||||||
(is (vs/subscribed-to? key view-sig))))
|
(is (vs/subscribed-to? key view-sig))))
|
||||||
|
|
||||||
(deftest can-use-prefix
|
(deftest can-use-prefix
|
||||||
(let [prefix1 1, prefix2 2, key 1, view-sig [:view 1]]
|
(let [prefix1 1, prefix2 2, key 1, view-sig [:user-posts 1]]
|
||||||
(vs/add-subscription! key view-sig prefix1)
|
(vs/add-subscription! key view-sig templates prefix1)
|
||||||
(vs/add-subscription! key view-sig prefix2)
|
(vs/add-subscription! key view-sig templates prefix2)
|
||||||
(is (vs/subscribed-to? key view-sig prefix1))
|
(is (vs/subscribed-to? key view-sig prefix1))
|
||||||
(is (vs/subscribed-to? key view-sig prefix2))))
|
(is (vs/subscribed-to? key view-sig prefix2))))
|
||||||
|
|
||||||
(deftest removes-a-subscription
|
(deftest removes-a-subscription
|
||||||
(let [key 1, view-sig [:view 1]]
|
(let [key 1, view-sig [:user-posts 1]]
|
||||||
(vs/add-subscription! key view-sig)
|
(vs/add-subscription! key view-sig templates)
|
||||||
(vs/remove-subscription! key view-sig)
|
(vs/remove-subscription! key view-sig)
|
||||||
(is (not (vs/subscribed-to? key view-sig)))))
|
(is (not (vs/subscribed-to? key view-sig)))))
|
||||||
|
|
||||||
(deftest doesnt-fail-or-create-view-entry-when-empty
|
(deftest doesnt-fail-or-create-view-entry-when-empty
|
||||||
(vs/remove-subscription! 1 [:view 1])
|
(vs/remove-subscription! 1 [:user-posts 1])
|
||||||
(is (= {} @vs/subscribed-views)))
|
(is (= {} @vs/subscribed-views)))
|
||||||
|
|
||||||
(deftest removes-a-subscription-with-prefix
|
(deftest removes-a-subscription-with-prefix
|
||||||
(let [prefix1 1, prefix2 2, key 1, view-sig [:view 1]]
|
(let [prefix1 1, prefix2 2, key 1, view-sig [:user-posts 1]]
|
||||||
(vs/add-subscription! key view-sig prefix1)
|
(vs/add-subscription! key view-sig templates prefix1)
|
||||||
(vs/add-subscription! key view-sig prefix2)
|
(vs/add-subscription! key view-sig templates prefix2)
|
||||||
(vs/remove-subscription! key view-sig prefix1)
|
(vs/remove-subscription! key view-sig prefix1)
|
||||||
(is (not (vs/subscribed-to? key view-sig prefix1)))
|
(is (not (vs/subscribed-to? key view-sig prefix1)))
|
||||||
(is (vs/subscribed-to? key view-sig prefix2))))
|
(is (vs/subscribed-to? key view-sig prefix2))))
|
||||||
|
|
||||||
(deftest removes-unsubscribed-to-view-from-subscribed-views
|
(deftest removes-unsubscribed-to-view-from-subscribed-views
|
||||||
(let [key 1, view-sig [:view 1]]
|
(let [key 1, view-sig [:user-posts 1]]
|
||||||
(vs/add-subscription! key view-sig)
|
(vs/add-subscription! key view-sig templates)
|
||||||
(vs/remove-subscription! key view-sig)
|
(vs/remove-subscription! key view-sig)
|
||||||
(is (= {} @vs/subscribed-views))))
|
(is (= {} @vs/subscribed-views))))
|
||||||
|
|
||||||
(deftest adds-multiple-views-at-a-time
|
(deftest adds-multiple-views-at-a-time
|
||||||
(let [key 1, view-sigs [[:view 1] [:view 2]]]
|
(let [key 1, view-sigs [[:user-posts 1] [:user-posts 2]]]
|
||||||
(vs/add-subscriptions! key view-sigs)
|
(vs/add-subscriptions! key view-sigs templates)
|
||||||
(is (vs/subscribed-to? key (first view-sigs)))
|
(is (vs/subscribed-to? key (first view-sigs)))
|
||||||
(is (vs/subscribed-to? key (last view-sigs)))))
|
(is (vs/subscribed-to? key (last view-sigs)))))
|
||||||
|
|
||||||
;; (deftest subscribing-compiles-and-stores-view-maps
|
(deftest subscribing-compiles-and-stores-view-maps
|
||||||
;; (let [key 1, view-sig [:view 1]]
|
(let [key 1, view-sig [:user-posts 1]]
|
||||||
;; (vs/add-subscriptions! key view-sigs)
|
(vs/add-subscription! key view-sig templates)
|
||||||
;; (is (vs/subscribed-to? key (first view-sigs)))
|
(is (= (:view (vs/compiled-view-for [:user-posts 1]))
|
||||||
;; (is (vs/subscribed-to? key (last view-sigs)))))
|
(user-posts-tmpl 1)))))
|
||||||
|
|
||||||
|
(deftest removing-last-view-sub-removes-compiled-view
|
||||||
|
(let [key 1, view-sig [:user-posts 1]]
|
||||||
|
(vs/add-subscription! key view-sig templates)
|
||||||
|
(vs/remove-subscription! key view-sig)
|
||||||
|
(is (nil? (vs/compiled-view-for [:user-posts 1])))))
|
||||||
|
|
Loading…
Reference in a new issue