Skip to content

Instantly share code, notes, and snippets.

@pesterhazy
Last active December 7, 2020 11:13
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save pesterhazy/699455c956759c793c9802cf7ad4714b to your computer and use it in GitHub Desktop.
Save pesterhazy/699455c956759c793c9802cf7ad4714b to your computer and use it in GitHub Desktop.
Inspect a datomic entity's history
;; Show history of an entity
;;
;; useful for interactively inspecting what happened to a datomic entity in its lifetime
;;
;; use `entity-history` to get a list of transactions that have touched the entity (assertions, retractions)
;;
;; use `explain-tx` to find out what else was transacted in the txs
(defn entity-history
"Takes an entity and shows all the transactions that touched this entity.
Pairs well with clojure.pprint/print-table"
[db eid]
(->> eid
(d/q
'[:find ?e ?a ?v ?tx ?added
:in $ ?e
:where
[?e ?a ?v ?tx ?added]]
(datomic.api/history db))
(map #(->> %
(map vector [:e :a :v :tx :added])
(into {})))
(sort-by :tx)))
(defn pretty-datom [d] (into {} (map (fn [x] [x (x d)]) [:e :a :v :tx :added])))
(defn resolve-attr [db {:keys [a] :as datom}]
(assoc datom
:a
(->> a (d/entity db) :db/ident)))
(defn explain-tx
"Takes a tx id and returns a prettified list of all datoms contained in the
transaction. N.b. takes a conn, not a db.
Pairs well with clojure.pprint/print-table"
[conn tx]
(->> (d/tx-range (d/log conn) tx nil)
first
:data
(map pretty-datom)
(map (partial resolve-attr (d/db conn)))
(sort-by :e)))
@kenbier
Copy link

kenbier commented Dec 7, 2017

Note you can get the attribute history in the entity-history query, rather than hitting the entity api N times as in the gist above.
If you only care about the historical view of a single entity, this is all you need:

(defn entity-history
    "Takes an entity and shows all the transactions that touched this entity.
  Pairs well with clojure.pprint/print-table"
    [db eid]
    (->> eid
         (d/q
          '[:find ?e ?attr ?v ?tx ?added ?inst
            :in $ ?e
            :where
            [?e ?a ?v ?tx ?added]
            [?tx :db/txInstant ?inst]
            [?a :db/ident ?attr]]
          (datomic.api/history db))
         (map #(->> %
                    (map vector [:e :a :v :tx :added :inst])
                    (into {})))
         (sort-by :tx)))

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