Skip to content

Instantly share code, notes, and snippets.

@favila
Last active October 16, 2019 13:14
Show Gist options
  • Save favila/8ed9e06f5cab2e35bf25 to your computer and use it in GitHub Desktop.
Save favila/8ed9e06f5cab2e35bf25 to your computer and use it in GitHub Desktop.
enity-changes Return transaction history for a datomic entity and its components.
(require '[datomic.api :as d])
(defn entity-changes
"Return transaction history for an entity and its components.
Returns a sequence of maps, each is the transaction map (tx metadata) plus a
key `:entity-changes`, which is a nested map of keys: entity id, attribute
ident, `:db/add` or `:db/retract`, and the value added or retracted, e.g.:
{12345678910 {:long-card-1-attr {:db/retract 1
:db/add 0}
:long-card-many-attr {:db/add #{0}}
:ref-card-1-component-attr {:db/add 12345678911}}
12345678911 {:long-card-1-attr {:db/add 2}}}`"
[db root-entity]
(->> (d/q '[:find ?e ?kw ?v ?added ?tx
:in % ?root $hist
:where
($hist ent+comp ?root ?e ?a ?v ?tx ?added)
[(datomic.api/ident $hist ?a) ?kw]]
'[[(ent+comp [?root] ?e ?a ?v ?tx ?added)
[?root ?nexta ?root2]
[?nexta :db/isComponent true]
(ent+comp ?root2 ?e ?a ?v ?tx ?added)]
[(ent+comp [?root] ?e ?a ?v ?tx ?added)
[?root ?a ?v ?tx ?added]
[(identity ?root) ?e]]]
(d/entid db root-entity)
(d/history db))
(group-by peek)
(sort-by key)
(map (fn [[tx datoms]]
(assoc (d/pull db '[*] tx)
:entity-changes
(->> datoms
(map #(vec (take 4 %)))
(sort-by peek)
(reduce (fn [acc [e a v add?]]
(if (= (:cardinality (d/attribute db a)) :db.cardinality/many)
(update-in acc [e a (if add? :db/add :db/retract)] (fnil conj #{}) v)
(assoc-in acc [e a (if add? :db/add :db/retract)] v))) {})))))))
@dpsutton
Copy link

(defn is-attribute-change? [attribute thing]
  (contains? (->> thing :entity-changes
                  vals
                  (mapcat keys)
                  set)
             attribute))

so that you can easily do

(filter (partial is-attribute-change? :fhir.Encounter/status$cr)
        encounter-changes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment