1 Schema migration guide
Roman Volosovskyi edited this page 2017-07-30 10:18:18 +03:00
;; While working on the status-react codebase, from time to time, some properties of persisted objects
;; can be added/removed, their semantics can change, or whole new kind of objects need to be persisted 
;; (or deleted).
;; In such situation, realm database schema need to be changed and maybe, even migration/s need to be specified.
;; Lets suppose we need to add boolean property `:unremovable?` to all chat objects persisted in realm.
;; First, we need to add new schema to schemas defined in accounts:
(ns status.im.data-store.realm.schemas.account.core
  (:require [status.im.data-store.realm.schemas.account.v1.core :as v1]
            ;; all the other versions between v1 and v(N)
            ;; require your v(N+1) schema file, in this case, v11
            [status.im.data-store.realm.schemas.account.v11.core :as v11]))
  
  ;; put schemas ordered by version
  (def schemas [{:schema        v1/schema
                 :schemaVersion 1
                 :migration     v1/migration}
                ;; all the other schemas
                ;; your new schema
                {:schema        v1/schema
                 :schemaVersion 11
                 :migration     v11/migration}])
   
;; With that in place, create new file for v11.core by copying the latest schema (v10.core in this case) and updating 
;; filename and ns to N+1.
;; Then inside the new file, update required namespace/s for object which will be changed, for example we will replace
[status-im.data-store.realm.schemas.account.v4.chat :as chat]
;; by
[status-im.data-store.realm.schemas.account.v11.chat :as chat]
;; If you are wondering why the version jump from v4 to v11, it's because realm schema for the chats was changed for last
;; in version v4, and v4-v10.core schema namespaces just required it. 
;; Now you need to create file for `status-im.data-store.realm.schemas.account.v11.chat` and define new chat schema there.
;; If you don't need to do any custom migrations, you are finished, upon startup the new schema will be applied.
;; When you need some custom migration, implement function `migration` for example for v11.chat:
(defn migration [old-realm new-realm]
  (log/debug "migrating chat schema v11")
  ;; make sure that console chat has `:unremovable?` set to true
  (when-let [console-chat (-> new-realm
                              (.objects "chat")
                              (.filtered "chat-id = \"console\"")
                              (aget 0))]
    (aset console-chat "unremovable?" true)))

;; And don't forget to call that function from v11.core namespace (chat is alias for v11.chat ns):
(defn migration [old-realm new-realm]
  (log/debug "migrating v11 account database: " old-realm new-realm)
  (chat/migration old-realm new-realm))