Building a txn to restore a partition's datoms


#1

Before applying a fairly extensive data transaction, I’d like to assure myself that I can easily restore the database to a specific point in time. Obviously I have datomic’s external restore capability to rely on, which is great, but for the purpose of this exercise, I’d like to generate a txn that, when applied, ensures that the contents of the user partition match the contents of the user partition at a given time.

I sketched this out, does anyone see any obvious flaws:

(defn restore-to
  [db t]
  (let [db' (d/as-of db t)
        user-vs-by-ea (reduce (fn [accum [e a v]]
                                (cond-> accum
                                  ;; only look at entities in the user partition
                                  (= 4 (d/part e))
                                  (update [e a] (fnil conj #{}) v)))
                              {}
                              (seq (d/datoms db :eavt)))]
    (into []
          (mapcat (fn [[[e a] vs]]
                    ;; vs are whare are currently true
                    ;; vs' are what we want to be true
                    (let [vs' (set (map :v (seq (d/datoms db' :eavt e a))))]
                      (concat
                       (for [v (set/difference vs' vs)]
                         [:db/add e a v])
                       (for [v (set/difference vs vs')]
                         [:db/remove e a v])))))
          user-vs-by-ea)))

Obviously here the entire datom set has to fit in memory, though one could do it in a single lazy pass by keeping track of the current e and a values. Performance aside, are there any problems I have not foreseen?