Last active
June 30, 2019 18:48
-
-
Save danielneal/6e543eafda4289389a75283ef22b948c to your computer and use it in GitHub Desktop.
compound2
This file contains hidden or 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
(ns compound2.core3) | |
(defprotocol Index | |
:extend-via-metadata true | |
(before [this o]) | |
(after [this o]) | |
(kfn [this o x]) | |
(vfn [this o x]) | |
(lookup [this o k] [this o k not-found]) | |
(index [this o k v]) | |
(unindex [this o k])) | |
(defn transact | |
[c k & args] | |
(case k | |
:add-items | |
(let [[o xs] args] | |
(after c | |
(reduce (fn [o x] | |
(index c o (kfn c o x) (vfn c o x))) | |
(before c o) | |
xs))) | |
:remove-items | |
(let [[o xs] args] | |
(after c | |
(reduce (fn [o x] | |
(unindex c o (kfn c o x))) | |
(before c o) | |
xs))) | |
:remove-keys | |
(let [[o ks] args] | |
(after c | |
(reduce (fn [o k] | |
(unindex c o k)) | |
(before c o) | |
ks))))) | |
(def transactor | |
(reify clojure.lang.ILookup | |
(valAt [this k] (partial transact this k)))) | |
(defn with-impl | |
[index m] | |
(vary-meta index merge m)) | |
(defn with-hash-map [index] | |
(with-impl index {`before (fn [c m] (or m {})) | |
`after (fn [c m] m) | |
`lookup (fn [c & args] (apply get args)) | |
`index (fn [c m k x] (assoc m k x)) | |
`unindex (fn [c m k] (dissoc m k))})) | |
(defn with-transient-map [index] | |
(with-impl index {`before (fn [c m] (transient (or m {}))) | |
`after (fn [c m] (persistent! m)) | |
`lookup (fn [c & args] (apply get args)) | |
`index (fn [c m k x] (assoc! m k x)) | |
`unindex (fn [c m k] (dissoc! m k))})) | |
(defn with-multiple-entries [index] | |
(with-impl index {`vfn (fn [c o x] (conj (lookup index o (kfn index o x) #{}) (vfn index o x)))})) | |
(defn basic-index [opts] | |
(let [{:keys [kfn]} opts] | |
(-> transactor | |
(with-impl {`kfn (fn [c m x] (kfn x)) | |
`vfn (fn [c m x] x)}) | |
(with-hash-map)))) | |
(let [{:keys [add-items remove-keys]} (basic-index {:kfn :id})] | |
(def add-products add-items) | |
(def remove-products remove-keys)) | |
(add-products {} [{:id 1, :sku "Asdfs"} | |
{:id 2, :sku "Asdfasd"}]) | |
;; => {1 {:id 1, :sku "Asdfs"}, | |
;; 2 {:id 2, :sku "Asdfasd"}} | |
(-> (add-products {} [{:id 1, :sku "Asdfs"} | |
{:id 2, :sku "Asdfasd"}]) | |
(remove-products [1])) | |
;; => {2 {:id 2, :sku "Asdfasd"}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment