Add mechanism for data migrations
This commit is contained in:
parent
ce56fb65c6
commit
54c57e085a
4 changed files with 137 additions and 32 deletions
|
|
@ -4,6 +4,7 @@
|
|||
[clojure.string :as str]
|
||||
[clojure.pprint :as pprint]
|
||||
[computersandblues.lodestone.database :as db]
|
||||
[computersandblues.lodestone.interop :refer [promise-all promise-resolve promise-reject]]
|
||||
[computersandblues.lodestone.match :refer [query->matching-xform]]
|
||||
[applied-science.js-interop :as j]))
|
||||
|
||||
|
|
@ -34,15 +35,6 @@
|
|||
|
||||
;; Mastodon API helpers
|
||||
|
||||
(defn- promise-all [xs]
|
||||
(js/Promise.all (apply array xs)))
|
||||
|
||||
(defn- promise-resolve [val]
|
||||
(js/Promise.resolve val))
|
||||
|
||||
(defn- promise-reject [val]
|
||||
(js/Promise.reject val))
|
||||
|
||||
(defn- now []
|
||||
(js/Date.now))
|
||||
|
||||
|
|
@ -560,26 +552,45 @@
|
|||
|
||||
;; database
|
||||
|
||||
(def db-version 3)
|
||||
;;; we provide two different kinds of migrations
|
||||
;;;
|
||||
;;; - structural migrations
|
||||
;;; - data migrations
|
||||
;;;
|
||||
;;; this is necessary due to the constraints imposed on us by indexeddb.
|
||||
;;;
|
||||
;;; structural migrations run in a callback after opening the database. they run
|
||||
;;; synchronously and do things like creates stores and indices. because they run
|
||||
;;; synchronously, they cannot modify any of the stored data.
|
||||
;;;
|
||||
;;; data migrations can do that! they run after all structural migrations for
|
||||
;;; the current database version have succeeded, and work on the open database.
|
||||
;;;
|
||||
;;; note that for each db-version, there needs to be at least one structural or
|
||||
;;; data migration. it is fine to have both for a single version, in which case
|
||||
;;; the structural migration will run first.
|
||||
|
||||
(def migrations
|
||||
{1 (fn migration-0001 [db _]
|
||||
(def db-version 4)
|
||||
|
||||
(def structural-migrations
|
||||
{1 (fn =0001-create-stores [db _]
|
||||
(db/create-object-store! db ::db/application {:keyPath "id"})
|
||||
(db/create-object-store! db ::db/posts {:keyPath "id"}))
|
||||
2 (fn migration-0002 [_ txn]
|
||||
2 (fn =0002-add-post-created-at-idx [_ txn]
|
||||
(-> (db/open-store txn ::db/posts "readwrite")
|
||||
(db/create-index! ::db/post-created-at "created_at" {:unique false})))
|
||||
3 (fn migration-0003 [_ txn]
|
||||
3 (fn =0003-add-post-internal-id-idx [_ txn]
|
||||
(-> (db/open-store txn ::db/posts "readwrite")
|
||||
(db/create-index! ::db/post-internal-id "internal_id" {:unique false})))})
|
||||
|
||||
(defn- convert-internal-ids! []
|
||||
; TODO figure out when we can remove this again
|
||||
(let [cursor (db/open-cursor ::db/posts ::db/all)
|
||||
result (db/transduce-cursor (filter (comp string? (j/get :internal_id))) cursor)]
|
||||
(.then result (fn [rows]
|
||||
(doseq [row rows]
|
||||
(db/put! ::db/posts (j/update! row :internal_id parse-long)))))))
|
||||
(def data-migrations
|
||||
{4 (fn =0004-convert-internal-ids [db]
|
||||
(let [cursor (db/open-cursor db ::db/posts ::db/post-internal-id ::db/all)
|
||||
result (db/transduce-cursor (filter (comp string? (j/get :internal_id))) cursor)]
|
||||
(.then result
|
||||
(fn [rows]
|
||||
(promise-all (for [row rows]
|
||||
(db/put! ::db/posts (j/update! row :internal_id parse-long))))))))})
|
||||
|
||||
;; go go go
|
||||
|
||||
|
|
@ -589,8 +600,7 @@
|
|||
(defn init []
|
||||
(swap! state assoc :root (rd/create-root (js/document.querySelector "#root")))
|
||||
(render)
|
||||
(-> (db/setup! ::database db-version migrations)
|
||||
(-> (db/setup! ::database db-version structural-migrations data-migrations)
|
||||
(.then #(setup-application!))
|
||||
(.then #(convert-internal-ids!))
|
||||
(.catch (fn [err]
|
||||
(js/console.error ::db/setup! err)))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue