Skip to content

Instantly share code, notes, and snippets.

@janherich
Last active July 30, 2017 06:04
Show Gist options
  • Save janherich/3d8379259b9d5c1487083a549195ad7d to your computer and use it in GitHub Desktop.
Save janherich/3d8379259b9d5c1487083a549195ad7d to your computer and use it in GitHub Desktop.
How to perform realm schema changes with optional database migrations
;; 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))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment