Skip to content

Instantly share code, notes, and snippets.

@stuarthalloway
Last active March 31, 2017 21:40
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuarthalloway/9160152 to your computer and use it in GitHub Desktop.
Save stuarthalloway/9160152 to your computer and use it in GitHub Desktop.
Complete schema history of a live Datomic database
;; Complete schema history for a live Datomic database.
(require
'[clojure.pprint :as pp]
'[clojure.set :as set]
'[datomic.api :as d])
;; fill this in with your own database connection
(def uri "datomic:dev://localhost:4334/my-db")
(def conn (d/connect uri))
(def db (d/db conn))
;; helpers
(def ^java.text.Format formatter (java.text.SimpleDateFormat. "yyyy-MM-dd kk:mm:ss"))
(defn format-inst
[inst]
(.format formatter inst))
(defprotocol Shorten
(shorten [_x] "Scrunch things up to fit in a text table"))
(extend-protocol Shorten
java.lang.Object
(shorten [s] s)
java.lang.String
(shorten [s] (if (< (count s) 20)
s
(subs s 0 20)))
clojure.lang.Keyword
(shorten [k]
(if (and (namespace k)
(.startsWith (namespace k) "db"))
(keyword (name k))
k))
java.util.Date
(shorten [d] (format-inst d)))
(defn schema-history
"Returns a map with
:op install or alter
:entity ident of schema entity
:attr ident of schema entity's attribute
:val value of attribute
:t database time t this fact was recorded
:inst wall clock time t this fact was recorded"
([db] (schema-history db false))
([db include-bootstrap?]
(->> (d/q '[:find ?op ?ent ?attr ?val ?tx
:in $ [?op ...]
:where
[0 ?op ?ent ?tx]
[?ent ?attr ?val ?tx]]
(d/history db)
[:db.install/attribute :db.alter/attribute])
(sort-by #(nth % 4))
(map (fn [[op ent attr v tx]]
{:op (case op
:db.install/attribute 'install
:db.alter/attribute 'alter)
:entity (d/ident db ent)
:attr (d/ident db attr)
:val (if (= :db.type/ref (:value-type (d/attribute db attr)))
(d/ident db v)
v)
:t (d/tx->t tx)
:inst (:db/txInstant (d/entity db tx))}))
(filter (if include-bootstrap?
identity
(fn [{:keys [t]}] (>= t 1000)))))))
;; data form
(schema-history db true)
;; print org-mode table of database history
(binding [*print-length* nil]
(->> (schema-history db true)
(map #(reduce
(fn [m [k v]] (assoc m k (shorten v)))
{} %))
(pp/print-table
[:op :entity :attr :val :t :inst])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment