From 2c3eec3c43975d1bfaaf9685c063e84d8919f865 Mon Sep 17 00:00:00 2001 From: Adrian Tiberius Date: Tue, 4 Oct 2016 14:49:59 +0300 Subject: [PATCH] added database migration functionality Former-commit-id: a6f63a5b5f2ec8fbecd07f975694d2fbb94f1137 --- src/status_im/accounts/handlers.cljs | 12 +- src/status_im/accounts/login/handlers.cljs | 12 +- .../accounts/recover/validations.cljs | 3 +- src/status_im/android/core.cljs | 2 +- src/status_im/chat/handlers.cljs | 44 ++--- .../chat/handlers/receive_message.cljs | 12 +- src/status_im/chat/handlers/requests.cljs | 22 +-- src/status_im/chat/handlers/send_message.cljs | 6 +- .../chat/handlers/unviewed_messages.cljs | 11 +- src/status_im/chat/styles/message_input.cljs | 2 +- src/status_im/chat/subs.cljs | 4 +- src/status_im/chat/views/message.cljs | 1 - src/status_im/commands/handlers/loading.cljs | 7 +- src/status_im/contacts/handlers.cljs | 10 +- src/status_im/contacts/validations.cljs | 4 +- src/status_im/data_store/accounts.cljs | 14 ++ src/status_im/data_store/chats.cljs | 73 +++++++ src/status_im/data_store/commands.cljs | 10 + src/status_im/data_store/contacts.cljs | 28 +++ src/status_im/data_store/core.cljs | 10 + src/status_im/data_store/discovery.cljs | 23 +++ src/status_im/data_store/messages.cljs | 92 +++++++++ .../data_store/pending_messages.cljs | 48 +++++ src/status_im/data_store/realm/accounts.cljs | 21 ++ src/status_im/data_store/realm/chats.cljs | 112 +++++++++++ src/status_im/data_store/realm/commands.cljs | 11 ++ src/status_im/data_store/realm/contacts.cljs | 25 +++ src/status_im/data_store/realm/core.cljs | 187 ++++++++++++++++++ src/status_im/data_store/realm/discovery.cljs | 73 +++++++ src/status_im/data_store/realm/messages.cljs | 55 ++++++ .../data_store/realm/pending_messages.cljs | 35 ++++ src/status_im/data_store/realm/requests.cljs | 40 ++++ .../realm/schemas/account/core.cljs | 7 + .../schemas/account/v1/chat-contact.cljs | 10 + .../realm/schemas/account/v1/chat.cljs | 30 +++ .../realm/schemas/account/v1/command.cljs | 10 + .../realm/schemas/account/v1/contact.cljs | 21 ++ .../realm/schemas/account/v1/core.cljs | 39 ++++ .../realm/schemas/account/v1/discovery.cljs | 17 ++ .../realm/schemas/account/v1/kv_store.cljs | 10 + .../realm/schemas/account/v1/message.cljs | 32 +++ .../schemas/account/v1/pending_message.cljs | 22 +++ .../realm/schemas/account/v1/request.cljs | 13 ++ .../realm/schemas/account/v1/tag.cljs | 10 + .../realm/schemas/account/v1/user_status.cljs | 12 ++ .../data_store/realm/schemas/base/core.cljs | 7 + .../realm/schemas/base/v1/account.cljs | 22 +++ .../realm/schemas/base/v1/core.cljs | 12 ++ .../realm/schemas/base/v1/kv_store.cljs | 10 + src/status_im/data_store/requests.cljs | 22 +++ src/status_im/discovery/handlers.cljs | 12 +- src/status_im/discovery/model.cljs | 67 ------- src/status_im/group_settings/handlers.cljs | 35 ++-- src/status_im/handlers.cljs | 4 +- src/status_im/ios/core.cljs | 2 +- src/status_im/models/accounts.cljs | 21 -- src/status_im/models/chats.cljs | 141 ------------- src/status_im/models/contacts.cljs | 50 ----- src/status_im/models/messages.cljs | 89 --------- src/status_im/models/pending_messages.cljs | 60 ------ src/status_im/models/requests.cljs | 21 -- src/status_im/new_group/handlers.cljs | 6 +- src/status_im/persistence/realm/core.cljs | 185 ----------------- src/status_im/persistence/realm/schemas.cljs | 147 -------------- src/status_im/persistence/realm_queries.cljs | 19 -- src/status_im/protocol/handlers.cljs | 73 ++++--- 66 files changed, 1285 insertions(+), 962 deletions(-) create mode 100644 src/status_im/data_store/accounts.cljs create mode 100644 src/status_im/data_store/chats.cljs create mode 100644 src/status_im/data_store/commands.cljs create mode 100644 src/status_im/data_store/contacts.cljs create mode 100644 src/status_im/data_store/core.cljs create mode 100644 src/status_im/data_store/discovery.cljs create mode 100644 src/status_im/data_store/messages.cljs create mode 100644 src/status_im/data_store/pending_messages.cljs create mode 100644 src/status_im/data_store/realm/accounts.cljs create mode 100644 src/status_im/data_store/realm/chats.cljs create mode 100644 src/status_im/data_store/realm/commands.cljs create mode 100644 src/status_im/data_store/realm/contacts.cljs create mode 100644 src/status_im/data_store/realm/core.cljs create mode 100644 src/status_im/data_store/realm/discovery.cljs create mode 100644 src/status_im/data_store/realm/messages.cljs create mode 100644 src/status_im/data_store/realm/pending_messages.cljs create mode 100644 src/status_im/data_store/realm/requests.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/core.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/chat-contact.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/chat.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/command.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/contact.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/core.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/discovery.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/kv_store.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/message.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/pending_message.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/request.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/tag.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v1/user_status.cljs create mode 100644 src/status_im/data_store/realm/schemas/base/core.cljs create mode 100644 src/status_im/data_store/realm/schemas/base/v1/account.cljs create mode 100644 src/status_im/data_store/realm/schemas/base/v1/core.cljs create mode 100644 src/status_im/data_store/realm/schemas/base/v1/kv_store.cljs create mode 100644 src/status_im/data_store/requests.cljs delete mode 100644 src/status_im/discovery/model.cljs delete mode 100644 src/status_im/models/accounts.cljs delete mode 100644 src/status_im/models/chats.cljs delete mode 100644 src/status_im/models/contacts.cljs delete mode 100644 src/status_im/models/messages.cljs delete mode 100644 src/status_im/models/pending_messages.cljs delete mode 100644 src/status_im/models/requests.cljs delete mode 100644 src/status_im/persistence/realm/core.cljs delete mode 100644 src/status_im/persistence/realm/schemas.cljs delete mode 100644 src/status_im/persistence/realm_queries.cljs diff --git a/src/status_im/accounts/handlers.cljs b/src/status_im/accounts/handlers.cljs index c51f875511..dedc90dfa9 100644 --- a/src/status_im/accounts/handlers.cljs +++ b/src/status_im/accounts/handlers.cljs @@ -1,5 +1,5 @@ (ns status-im.accounts.handlers - (:require [status-im.models.accounts :as accounts-model] + (:require [status-im.data-store.accounts :as accounts-store] [re-frame.core :refer [register-handler after dispatch dispatch-sync debug]] [taoensso.timbre :as log] [status-im.protocol.core :as protocol] @@ -19,7 +19,7 @@ (defn save-account [_ [_ account]] - (accounts-model/save-accounts [account] true)) + (accounts-store/save account true)) (register-handler :add-account @@ -54,9 +54,9 @@ password #(account-created % password))))) -(defn save-account-to-realm! +(defn save-account! [{:keys [current-account-id accounts]} _] - (accounts-model/save-accounts [(get accounts current-account-id)] true)) + (accounts-store/save (get accounts current-account-id) true)) (defn send-account-update [{:keys [current-account-id current-public-key web3 accounts]} _] @@ -79,7 +79,7 @@ account (-> (get accounts current-account-id) (merge data))] (assoc-in db [:accounts current-account-id] account))) - ((after save-account-to-realm!)) + ((after save-account!)) ((after send-account-update)))) (register-handler @@ -103,7 +103,7 @@ (register-handler :set-current-account set-current-account) (defn load-accounts! [db _] - (let [accounts (->> (accounts-model/get-accounts) + (let [accounts (->> (accounts-store/get-all) (map (fn [{:keys [address] :as account}] [address account])) (into {}))] diff --git a/src/status_im/accounts/login/handlers.cljs b/src/status_im/accounts/login/handlers.cljs index 9fb7dc550f..5f39b17cfa 100644 --- a/src/status_im/accounts/login/handlers.cljs +++ b/src/status_im/accounts/login/handlers.cljs @@ -4,7 +4,7 @@ [taoensso.timbre :as log] [status-im.utils.types :refer [json->clj]] [status-im.db :refer [default-view]] - [status-im.persistence.realm.core :as realm] + [status-im.data-store.core :as data-store] [status-im.components.status :as status] [status-im.constants :refer [console-chat-id]])) @@ -29,24 +29,24 @@ (dispatch [:navigate-to default-view])))) (register-handler - :change-realm-account + :change-account (u/side-effect! (fn [db [_ address new-account? callback]] - (realm/change-account-realm address new-account? - #(callback % address new-account?))))) + (data-store/change-account address new-account? + #(callback % address new-account?))))) (defn on-account-changed [error address new-account?] (if (nil? error) (initialize-account address new-account?) - (log/debug "Error changing acount realm: " error))) + (log/debug "Error changing acount: " error))) (defn logged-in [db address] (let [is-login-screen? (= (:view-id db) :login) new-account? (not is-login-screen?)] (log/debug "Logged in: ") - (dispatch [:change-realm-account address new-account? on-account-changed]))) + (dispatch [:change-account address new-account? on-account-changed]))) (register-handler :login-account diff --git a/src/status_im/accounts/recover/validations.cljs b/src/status_im/accounts/recover/validations.cljs index e6fdc7ca90..1c9d30c7e1 100644 --- a/src/status_im/accounts/recover/validations.cljs +++ b/src/status_im/accounts/recover/validations.cljs @@ -1,7 +1,6 @@ (ns status-im.accounts.recover.validations (:require [cljs.spec :as s] - [cljsjs.web3] - [status-im.persistence.realm.core :as realm])) + [cljsjs.web3])) (s/def ::not-empty-string (s/and string? not-empty)) (s/def ::passphrase ::not-empty-string) diff --git a/src/status_im/android/core.cljs b/src/status_im/android/core.cljs index 4156377057..be77a6c3fa 100644 --- a/src/status_im/android/core.cljs +++ b/src/status_im/android/core.cljs @@ -26,7 +26,7 @@ [status-im.group-settings.screen :refer [group-settings]] [status-im.profile.screen :refer [profile my-profile]] [status-im.profile.photo-capture.screen :refer [profile-photo-capture]] - status-im.persistence.realm.core + status-im.data-store.core [taoensso.timbre :as log] [status-im.components.status :as status])) diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 23850a59a5..1052ba3a25 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -6,10 +6,10 @@ [status-im.components.styles :refer [default-chat-color]] [status-im.chat.suggestions :as suggestions] [status-im.protocol.core :as protocol] - [status-im.models.chats :as chats] - [status-im.models.contacts :as contacts] - [status-im.models.messages :as messages] - [status-im.models.pending-messages :as pending-messages] + [status-im.data-store.chats :as chats] + [status-im.data-store.contacts :as contacts] + [status-im.data-store.messages :as messages] + [status-im.data-store.pending-messages :as pending-messages] [status-im.constants :refer [text-content-type content-type-command content-type-command-request @@ -18,7 +18,6 @@ [status-im.chat.sign-up :as sign-up-service] [status-im.navigation.handlers :as nav] [status-im.utils.handlers :refer [register-handler] :as u] - [status-im.persistence.realm.core :as r] [status-im.handlers.server :as server] [status-im.utils.phone-number :refer [format-phone-number valid-mobile-number?]] @@ -61,7 +60,7 @@ db (let [messages-path [:chats current-chat-id :messages] messages (get-in db messages-path) - new-messages (messages/get-messages current-chat-id (count messages)) + new-messages (messages/get-by-chat-id current-chat-id (count messages)) all-loaded? (> default-number-of-messages (count new-messages))] (-> db (assoc :loading-allowed false) @@ -179,8 +178,8 @@ (if (chats console-chat-id) db (do - (chats/create-chat new-chat) - (contacts/save-contacts [sign-up-service/console-contact]) + (chats/save new-chat) + (contacts/save-all [sign-up-service/console-contact]) (sign-up-service/intro) (when existing-account? (sign-up-service/start-signup)) @@ -228,7 +227,7 @@ (defn load-messages! ([db] (load-messages! db nil)) ([{:keys [current-chat-id] :as db} _] - (assoc db :messages (messages/get-messages current-chat-id)))) + (assoc db :messages (messages/get-by-chat-id current-chat-id)))) (defn init-chat ([db] (init-chat db nil)) @@ -261,7 +260,7 @@ (defn load-chats! [db _] - (assoc db :loaded-chats (chats/chats-list))) + (assoc db :loaded-chats (chats/get-all))) ;TODO: check if its new account / signup status / create console chat (register-handler :initialize-chats @@ -304,7 +303,7 @@ (defn save-new-chat! [{:keys [new-chat]} _] - (chats/create-chat new-chat)) + (chats/save new-chat)) (defn open-chat! [_ [_ chat-id _ navigation-type]] @@ -341,7 +340,7 @@ ; todo do we really need this message? (defn leaving-message! [{:keys [current-chat-id]} _] - (messages/save-message + (messages/save current-chat-id {:from "system" :message-id (random/id) @@ -351,24 +350,15 @@ (defn delete-messages! [{:keys [current-chat-id]} [_ chat-id]] (let [id (or chat-id current-chat-id)] - (r/write :account - (fn [] - (r/delete :account - (r/get-by-field :account :message :chat-id id)))))) + (messages/delete-by-chat-id id))) (defn delete-chat! [_ [_ chat-id]] - (r/write :account - (fn [] :account - (when-let [chat (->> (r/get-by-field :account :chat :chat-id chat-id) - (r/single))] - (doto chat - (aset "is-active" false) - (aset "removed-at" (.getTime (js/Date.)))))))) + (chats/delete chat-id)) (defn remove-pending-messages! [_ [_ chat-id]] - (pending-messages/remove-all-by-chat chat-id)) + (pending-messages/delete-all-by-chat-id chat-id)) (register-handler :leave-group-chat ;; todo oreder of operations tbd @@ -435,8 +425,8 @@ :message-id message-id}})))) (register-handler :send-seen! [(after (fn [_ [_ {:keys [message-id]}]] - (messages/update-message! {:message-id message-id - :message-status :seen}))) + (messages/update {:message-id message-id + :message-status :seen}))) (after (fn [_ [_ {:keys [chat-id]}]] (dispatch [:remove-unviewed-messages chat-id])))] (u/side-effect! send-seen!)) @@ -457,7 +447,7 @@ (defn update-chat! [_ [_ chat]] - (chats/update-chat chat)) + (chats/save chat)) (register-handler :update-chat! (-> (fn [db [_ {:keys [chat-id] :as chat}]] diff --git a/src/status_im/chat/handlers/receive_message.cljs b/src/status_im/chat/handlers/receive_message.cljs index 388ec1d4d7..c05181b614 100644 --- a/src/status_im/chat/handlers/receive_message.cljs +++ b/src/status_im/chat/handlers/receive_message.cljs @@ -1,12 +1,12 @@ (ns status-im.chat.handlers.receive-message (:require [status-im.utils.handlers :refer [register-handler] :as u] [re-frame.core :refer [enrich after debug dispatch path]] - [status-im.models.messages :as messages] + [status-im.data-store.messages :as messages] [status-im.chat.utils :as cu] [status-im.commands.utils :refer [generate-hiccup]] [status-im.constants :refer [content-type-command-request]] [cljs.reader :refer [read-string]] - [status-im.models.chats :as c])) + [status-im.data-store.chats :as chats])) (defn check-preview [{:keys [content] :as message}] (if-let [preview (:preview content)] @@ -17,7 +17,7 @@ message)) (defn store-message [{chat-id :chat-id :as message}] - (messages/save-message chat-id (dissoc message :rendered-preview :new?))) + (messages/save chat-id (dissoc message :rendered-preview :new?))) (defn get-current-identity [{:keys [current-account-id accounts]}] @@ -25,11 +25,11 @@ (defn receive-message [db [_ {:keys [from group-id chat-id message-id] :as message}]] - (let [same-message (messages/get-message message-id) + (let [same-message (messages/get-by-id message-id) current-identity (get-current-identity db) chat-id' (or group-id chat-id from) - exists? (c/chat-exists? chat-id') - active? (c/is-active? chat-id')] + exists? (chats/exists? chat-id') + active? (chats/is-active? chat-id')] (when (and (not same-message) (not= from current-identity) (or (not exists?) active?)) diff --git a/src/status_im/chat/handlers/requests.cljs b/src/status_im/chat/handlers/requests.cljs index a4bd6a4788..60488c7914 100644 --- a/src/status_im/chat/handlers/requests.cljs +++ b/src/status_im/chat/handlers/requests.cljs @@ -1,13 +1,12 @@ (ns status-im.chat.handlers.requests (:require [re-frame.core :refer [after dispatch enrich]] [status-im.utils.handlers :refer [register-handler]] - [status-im.models.requests :as requests] - [status-im.utils.handlers :refer [register-handler] :as u] - [status-im.persistence.realm.core :as realm])) + [status-im.data-store.requests :as requests] + [status-im.utils.handlers :refer [register-handler] :as u])) (defn store-request! [{:keys [new-request] :as db}] - (requests/save-request new-request)) + (requests/save new-request)) (defn add-request [db [_ chat-id {:keys [message-id content]}]] @@ -23,23 +22,14 @@ (defn load-requests! [{:keys [current-chat-id] :as db} [_ chat-id]] (let [chat-id' (or chat-id current-chat-id) - requests (-> ;; todo maybe limit is needed - (realm/get-by-fields :account :request :and [[:chat-id chat-id'] - [:status "open"]]) - (realm/sorted :added :desc) - (realm/realm-collection->list)) + ;; todo maybe limit is needed + requests (requests/get-open-by-chat-id chat-id') requests' (map #(update % :type keyword) requests)] (assoc-in db [:chats chat-id' :requests] requests'))) (defn mark-request-as-answered! [_ [_ chat-id message-id]] - (realm/write :account - (fn [] - (-> (realm/get-by-fields :account :request :and [[:chat-id chat-id] - [:message-id message-id]]) - (realm/single) - (.-status) - (set! "answered"))))) + (requests/mark-as-answered chat-id message-id)) (register-handler :add-request (after store-request!) diff --git a/src/status_im/chat/handlers/send_message.cljs b/src/status_im/chat/handlers/send_message.cljs index db40b1ce8a..0dcbe78501 100644 --- a/src/status_im/chat/handlers/send_message.cljs +++ b/src/status_im/chat/handlers/send_message.cljs @@ -1,7 +1,7 @@ (ns status-im.chat.handlers.send-message (:require [status-im.utils.handlers :refer [register-handler] :as u] [clojure.string :as s] - [status-im.models.messages :as messages] + [status-im.data-store.messages :as messages] [status-im.components.status :as status] [status-im.utils.random :as random] [status-im.utils.datetime :as time] @@ -97,7 +97,7 @@ (register-handler ::save-command! (u/side-effect! (fn [{:keys [current-public-key]} [_ {:keys [command chat-id]}]] - (messages/save-message + (messages/save chat-id (dissoc command :rendered-preview :to-message :has-handler))))) @@ -154,7 +154,7 @@ (dispatch [::send-message! params]))) (u/side-effect! (fn [_ [_ {:keys [chat-id message]}]] - (messages/save-message chat-id message)))) + (messages/save chat-id message)))) (register-handler ::send-message! (u/side-effect! diff --git a/src/status_im/chat/handlers/unviewed_messages.cljs b/src/status_im/chat/handlers/unviewed_messages.cljs index d25beb18fe..45196cf146 100644 --- a/src/status_im/chat/handlers/unviewed_messages.cljs +++ b/src/status_im/chat/handlers/unviewed_messages.cljs @@ -1,12 +1,7 @@ (ns status-im.chat.handlers.unviewed-messages (:require [re-frame.core :refer [after enrich path dispatch]] [status-im.utils.handlers :refer [register-handler]] - [status-im.persistence.realm.core :as realm])) - -(defn delivered-messages [] - (-> (realm/get-by-fields :account :message :and {:outgoing false - :message-status nil}) - (realm/realm-collection->list))) + [status-im.data-store.messages :as messages])) (defn set-unviewed-messages [db] (let [messages (->> (::raw-unviewed-messages db) @@ -20,7 +15,7 @@ (dissoc ::raw-unviewed-messages)))) (defn load-messages! [db] - (let [messages (delivered-messages)] + (let [messages (messages/get-unviewed)] (assoc db ::raw-unviewed-messages messages))) (register-handler ::set-unviewed-messages set-unviewed-messages) @@ -39,4 +34,4 @@ (register-handler :remove-unviewed-messages (path :unviewed-messages) (fn [db [_ chat-id]] - (dissoc db chat-id))) + (dissoc db chat-id))) \ No newline at end of file diff --git a/src/status_im/chat/styles/message_input.cljs b/src/status_im/chat/styles/message_input.cljs index 0e840690d0..9f17e54bc1 100644 --- a/src/status_im/chat/styles/message_input.cljs +++ b/src/status_im/chat/styles/message_input.cljs @@ -44,4 +44,4 @@ {:margin-top 10.5 :margin-left 12 :width 15 - :height 15}) + :height 15}) \ No newline at end of file diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index 99529f9f6a..89b73abe12 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -3,7 +3,7 @@ (:require [re-frame.core :refer [register-sub dispatch subscribe path]] [status-im.utils.platform :refer [ios?]] [status-im.models.commands :as commands] - [status-im.models.chats :as chats] + [status-im.data-store.chats :as chats] [status-im.constants :refer [response-suggesstion-resize-duration]] [status-im.chat.constants :as c] [status-im.chat.views.plain-message :as plain-message] @@ -50,7 +50,7 @@ (register-sub :get-chat-by-id (fn [_ [_ chat-id]] - (reaction (chats/chat-by-id chat-id)))) + (reaction (chats/get-by-id chat-id)))) (register-sub :get-responses (fn [db _] diff --git a/src/status_im/chat/views/message.cljs b/src/status_im/chat/views/message.cljs index 3cdca5cfe6..55827f9953 100644 --- a/src/status_im/chat/views/message.cljs +++ b/src/status_im/chat/views/message.cljs @@ -13,7 +13,6 @@ [status-im.chat.views.request-message :refer [message-content-command-request]] [status-im.chat.styles.message :as st] [status-im.chat.styles.command-pill :as pill-st] - [status-im.models.chats :refer [chat-by-id]] [status-im.models.commands :refer [parse-command-message-content parse-command-request]] [status-im.resources :as res] diff --git a/src/status_im/commands/handlers/loading.cljs b/src/status_im/commands/handlers/loading.cljs index 28f1f0d6f8..84889ec1bf 100644 --- a/src/status_im/commands/handlers/loading.cljs +++ b/src/status_im/commands/handlers/loading.cljs @@ -4,7 +4,7 @@ [status-im.utils.handlers :as u] [status-im.utils.utils :refer [http-get show-popup]] [clojure.string :as s] - [status-im.persistence.realm.core :as realm] + [status-im.data-store.commands :as commands] [status-im.components.status :as status] [status-im.utils.types :refer [json->clj]] [status-im.commands.utils :refer [reg-handler]] @@ -16,8 +16,7 @@ [_ [identity]] (dispatch [::fetch-commands! identity]) ;; todo uncomment - #_(if-let [{:keys [file]} (realm/get-one-by-field :account :command - :chat-id identity)] + #_(if-let [{:keys [file]} (commands/get-by-chat-id identity)] (dispatch [::parse-commands! identity file]) (dispatch [::fetch-commands! identity]))) @@ -85,7 +84,7 @@ (defn save-commands-js! [_ [id file]] - (realm/create-object :account :command {:chat-id id :file file})) + (commands/save {:chat-id id :file file})) (defn loading-failed! [db [id reason details]] diff --git a/src/status_im/contacts/handlers.cljs b/src/status_im/contacts/handlers.cljs index 3bdaeae4af..79bdfef65a 100644 --- a/src/status_im/contacts/handlers.cljs +++ b/src/status_im/contacts/handlers.cljs @@ -1,7 +1,7 @@ (ns status-im.contacts.handlers (:require [re-frame.core :refer [after dispatch]] [status-im.utils.handlers :refer [register-handler]] - [status-im.models.contacts :as contacts] + [status-im.data-store.contacts :as contacts] [status-im.utils.crypt :refer [encrypt]] [clojure.string :as s] [status-im.protocol.core :as protocol] @@ -30,7 +30,7 @@ (defn save-contact [_ [_ contact]] - (contacts/save-contacts [contact])) + (contacts/save contact)) (defn watch-contact [{:keys [web3]} [_ {:keys [whisper-identity public-key private-key]}]] @@ -64,7 +64,7 @@ ((after save-contact)))) (defn load-contacts! [db _] - (let [contacts (->> (contacts/get-contacts) + (let [contacts (->> (contacts/get-all) (map (fn [{:keys [whisper-identity] :as contact}] [whisper-identity contact])) (into {}))] @@ -136,7 +136,7 @@ (u/side-effect! get-identities-by-contacts!)) (defn save-contacts! [{:keys [new-contacts]} _] - (contacts/save-contacts new-contacts)) + (contacts/save-all new-contacts)) (defn update-pending-status [old-contacts {:keys [whisper-identity pending] :as contact}] (let [{old-pending :pending @@ -169,7 +169,7 @@ (register-handler :add-new-contact (u/side-effect! (fn [_ [_ {:keys [whisper-identity] :as contact}]] - (when-not (contacts/get-contact whisper-identity) + (when-not (contacts/get-by-id whisper-identity) (dispatch [::prepare-contact contact]))))) (register-handler ::prepare-contact diff --git a/src/status_im/contacts/validations.cljs b/src/status_im/contacts/validations.cljs index ec3ab79dcf..d4af512cf4 100644 --- a/src/status_im/contacts/validations.cljs +++ b/src/status_im/contacts/validations.cljs @@ -1,13 +1,13 @@ (ns status-im.contacts.validations (:require [cljs.spec :as s] [cljsjs.web3] - [status-im.persistence.realm.core :as realm])) + [status-im.data-store.contacts :as contacts])) (defn is-address? [s] (.isAddress js/Web3.prototype s)) (defn unique-identity? [identity] - (not (realm/exists? :account :contact {:whisper-identity identity}))) + (not (contacts/exists? identity))) (defn valid-length? [identity] (let [length (count identity)] diff --git a/src/status_im/data_store/accounts.cljs b/src/status_im/data_store/accounts.cljs new file mode 100644 index 0000000000..fd018e6757 --- /dev/null +++ b/src/status_im/data_store/accounts.cljs @@ -0,0 +1,14 @@ +(ns status-im.data-store.accounts + (:require [status-im.data-store.realm.accounts :as data-store])) + +(defn get-all [] + (data-store/get-all-as-list)) + +(defn get-by-address [address] + (data-store/get-by-address address)) + +(defn save [account update?] + (data-store/save account update?)) + +(defn save-all [accounts update?] + (data-store/save-all accounts update?)) \ No newline at end of file diff --git a/src/status_im/data_store/chats.cljs b/src/status_im/data_store/chats.cljs new file mode 100644 index 0000000000..ec3a3eb986 --- /dev/null +++ b/src/status_im/data_store/chats.cljs @@ -0,0 +1,73 @@ +(ns status-im.data-store.chats + (:require [status-im.data-store.realm.chats :as data-store] + [re-frame.core :refer [dispatch]]) + (:refer-clojure :exclude [exists?])) + +(defn- normalize-contacts + [chats] + (map #(update % :contacts vals) chats)) + +(defn get-all + [] + (-> (data-store/get-all-active) + normalize-contacts)) + +(defn get-by-id + [id] + (data-store/get-by-id id)) + +(defn exists? + [chat-id] + (data-store/exists? chat-id)) + +(defn save + [{:keys [last-message-id chat-id] :as chat}] + (let [chat (assoc chat :last-message-id (or last-message-id ""))] + (data-store/save chat (data-store/exists? chat-id)))) + +(defn delete + [chat-id] + (data-store/delete chat-id)) + +(defn get-contacts + [chat-id] + (data-store/get-contacts chat-id)) + +(defn has-contact? + [chat-id identity] + (data-store/has-contact? chat-id identity)) + +(defn add-contacts + [chat-id identities] + (data-store/add-contacts chat-id identities) + ; TODO: move this somewhere else + ; TODO: temp. Update chat in db atom + (dispatch [:initialize-chats])) + +(defn remove-contacts + [chat-id identities] + (data-store/remove-contacts chat-id identities)) + +(defn save-property + [chat-id property-name value] + (data-store/save-property chat-id property-name value)) + +(defn get-property + [chat-id property-name] + (data-store/get-property chat-id property-name)) + +(defn is-active? + [chat-id] + (get-property chat-id :is-active)) + +(defn removed-at + [chat-id] + (get-property chat-id :removed-at)) + +(defn get-active-group-chats + [] + (data-store/get-active-group-chats)) + +(defn set-active + [chat-id active?] + (save-property chat-id :is-active active?)) diff --git a/src/status_im/data_store/commands.cljs b/src/status_im/data_store/commands.cljs new file mode 100644 index 0000000000..9a7a04cf7e --- /dev/null +++ b/src/status_im/data_store/commands.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.commands + (:require [status-im.data-store.realm.commands :as data-store])) + +(defn get-by-chat-id + [chat-id] + (data-store/get-by-chat-id chat-id)) + +(defn save + [command] + (data-store/save command)) diff --git a/src/status_im/data_store/contacts.cljs b/src/status_im/data_store/contacts.cljs new file mode 100644 index 0000000000..150ea20e56 --- /dev/null +++ b/src/status_im/data_store/contacts.cljs @@ -0,0 +1,28 @@ +(ns status-im.data-store.contacts + (:require [status-im.data-store.realm.contacts :as data-store]) + (:refer-clojure :exclude [exists?])) + +(defn get-all + [] + (data-store/get-all-as-list)) + +(defn get-by-id + [whisper-identity] + (data-store/get-by-id whisper-identity)) + +(defn save + [{:keys [whisper-identity pending] :as contact}] + (let [{pending-db :pending + :as contact-db} (data-store/get-by-id whisper-identity) + contact (assoc contact :pending (boolean (if contact-db + (and pending-db pending) + pending)))] + (data-store/save contact (if contact-db true false)))) + +(defn save-all + [contacts] + (mapv save contacts)) + +(defn exists? + [whisper-identity] + (data-store/exists? whisper-identity)) \ No newline at end of file diff --git a/src/status_im/data_store/core.cljs b/src/status_im/data_store/core.cljs new file mode 100644 index 0000000000..21a948bc3d --- /dev/null +++ b/src/status_im/data_store/core.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.core + (:require [taoensso.timbre :as log] + [status-im.data-store.realm.core :as data-source])) + + +(defn init [] + (data-source/reset-account)) + +(defn change-account [address new-account? handler] + (data-source/change-account address new-account? handler)) diff --git a/src/status_im/data_store/discovery.cljs b/src/status_im/data_store/discovery.cljs new file mode 100644 index 0000000000..3a898d0ed2 --- /dev/null +++ b/src/status_im/data_store/discovery.cljs @@ -0,0 +1,23 @@ +(ns status-im.data-store.discovery + (:require [status-im.data-store.realm.discovery :as data-store])) + +(defn get-all + [] + (->> (data-store/get-all-as-list) + (mapv #(update % :tags vals)))) + +(defn save + [discovery] + (data-store/save discovery)) + +(defn save-all + [discoveries] + (data-store/save-all discoveries)) + +(defn delete + [by ordering critical-count to-delete-count] + (data-store/delete by ordering critical-count to-delete-count)) + +(defn get-all-tags + [] + (data-store/get-all-tags)) \ No newline at end of file diff --git a/src/status_im/data_store/messages.cljs b/src/status_im/data_store/messages.cljs new file mode 100644 index 0000000000..b5fcdc8ea0 --- /dev/null +++ b/src/status_im/data_store/messages.cljs @@ -0,0 +1,92 @@ +(ns status-im.data-store.messages + (:require [status-im.data-store.realm.messages :as data-store] + [clojure.string :refer [join split]] + [status-im.utils.random :refer [timestamp]] + [clojure.walk :refer [stringify-keys keywordize-keys]] + [status-im.commands.utils :refer [generate-hiccup]] + [cljs.reader :refer [read-string]] + [status-im.constants :as c]) + (:refer-clojure :exclude [update])) + +(defn- map-to-str + [m] + (join ";" (map #(join "=" %) (stringify-keys m)))) + +(defn- str-to-map + [s] + (keywordize-keys (apply hash-map (split s #"[;=]")))) + +(defn- user-statuses-to-map + [user-statuses] + (->> (vals user-statuses) + (mapv (fn [{:keys [whisper-identity] :as status}] + [whisper-identity status])) + (into {}))) + +(defn- command-type? + [type] + (contains? + #{c/content-type-command c/content-type-command-request} + type)) + +(def default-values + {:outgoing false + :to nil + :same-author false + :same-direction false + :preview nil}) + +(defn get-by-id + [message-id] + (some-> (data-store/get-by-id message-id) + (clojure.core/update :user-statuses user-statuses-to-map))) + +(defn get-by-chat-id + ([chat-id] + (get-by-chat-id chat-id 0)) + ([chat-id from] + (->> (data-store/get-by-chat-id chat-id from c/default-number-of-messages) + (mapv #(clojure.core/update % :user-statuses user-statuses-to-map)) + (into '()) + reverse + (keep (fn [{:keys [content-type preview] :as message}] + (if (command-type? content-type) + (-> message + (clojure.core/update :content str-to-map) + (assoc :rendered-preview + (when preview + (generate-hiccup (read-string preview))))) + message)))))) + +(defn get-last-message + [chat-id] + (data-store/get-last-message chat-id)) + +(defn get-unviewed + [] + (data-store/get-unviewed)) + +(defn save + ;; todo remove chat-id parameter + [chat-id {:keys [message-id content] + :as message}] + (when-not (data-store/exists? message-id) + (let [content' (if (string? content) + content + (map-to-str content)) + message' (merge default-values + message + {:chat-id chat-id + :content content' + :timestamp (timestamp)})] + (data-store/save message')))) + +(defn update + [{:keys [message-id] :as message}] + (when (data-store/exists? message-id) + (let [message (clojure.core/update message :user-statuses vals)] + (data-store/save message)))) + +(defn delete-by-chat-id [chat-id] + (data-store/delete-by-chat-id chat-id)) + diff --git a/src/status_im/data_store/pending_messages.cljs b/src/status_im/data_store/pending_messages.cljs new file mode 100644 index 0000000000..6bf7b19c09 --- /dev/null +++ b/src/status_im/data_store/pending_messages.cljs @@ -0,0 +1,48 @@ +(ns status-im.data-store.pending-messages + (:require [status-im.data-store.realm.pending-messages :as data-store] + [clojure.string :as str] + [status-im.utils.hex :as i])) + +(defn- get-id + [message-id to] + (let [to' (i/normalize-hex to) + to'' (when to' (subs to' 0 7)) + id' (if to'' + (str message-id "-" (subs to'' 0 7)) + message-id)] + id')) + +(defn get-all + [] + (data-store/get-all-as-list)) + +(defn get-by-chat-id + [chat-id] + (data-store/get-by-chat-id chat-id)) + +(defn get-by-message-id + [message-id] + (data-store/get-by-message-id message-id)) + +(defn save + [{:keys [id to group-id message] :as pending-message}] + (let [{:keys [from topics payload]} message + id' (get-id id to) + chat-id (or group-id to) + message' (-> pending-message + (assoc :id id' + :from from + :message-id id + :chat-id chat-id + :payload payload + :topics (prn-str topics)) + (dissoc :message))] + (data-store/save message'))) + +(defn delete + [pending-message] + (data-store/delete pending-message)) + +(defn delete-all-by-chat-id + [chat-id] + (data-store/delete-all-by-chat-id chat-id)) \ No newline at end of file diff --git a/src/status_im/data_store/realm/accounts.cljs b/src/status_im/data_store/realm/accounts.cljs new file mode 100644 index 0000000000..44bd4ad0a3 --- /dev/null +++ b/src/status_im/data_store/realm/accounts.cljs @@ -0,0 +1,21 @@ +(ns status-im.data-store.realm.accounts + (:require [status-im.data-store.realm.core :as realm])) + +(defn get-all [] + (realm/get-all realm/base-realm :account)) + +(defn get-all-as-list [] + (-> (get-all) + realm/realm-collection->list)) + +(defn get-by-address [address] + (realm/get-one-by-field-clj realm/base-realm :account :address address)) + +(defn save [account update?] + (realm/write realm/base-realm + #(realm/create realm/base-realm :account account update?))) + +(defn save-all [accounts update?] + (realm/write realm/base-realm + (fn [] + (mapv #(realm/create realm/base-realm :account % update?) accounts)))) \ No newline at end of file diff --git a/src/status_im/data_store/realm/chats.cljs b/src/status_im/data_store/realm/chats.cljs new file mode 100644 index 0000000000..a1dd73cc81 --- /dev/null +++ b/src/status_im/data_store/realm/chats.cljs @@ -0,0 +1,112 @@ +(ns status-im.data-store.realm.chats + (:require [status-im.data-store.realm.core :as realm] + [status-im.utils.random :refer [timestamp]]) + (:refer-clojure :exclude [exists?])) + +(defn get-all + [] + (-> (realm/get-all @realm/account-realm :chat) + (realm/sorted :timestamp :desc))) + +(defn get-all-as-list + [] + (-> (get-all) + realm/realm-collection->list)) + +(defn get-all-active + [] + (-> (realm/get-by-field @realm/account-realm :chat :is-active true) + (realm/sorted :timestamp :desc) + realm/realm-collection->list)) + +(defn- groups + [active?] + (realm/filtered (get-all) + (str "group-chat = true && is-active = " + (if active? "true" "false")))) + +(defn get-active-group-chats + [] + (map + (fn [{:keys [chat-id public-key private-key]}] + {:chat-id chat-id + :keypair {:private private-key + :public public-key}}) + (realm/realm-collection->list (groups true)))) + +(defn get-by-id + [chat-id] + (-> (realm/get-one-by-field-clj @realm/account-realm :chat :chat-id chat-id) + (realm/list->array :contacts))) + +(defn save + [chat update?] + (realm/save @realm/account-realm :chat chat update?)) + +(defn exists? + [chat-id] + (realm/exists? @realm/account-realm :chat {:chat-id chat-id})) + +(defn delete + [chat-id] + (when-let [chat (get-by-id chat-id)] + (realm/write @realm/account-realm + (fn [] + (doto chat + (aset "is-active" false) + (aset "removed-at" timestamp)))))) + +(defn get-contacts + [chat-id] + (-> (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id) + (aget "contacts"))) + +(defn has-contact? + [chat-id identity] + (let [contacts (get-contacts chat-id) + contact (.find contacts (fn [object index collection] + (= identity (aget object "identity"))))] + (if contact true false))) + +(defn- save-contacts + [identities contacts added-at] + (doseq [contact-identity identities] + (if-let [contact (.find contacts (fn [object index collection] + (= contact-identity (aget object "identity"))))] + (doto contact + (aset "is-in-chat" true) + (aset "added-at" added-at)) + (.push contacts (clj->js {:identity contact-identity + :added-at added-at}))))) + +(defn add-contacts + [chat-id identities] + (let [contacts (get-contacts chat-id) + added-at (timestamp)] + (realm/write @realm/account-realm + #(save-contacts identities contacts added-at)))) + +(defn- delete-contacts + [identities contacts] + (doseq [contact-identity identities] + (when-let [contact (.find contacts (fn [object index collection] + (= contact-identity (aget object "identity"))))] + (realm/delete @realm/account-realm contact)))) + +(defn remove-contacts + [chat-id identities] + (let [contacts (get-contacts chat-id)] + (realm/write @realm/account-realm + #(delete-contacts identities contacts)))) + +(defn save-property + [chat-id property-name value] + (realm/write @realm/account-realm + (fn [] + (-> (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id) + (aset (name property-name) value))))) + +(defn get-property + [chat-id property] + (when-let [chat (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id)] + (aget chat (name property)))) diff --git a/src/status_im/data_store/realm/commands.cljs b/src/status_im/data_store/realm/commands.cljs new file mode 100644 index 0000000000..187da5172f --- /dev/null +++ b/src/status_im/data_store/realm/commands.cljs @@ -0,0 +1,11 @@ +(ns status-im.data-store.realm.commands + (:require [status-im.data-store.realm.core :as realm])) + +(defn get-by-chat-id + [chat-id] + (realm/get-one-by-field-clj @realm/account-realm :command + :chat-id identity)) + +(defn save + [command] + (realm/save @realm/account-realm :command command true)) diff --git a/src/status_im/data_store/realm/contacts.cljs b/src/status_im/data_store/realm/contacts.cljs new file mode 100644 index 0000000000..dddb3acf09 --- /dev/null +++ b/src/status_im/data_store/realm/contacts.cljs @@ -0,0 +1,25 @@ +(ns status-im.data-store.realm.contacts + (:require [status-im.data-store.realm.core :as realm]) + (:refer-clojure :exclude [exists?])) + +(defn get-all + [] + (-> (realm/get-all @realm/account-realm :contact) + (realm/sorted :name :asc))) + +(defn get-all-as-list + [] + (-> (get-all) + realm/realm-collection->list)) + +(defn get-by-id + [whisper-identity] + (realm/get-one-by-field-clj @realm/account-realm :contact :whisper-identity whisper-identity)) + +(defn save + [contact update?] + (realm/save @realm/account-realm :contact contact update?)) + +(defn exists? + [whisper-identity] + (realm/exists? @realm/account-realm :contact {:whisper-identity whisper-identity})) \ No newline at end of file diff --git a/src/status_im/data_store/realm/core.cljs b/src/status_im/data_store/realm/core.cljs new file mode 100644 index 0000000000..040ace99b7 --- /dev/null +++ b/src/status_im/data_store/realm/core.cljs @@ -0,0 +1,187 @@ +(ns status-im.data-store.realm.core + (:require [status-im.utils.utils :as u] + [status-im.utils.types :refer [to-string]] + [status-im.data-store.realm.schemas.account.core :as account] + [status-im.data-store.realm.schemas.base.core :as base] + [taoensso.timbre :as log] + [status-im.utils.fs :as fs] + [clojure.string :as str]) + (:refer-clojure :exclude [exists?])) + +(def realm-class (u/require "realm")) + +(defn realm-version + [file-name] + (.schemaVersion realm-class file-name)) + +(defn open-realm + [options file-name] + (let [options (merge options {:path file-name})] + (when (cljs.core/exists? js/window) + (realm-class. (clj->js options))))) + +(defn close [realm] + (.close realm)) + +(defn migrate [file-name schemas] + (let [current-version (realm-version file-name)] + (doseq [schema schemas + :when (> (:schemaVersion schema) current-version) + :let [migrated-realm (open-realm schema file-name)]] + (close migrated-realm)))) + +(defn open-migrated-realm + [file-name schemas] + (migrate file-name schemas) + (open-realm (last schemas) file-name)) + +(def new-account-filename "new-account") +(def new-accout-realm-file (str new-account-filename ".realm")) + +(def base-realm (open-migrated-realm (.-defaultPath realm-class) base/schemas)) + +(def account-realm (atom (open-migrated-realm new-account-filename account/schemas))) + +(defn close-account-realm [] + (close @account-realm) + (reset! account-realm nil)) + +(defn reset-account [] + (when @account-realm + (close @account-realm)) + (reset! account-realm (open-migrated-realm new-account-filename account/schemas)) + (.write @account-realm #(.deleteAll @account-realm))) + +(defn move-file-handler [address err handler] + (log/debug "Moved file with error: " err address) + (if err + (log/error "Error moving account realm: " (.-message err)) + (reset! account-realm (open-migrated-realm address account/schemas))) + (handler err)) + +(defn change-account [address new-account? handler] + (let [path (.-path @account-realm)] + (log/debug "closing account realm: " path) + (close-account-realm) + (log/debug "is new account? " new-account?) + (if new-account? + (let [new-path (str/replace path new-accout-realm-file (str address ".realm"))] + (log/debug "Moving file to " new-path) + (fs/move-file path new-path #(move-file-handler address % handler))) + (do + (reset! account-realm (open-migrated-realm address account/schemas)) + (handler nil))))) + +; realm functions + +(defn and-query [queries] + (str/join " and " queries)) + +(defn or-query [queries] + (str/join " or " queries)) + +(defn write [realm f] + (.write realm f)) + +(defn create + ([realm schema-name obj] + (create realm schema-name obj false)) + ([realm schema-name obj update?] + (.create realm (to-string schema-name) (clj->js obj) update?))) + +(defn save + ([realm schema-name obj] + (save realm schema-name obj false)) + ([realm schema-name obj update?] + (write realm #(create realm schema-name obj update?)))) + +(defn save-all + ([realm schema-name objs] + (save-all realm schema-name objs false)) + ([realm schema-name objs update?] + (write realm (fn [] + (mapv #(save realm schema-name % update?) objs))))) + +(defn delete [realm obj] + (write realm #(.delete realm obj))) + +(defn get-all [realm schema-name] + (.objects realm (to-string schema-name))) + +(defn sorted [results field-name order] + (.sorted results (to-string field-name) (if (= order :asc) + false + true))) + +(defn get-count [objs] + (.-length objs)) + +(defn page [results from to] + (js/Array.prototype.slice.call results from to)) + +(defn filtered [results filter-query] + (.filtered results filter-query)) + +(defn realm-collection->list [collection] + (-> (.map collection (fn [object _ _] object)) + (js->clj :keywordize-keys true))) + +(defn list->array [record list-field] + (update-in record [list-field] (comp vec vals))) + +(defn single [result] + (-> (aget result 0))) + +(defn single-cljs [result] + (some-> (aget result 0) + (js->clj :keywordize-keys true))) + +(defn get-by-filter [realm schema-name filter] + (-> (.objects realm (name schema-name)) + (.filtered filter))) + +(defn- get-schema-by-name [opts] + (->> opts + (mapv (fn [{:keys [name] :as schema}] + [(keyword name) schema])) + (into {}))) + +(defn- field-type [realm schema-name field] + (let [schema-by-name (get-schema-by-name (js->clj (.-schema realm) :keywordize-keys true)) + field-def (get-in schema-by-name [schema-name :properties field])] + (if (map? field-def) + (:type field-def) + field-def))) + +(defmulti to-query (fn [realm schema-name operator field value] + operator)) + +(defmethod to-query :eq [realm schema-name operator field value] + (let [value (to-string value) + field-type (field-type realm schema-name field) + query (str (name field) "=" (if (= "string" (name field-type)) + (str "\"" value "\"") + value))] + query)) + +(defn get-by-field [realm schema-name field value] + (let [q (to-query realm schema-name :eq field value)] + (.filtered (.objects realm (name schema-name)) q))) + +(defn get-one-by-field [realm schema-name field value] + (single (get-by-field realm schema-name field value))) + +(defn get-one-by-field-clj [realm schema-name field value] + (single-cljs (get-by-field realm schema-name field value))) + +(defn get-by-fields [realm schema-name op fields] + (let [queries (map (fn [[k v]] + (to-query realm schema-name :eq k v)) + fields)] + (.filtered (.objects realm (name schema-name)) + (case op + :and (and-query queries) + :or (or-query queries))))) + +(defn exists? [realm schema-name fields] + (pos? (.-length (get-by-fields realm schema-name :and fields)))) \ No newline at end of file diff --git a/src/status_im/data_store/realm/discovery.cljs b/src/status_im/data_store/realm/discovery.cljs new file mode 100644 index 0000000000..9f01e4c9a5 --- /dev/null +++ b/src/status_im/data_store/realm/discovery.cljs @@ -0,0 +1,73 @@ +(ns status-im.data-store.realm.discovery + (:require [status-im.data-store.realm.core :as realm] + [taoensso.timbre :as log])) + +(defn get-all + [] + (-> (realm/get-all @realm/account-realm :discovery) + (realm/sorted :priority :desc))) + +(defn get-all-as-list + [] + (-> (get-all) + realm/realm-collection->list)) + +(defn get-tag-by-name [tag] + (log/debug "Getting tag: " tag) + (realm/get-one-by-field-clj @realm/account-realm :tag :name tag)) + +(defn- update-tag-counter [func tag] + (let [tag (:name tag) + tag-object (get-tag-by-name tag)] + (if tag-object + (realm/create @realm/account-realm :tag + {:name tag + :count (func (:count tag-object))} + true)))) + +(defn- update-tags-counter [func tags] + (doseq [tag (distinct tags)] + (update-tag-counter func tag))) + +(defn- get-tags + [message-id] + (-> (realm/get-one-by-field-clj @realm/account-realm :discovery :message-id message-id) + (:tags) + (vals))) + +(defn- upsert-discovery [{:keys [message-id tags] :as discovery}] + (log/debug "Creating/updating discovery with tags: " tags) + (let [prev-tags (get-tags message-id)] + (if prev-tags + (update-tags-counter dec prev-tags)) + (realm/create @realm/account-realm :discovery discovery true) + (update-tags-counter inc tags))) + +(defn save + [discovery] + (realm/write @realm/account-realm + #(upsert-discovery discovery))) + +(defn save-all + [discoveries] + (realm/write @realm/account-realm + (fn [] + (doseq [discovery discoveries] + (upsert-discovery discovery))))) + +(defn delete + [by ordering critical-count to-delete-count] + (let [discoveries (realm/get-all @realm/account-realm :discovery) + count (realm/get-count discoveries)] + (if (> count critical-count) + (let [to-delete (-> (realm/sorted discoveries by ordering) + (realm/page 0 to-delete-count))] + (realm/write @realm/account-realm + (fn [] + (log/debug (str "Deleting " (realm/get-count to-delete) " discoveries")) + (realm/delete @realm/account-realm to-delete))))))) + +(defn get-all-tags [] + (-> (realm/get-all @realm/account-realm :tag) + (realm/sorted :count :desc) + realm/realm-collection->list)) diff --git a/src/status_im/data_store/realm/messages.cljs b/src/status_im/data_store/realm/messages.cljs new file mode 100644 index 0000000000..c818d49c65 --- /dev/null +++ b/src/status_im/data_store/realm/messages.cljs @@ -0,0 +1,55 @@ +(ns status-im.data-store.realm.messages + (:require [status-im.data-store.realm.core :as realm]) + (:refer-clojure :exclude [exists?])) + + +(defn get-all + [] + (realm/get-all @realm/account-realm :message)) + +(defn get-all-as-list + [] + (-> (get-all) + realm/realm-collection->list)) + +(defn get-by-id + [message-id] + (realm/get-one-by-field-clj @realm/account-realm :message :message-id message-id)) + +(defn get-by-chat-id + ([chat-id] + (realm/get-by-field @realm/account-realm :message :chat-id chat-id)) + ([chat-id number-of-messages] + (get-by-chat-id chat-id 0 number-of-messages)) + ([chat-id from number-of-messages] + (-> (realm/get-by-field @realm/account-realm :message :chat-id chat-id) + (realm/sorted :timestamp :desc) + (realm/page from (+ from number-of-messages)) + (realm/realm-collection->list)))) + +(defn get-last-message + [chat-id] + (-> (realm/get-by-field @realm/account-realm :message :chat-id chat-id) + (realm/sorted :timestamp :desc) + (realm/single) + (js->clj :keywordize-keys true))) + +(defn get-unviewed + [] + (-> (realm/get-by-fields @realm/account-realm :message :and {:outgoing false + :message-status nil}) + (realm/realm-collection->list))) + +(defn exists? + [message-id] + (realm/exists? @realm/account-realm :message {:message-id message-id})) + +(defn save + [message] + (realm/save @realm/account-realm :message message true)) + +(defn delete-by-chat-id + [chat-id] + (realm/write @realm/account-realm + #(realm/delete @realm/account-realm + (get-by-chat-id chat-id)))) \ No newline at end of file diff --git a/src/status_im/data_store/realm/pending_messages.cljs b/src/status_im/data_store/realm/pending_messages.cljs new file mode 100644 index 0000000000..23a7af8cac --- /dev/null +++ b/src/status_im/data_store/realm/pending_messages.cljs @@ -0,0 +1,35 @@ +(ns status-im.data-store.realm.pending-messages + (:require [status-im.data-store.realm.core :as realm] + [cljs.reader :refer [read-string]])) + +(defn get-all + [] + (realm/get-all @realm/account-realm :pending-message)) + +(defn get-all-as-list + [] + (->> (get-all) + realm/realm-collection->list + (map (fn [message] + (update message :topics read-string))))) + +(defn get-by-message-id + [message-id] + (realm/get-by-field @realm/account-realm :pending-message :message-id message-id)) + +(defn get-by-chat-id + [chat-id] + (realm/get-by-field @realm/account-realm :pending-message :chat-id chat-id)) + +(defn save + [pending-message] + (realm/save @realm/account-realm :pending-message pending-message true)) + +(defn delete + [{{:keys [message-id ack-of-message]} :payload}] + (let [message-id (or ack-of-message message-id)] + (realm/delete @realm/account-realm (get-by-message-id message-id)))) + +(defn delete-all-by-chat-id + [chat-id] + (realm/delete @realm/account-realm (get-by-chat-id chat-id))) diff --git a/src/status_im/data_store/realm/requests.cljs b/src/status_im/data_store/realm/requests.cljs new file mode 100644 index 0000000000..d87c1bbc77 --- /dev/null +++ b/src/status_im/data_store/realm/requests.cljs @@ -0,0 +1,40 @@ +(ns status-im.data-store.realm.requests + (:require [status-im.data-store.realm.core :as realm])) + +(defn get-all + [] + (realm/get-all @realm/account-realm :request)) + +(defn get-all-as-list + [] + (-> (get-all) + realm/realm-collection->list)) + +(defn get-open-by-chat-id + [chat-id] + (-> (realm/get-by-fields @realm/account-realm :request :and [[:chat-id chat-id] + [:status "open"]]) + (realm/sorted :added :desc) + (realm/realm-collection->list))) + +(defn save + [request] + (realm/save @realm/account-realm :request request true)) + +(defn save-all + [requests] + (realm/save-all @realm/account-realm :request requests true)) + +(defn- get-by-message-id + [chat-id message-id] + (-> (realm/get-by-fields @realm/account-realm :request :and [[:chat-id chat-id] + [:message-id message-id]]) + (realm/single))) + +(defn mark-as-answered + [chat-id message-id] + (realm/write @realm/account-realm + (fn [] + (-> (get-by-message-id chat-id message-id) + (.-status) + (set! "answered"))))) diff --git a/src/status_im/data_store/realm/schemas/account/core.cljs b/src/status_im/data_store/realm/schemas/account/core.cljs new file mode 100644 index 0000000000..666e27468f --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/core.cljs @@ -0,0 +1,7 @@ +(ns status-im.data-store.realm.schemas.account.core + (:require [status-im.data-store.realm.schemas.account.v1.core :as v1])) + +; put schemas ordered by version +(def schemas [{:schema v1/schema + :schemaVersion 1 + :migration v1/migration}]) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/chat-contact.cljs b/src/status_im/data_store/realm/schemas/account/v1/chat-contact.cljs new file mode 100644 index 0000000000..49fccbe81f --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/chat-contact.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.realm.schemas.account.v1.chat-contact + (:require [taoensso.timbre :as log])) + +(def schema {:name :chat-contact + :properties {:identity "string" + :is-in-chat {:type "bool" + :default true}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating chat-contact schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/chat.cljs b/src/status_im/data_store/realm/schemas/account/v1/chat.cljs new file mode 100644 index 0000000000..65a4234880 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/chat.cljs @@ -0,0 +1,30 @@ +(ns status-im.data-store.realm.schemas.account.v1.chat + (:require [taoensso.timbre :as log] + [status-im.components.styles :refer [default-chat-color]])) + +(def schema {:name :chat + :primaryKey :chat-id + :properties {:chat-id "string" + :name "string" + :color {:type "string" + :default default-chat-color} + :group-chat {:type "bool" + :indexed true} + :is-active "bool" + :timestamp "int" + :contacts {:type "list" + :objectType "chat-contact"} + :dapp-url {:type :string + :optional true} + :dapp-hash {:type :int + :optional true} + :removed-at {:type :int + :optional true} + :last-message-id "string" + :public-key {:type :string + :optional true} + :private-key {:type :string + :optional true}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating chat schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/command.cljs b/src/status_im/data_store/realm/schemas/account/v1/command.cljs new file mode 100644 index 0000000000..b731766c0c --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/command.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.realm.schemas.account.v1.command + (:require [taoensso.timbre :as log])) + +(def schema {:name :command + :primaryKey :chat-id + :properties {:chat-id "string" + :file "string"}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating command schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/contact.cljs b/src/status_im/data_store/realm/schemas/account/v1/contact.cljs new file mode 100644 index 0000000000..e7bf1279dd --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/contact.cljs @@ -0,0 +1,21 @@ +(ns status-im.data-store.realm.schemas.account.v1.contact + (:require [taoensso.timbre :as log])) + +(def schema {:name :contact + :primaryKey :whisper-identity + :properties {:address {:type "string" :optional true} + :whisper-identity "string" + :name {:type "string" :optional true} + :photo-path {:type "string" :optional true} + :last-updated {:type "int" :default 0} + :last-online {:type "int" :default 0} + :pending {:type "bool" :default false} + :public-key {:type :string + :optional true} + :private-key {:type :string + :optional true} + :dapp? {:type :bool + :default false}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating contact schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/core.cljs b/src/status_im/data_store/realm/schemas/account/v1/core.cljs new file mode 100644 index 0000000000..2ffdc748bd --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/core.cljs @@ -0,0 +1,39 @@ +(ns status-im.data-store.realm.schemas.account.v1.core + (:require [status-im.data-store.realm.schemas.account.v1.chat :as chat] + [status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact] + [status-im.data-store.realm.schemas.account.v1.command :as command] + [status-im.data-store.realm.schemas.account.v1.contact :as contact] + [status-im.data-store.realm.schemas.account.v1.discovery :as discovery] + [status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store] + [status-im.data-store.realm.schemas.account.v1.message :as message] + [status-im.data-store.realm.schemas.account.v1.pending-message :as pending-message] + [status-im.data-store.realm.schemas.account.v1.request :as request] + [status-im.data-store.realm.schemas.account.v1.tag :as tag] + [status-im.data-store.realm.schemas.account.v1.user-status :as user-status] + [taoensso.timbre :as log])) + +(def schema [chat/schema + chat-contact/schema + command/schema + contact/schema + discovery/schema + kv-store/schema + message/schema + pending-message/schema + request/schema + tag/schema + user-status/schema]) + +(defn migration [old-realm new-realm] + (log/debug "migrating v1 account database: " old-realm new-realm) + (chat/migration old-realm new-realm) + (chat-contact/migration old-realm new-realm) + (command/migration old-realm new-realm) + (contact/migration old-realm new-realm) + (discovery/migration old-realm new-realm) + (kv-store/migration old-realm new-realm) + (message/migration old-realm new-realm) + (pending-message/migration old-realm new-realm) + (request/migration old-realm new-realm) + (tag/migration old-realm new-realm) + (user-status/migration old-realm new-realm)) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/discovery.cljs b/src/status_im/data_store/realm/schemas/account/v1/discovery.cljs new file mode 100644 index 0000000000..b3c2988ba9 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/discovery.cljs @@ -0,0 +1,17 @@ +(ns status-im.data-store.realm.schemas.account.v1.discovery + (:require [taoensso.timbre :as log])) + +(def schema {:name :discovery + :primaryKey :message-id + :properties {:message-id "string" + :name {:type "string" :optional true} + :status "string" + :whisper-id "string" + :photo-path {:type "string" :optional true} + :tags {:type "list" + :objectType "tag"} + :priority {:type "int" :default 0} + :last-updated "date"}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating discovery schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/kv_store.cljs b/src/status_im/data_store/realm/schemas/account/v1/kv_store.cljs new file mode 100644 index 0000000000..011a1ac552 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/kv_store.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.realm.schemas.account.v1.kv-store + (:require [taoensso.timbre :as log])) + +(def schema {:name :kv-store + :primaryKey :key + :properties {:key "string" + :value "string"}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating kv-store schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/message.cljs b/src/status_im/data_store/realm/schemas/account/v1/message.cljs new file mode 100644 index 0000000000..5aa749e36e --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/message.cljs @@ -0,0 +1,32 @@ +(ns status-im.data-store.realm.schemas.account.v1.message + (:require [taoensso.timbre :as log])) + +(def schema {:name :message + :primaryKey :message-id + :properties {:message-id "string" + :from "string" + :to {:type "string" + :optional true} + :group-id {:type "string" + :optional true} + :content "string" ;; TODO make it ArrayBuffer + :content-type "string" + :timestamp "int" + :chat-id {:type "string" + :indexed true} + :outgoing "bool" + :retry-count {:type :int + :default 0} + :same-author "bool" + :same-direction "bool" + :preview {:type :string + :optional true} + :message-type {:type :string + :optional true} + :message-status {:type :string + :optional true} + :user-statuses {:type :list + :objectType "user-status"}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating message schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/pending_message.cljs b/src/status_im/data_store/realm/schemas/account/v1/pending_message.cljs new file mode 100644 index 0000000000..de046ef935 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/pending_message.cljs @@ -0,0 +1,22 @@ +(ns status-im.data-store.realm.schemas.account.v1.pending-message + (:require [taoensso.timbre :as log])) + +(def schema {:name :pending-message + :primaryKey :id + :properties {:id :string + :message-id :string + :chat-id {:type :string + :optional true} + :ack? :bool + :requires-ack? :bool + :from :string + :to {:type :string + :optional true} + :payload :string + :type :string + :topics :string + :attempts :int + :was-sent? :bool}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating pending-message schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/request.cljs b/src/status_im/data_store/realm/schemas/account/v1/request.cljs new file mode 100644 index 0000000000..832b79d9dc --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/request.cljs @@ -0,0 +1,13 @@ +(ns status-im.data-store.realm.schemas.account.v1.request + (:require [taoensso.timbre :as log])) + +(def schema {:name :request + :properties {:message-id :string + :chat-id :string + :type :string + :status {:type :string + :default "open"} + :added :date}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating request schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/tag.cljs b/src/status_im/data_store/realm/schemas/account/v1/tag.cljs new file mode 100644 index 0000000000..6f081b9df6 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/tag.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.realm.schemas.account.v1.tag + (:require [taoensso.timbre :as log])) + +(def schema {:name :tag + :primaryKey :name + :properties {:name "string" + :count {:type "int" :optional true :default 0}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating tag schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/account/v1/user_status.cljs b/src/status_im/data_store/realm/schemas/account/v1/user_status.cljs new file mode 100644 index 0000000000..ae388e4b56 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v1/user_status.cljs @@ -0,0 +1,12 @@ +(ns status-im.data-store.realm.schemas.account.v1.user-status + (:require [taoensso.timbre :as log])) + +(def schema {:name :user-status + :primaryKey :id + :properties {:id "string" + :whisper-identity {:type "string" + :default ""} + :status "string"}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating user-status schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/base/core.cljs b/src/status_im/data_store/realm/schemas/base/core.cljs new file mode 100644 index 0000000000..5a5b22934e --- /dev/null +++ b/src/status_im/data_store/realm/schemas/base/core.cljs @@ -0,0 +1,7 @@ +(ns status-im.data-store.realm.schemas.base.core + (:require [status-im.data-store.realm.schemas.base.v1.core :as v1])) + +; put schemas ordered by version +(def schemas [{:schema v1/schema + :schemaVersion 1 + :migration v1/migration}]) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/base/v1/account.cljs b/src/status_im/data_store/realm/schemas/base/v1/account.cljs new file mode 100644 index 0000000000..d17aa9ef0d --- /dev/null +++ b/src/status_im/data_store/realm/schemas/base/v1/account.cljs @@ -0,0 +1,22 @@ +(ns status-im.data-store.realm.schemas.base.v1.account + (:require [taoensso.timbre :as log])) + +(def schema {:name :account + :primaryKey :address + :properties {:address "string" + :public-key "string" + :updates-public-key {:type :string + :optional true} + :updates-private-key {:type :string + :optional true} + :name {:type "string" :optional true} + :phone {:type "string" :optional true} + :email {:type "string" :optional true} + :status {:type "string" :optional true} + :photo-path "string" + :last-updated {:type "int" :default 0} + :signed-up? {:type :bool + :default false}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating account schema")) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/base/v1/core.cljs b/src/status_im/data_store/realm/schemas/base/v1/core.cljs new file mode 100644 index 0000000000..6addb40b3f --- /dev/null +++ b/src/status_im/data_store/realm/schemas/base/v1/core.cljs @@ -0,0 +1,12 @@ +(ns status-im.data-store.realm.schemas.base.v1.core + (:require [status-im.data-store.realm.schemas.base.v1.account :as account] + [status-im.data-store.realm.schemas.base.v1.kv-store :as kv-store] + [taoensso.timbre :as log])) + +(def schema [account/schema + kv-store/schema]) + +(defn migration [old-realm new-realm] + (log/debug "migrating v1 base database: " old-realm new-realm) + (account/migration old-realm new-realm) + (kv-store/migration old-realm new-realm)) \ No newline at end of file diff --git a/src/status_im/data_store/realm/schemas/base/v1/kv_store.cljs b/src/status_im/data_store/realm/schemas/base/v1/kv_store.cljs new file mode 100644 index 0000000000..8bc17ec68c --- /dev/null +++ b/src/status_im/data_store/realm/schemas/base/v1/kv_store.cljs @@ -0,0 +1,10 @@ +(ns status-im.data-store.realm.schemas.base.v1.kv-store + (:require [taoensso.timbre :as log])) + +(def schema {:name :kv-store + :primaryKey :key + :properties {:key "string" + :value "string"}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating kv-store schema")) \ No newline at end of file diff --git a/src/status_im/data_store/requests.cljs b/src/status_im/data_store/requests.cljs new file mode 100644 index 0000000000..fd6a25239f --- /dev/null +++ b/src/status_im/data_store/requests.cljs @@ -0,0 +1,22 @@ +(ns status-im.data-store.requests + (:require [status-im.data-store.realm.requests :as data-store])) + +(defn get-all + [] + (data-store/get-all-as-list)) + +(defn get-open-by-chat-id + [chat-id] + (data-store/get-open-by-chat-id chat-id)) + +(defn save + [request] + (data-store/save request)) + +(defn save-all + [requests] + (data-store/save-all requests)) + +(defn mark-as-answered + [chat-id message-id] + (data-store/mark-as-answered chat-id message-id)) diff --git a/src/status_im/discovery/handlers.cljs b/src/status_im/discovery/handlers.cljs index ebad874858..533505dcfa 100644 --- a/src/status_im/discovery/handlers.cljs +++ b/src/status_im/discovery/handlers.cljs @@ -4,7 +4,7 @@ [status-im.utils.handlers :refer [register-handler]] [status-im.protocol.core :as protocol] [status-im.navigation.handlers :as nav] - [status-im.discovery.model :as discoveries] + [status-im.data-store.discovery :as discoveries] [status-im.utils.handlers :as u] [status-im.utils.datetime :as time] [status-im.utils.random :as random])) @@ -28,11 +28,11 @@ (defmethod nav/preload-data! :discovery [{:keys [discoveries] :as db} _] (-> db - (assoc :tags (discoveries/all-tags)) + (assoc :tags (discoveries/get-all-tags)) ;; todo add limit ;; todo hash-map with whisper-id as key and sorted by last-update ;; may be more efficient here - (assoc :discoveries (discoveries/discovery-list)))) + (assoc :discoveries (discoveries/get-all)))) (register-handler :discovery-response-received (u/side-effect! @@ -85,11 +85,11 @@ (defn save-discovery! [{:keys [new-discovery]} _] - (discoveries/save-discoveries [new-discovery])) + (discoveries/save new-discovery)) (defn reload-tags! [db _] - (assoc db :tags (discoveries/all-tags))) + (assoc db :tags (discoveries/get-all-tags))) (register-handler :add-discovery (-> add-discovery @@ -100,4 +100,4 @@ :remove-old-discoveries! (u/side-effect! (fn [_ _] - (discoveries/remove-discoveries! :priority :asc 1000 200)))) + (discoveries/delete :priority :asc 1000 200)))) diff --git a/src/status_im/discovery/model.cljs b/src/status_im/discovery/model.cljs deleted file mode 100644 index 6a09d9d5ca..0000000000 --- a/src/status_im/discovery/model.cljs +++ /dev/null @@ -1,67 +0,0 @@ -(ns status-im.discovery.model - (:require [taoensso.timbre :as log] - [status-im.persistence.realm.core :as r])) - -(defn get-tag [tag] - (log/debug "Getting tag: " tag) - (-> (r/get-by-field :account :tag :name tag) - (r/single-cljs))) - -(defn update-tag-counter [func tag] - (let [tag (:name tag) - tag-object (get-tag tag)] - (if tag-object - (r/create :account :tag - {:name tag - :count (func (:count tag-object))} - true)))) - -(defn update-tags-counter [func tags] - (doseq [tag (distinct tags)] - (update-tag-counter func tag))) - -(defn get-tags [message-id] - (-> (r/get-by-field :account :discovery :message-id message-id) - (r/single-cljs) - (:tags) - (vals))) - -(defn- upsert-discovery [{:keys [message-id tags] :as discovery}] - (log/debug "Creating/updating discovery with tags: " tags) - (let [prev-tags (get-tags message-id)] - (if prev-tags - (update-tags-counter dec prev-tags)) - (r/create :account :discovery discovery true) - (update-tags-counter inc tags))) - -(defn discovery-list [] - (->> (-> (r/get-all :account :discovery) - (r/sorted :priority :desc) - (r/realm-collection->list)) - (mapv #(update % :tags vals)))) - -(defn- add-discoveries [discoveries] - (r/write :account - (fn [] - (doseq [discovery discoveries] - (upsert-discovery discovery))))) - -(defn save-discoveries [discoveries] - (add-discoveries discoveries)) - -(defn remove-discoveries! [by ordering critical-count to-delete-count] - (let [objs (r/get-all :account :discovery) - count (r/get-count objs)] - (if (> count critical-count) - (let [to-delete (-> (r/sorted objs by ordering) - (r/page 0 to-delete-count))] - (r/write :account - (fn [] - (log/debug (str "Deleting " (r/get-count to-delete) " discoveries")) - (r/delete :account to-delete))))))) - -(defn all-tags [] - (-> (r/get-all :account :tag) - (r/sorted :count :desc) - r/realm-collection->list)) - diff --git a/src/status_im/group_settings/handlers.cljs b/src/status_im/group_settings/handlers.cljs index 56bc91ec3e..204df18947 100644 --- a/src/status_im/group_settings/handlers.cljs +++ b/src/status_im/group_settings/handlers.cljs @@ -1,13 +1,12 @@ (ns status-im.group-settings.handlers (:require [re-frame.core :refer [debug dispatch after enrich]] [status-im.utils.handlers :refer [register-handler]] - [status-im.persistence.realm.core :as r] [status-im.chat.handlers :refer [delete-messages!]] [status-im.protocol.core :as protocol] [status-im.utils.random :as random] - [status-im.models.contacts :as contacts] - [status-im.models.messages :as messages] - [status-im.models.chats :as chats] + [status-im.data-store.contacts :as contacts] + [status-im.data-store.messages :as messages] + [status-im.data-store.chats :as chats] [status-im.constants :refer [text-content-type]] [status-im.utils.handlers :as u] [status-im.navigation.handlers :as nav])) @@ -18,11 +17,7 @@ (defn save-property! [current-chat-id property-name value] - (r/write :account - (fn [] - (-> (r/get-by-field :account :chat :chat-id current-chat-id) - (r/single) - (aset (name property-name) value))))) + (chats/save-property current-chat-id property-name value)) (defn save-chat-property! [db-name property-name] @@ -80,15 +75,9 @@ (update-in db [:chats current-chat-id :contacts] remove-identities selected-participants)) -(defn remove-members-from-realm! +(defn remove-members-from-chat! [{:keys [current-chat-id selected-participants] :as db} _] - (let [chat (get-in db [:chats current-chat-id])] - (r/write :account - (fn [] - (r/create :account - :chat - (update chat :contacts remove-identities selected-participants) - true))))) + (chats/remove-contacts current-chat-id selected-participants)) (defn notify-about-removing! [{:keys [current-chat-id selected-participants]} _] @@ -103,10 +92,10 @@ :content-type text-content-type}) (defn removed-participant-message [chat-id identity] - (let [contact-name (:name (contacts/contact-by-identity identity))] + (let [contact-name (:name (contacts/get-by-id identity))] (->> (str "You've removed " (or contact-name identity)) (system-message (random/id)) - (messages/save-message chat-id)))) + (messages/save chat-id)))) (defn create-removing-messages! [{:keys [current-chat-id selected-participants]} _] @@ -122,7 +111,7 @@ (-> remove-members ;; todo shouldn't this be done only after receiving of the "ack message" ;; about the api call that removes participants from the group? - ((after remove-members-from-realm!)) + ((after remove-members-from-chat!)) ;; todo uncomment ;((after notify-about-removing!)) ((after create-removing-messages!)) @@ -134,9 +123,9 @@ (let [new-identities (map #(hash-map :identity %) selected-participants)] (update db [:chats current-chat-id :contacts] concat new-identities))) -(defn add-members-to-realm! +(defn add-members-to-chat! [{:keys [current-chat-id selected-participants]} _] - (chats/chat-add-participants current-chat-id selected-participants)) + (chats/add-contacts current-chat-id selected-participants)) (defn notify-about-new-members! [{:keys [current-chat-id selected-participants @@ -166,6 +155,6 @@ (register-handler :add-new-participants ;; todo order of operations tbd (-> add-memebers - ((after add-members-to-realm!)) + ((after add-members-to-chat!)) ((after notify-about-new-members!)) ((enrich deselect-members)))) diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs index 97a2c2e08d..9c1cdd1682 100644 --- a/src/status_im/handlers.cljs +++ b/src/status_im/handlers.cljs @@ -3,7 +3,7 @@ [re-frame.core :refer [after dispatch dispatch-sync debug]] [schema.core :as s :include-macros true] [status-im.db :refer [app-db schema]] - [status-im.persistence.realm.core :as realm] + [status-im.data-store.core :as data-store] [taoensso.timbre :as log] [status-im.utils.crypt :refer [gen-random-bytes]] [status-im.components.status :as status] @@ -43,7 +43,7 @@ (register-handler :initialize-db (fn [_ _] - (realm/reset-account) + (data-store/init) (assoc app-db :current-account-id nil))) (register-handler :initialize-account-db diff --git a/src/status_im/ios/core.cljs b/src/status_im/ios/core.cljs index 776c31c8b1..9a3fdc5244 100644 --- a/src/status_im/ios/core.cljs +++ b/src/status_im/ios/core.cljs @@ -22,7 +22,7 @@ [status-im.group-settings.screen :refer [group-settings]] [status-im.profile.screen :refer [profile my-profile]] [status-im.profile.photo-capture.screen :refer [profile-photo-capture]] - status-im.persistence.realm.core + status-im.data-store.core [taoensso.timbre :as log])) (defn orientation->keyword [o] diff --git a/src/status_im/models/accounts.cljs b/src/status_im/models/accounts.cljs deleted file mode 100644 index 112ebfb464..0000000000 --- a/src/status_im/models/accounts.cljs +++ /dev/null @@ -1,21 +0,0 @@ -(ns status-im.models.accounts - (:require [status-im.persistence.realm.core :as r])) - -(defn get-accounts [] - (-> (r/get-all :base :account) - r/realm-collection->list)) - -(defn save-account [update?] - #(r/create :base :account % update?)) - -(defn save-accounts [accounts update?] - (r/write :base #(mapv (save-account update?) accounts))) - - -;;;;;;;;;;;;;;;;;;;;---------------------------------------------- - -(defn accounts-list [] - (r/get-all :base :account)) - -(defn account-by-address [address] - (r/single-cljs (r/get-by-field :base :account :address address))) diff --git a/src/status_im/models/chats.cljs b/src/status_im/models/chats.cljs deleted file mode 100644 index 898f02d171..0000000000 --- a/src/status_im/models/chats.cljs +++ /dev/null @@ -1,141 +0,0 @@ -(ns status-im.models.chats - (:require [clojure.set :refer [difference]] - [re-frame.core :refer [dispatch]] - [status-im.persistence.realm.core :as r] - [status-im.utils.random :as random :refer [timestamp]] - [clojure.string :refer [join blank?]] - [status-im.constants :refer [content-type-status]] - [status-im.models.messages :refer [save-message]] - [status-im.persistence.realm-queries :refer [include-query]])) - -(defn chat-name-from-contacts [identities] - (let [chat-name (->> identities - (map (fn [identity] - (-> (r/get-by-field :account :contact :whisper-identity identity) - (r/single-cljs) - :name))) - (filter identity) - (join ","))] - (when-not (blank? chat-name) - chat-name))) - -(defn get-chat-name [chat-id identities] - (or (chat-name-from-contacts identities) - chat-id)) - -(defn chat-exists? [chat-id] - (r/exists? :account :chat {:chat-id chat-id})) - -(defn chat-contacts [chat-id] - (-> (r/get-by-field :account :chat :chat-id chat-id) - (r/single) - (aget "contacts"))) - -(defn re-join-group-chat [db group-id identities group-name] - (r/write :account - (fn [] - (let [new-identities (set identities) - only-old-contacts (->> (chat-contacts group-id) - (r/cljs-list) - (remove (fn [{:keys [identity]}] - (new-identities identity)))) - contacts (->> new-identities - (mapv (fn [ident] - {:identity ident})) - (concat only-old-contacts))] - (r/create :account :chat - {:chat-id group-id - :is-active true - :name group-name - :contacts contacts} true)))) - db) - -(defn normalize-contacts - [chats] - (map #(update % :contacts vals) chats)) - -(defn chats-list [] - (-> (r/get-by-field :account :chat :is-active true) - (r/sorted :timestamp :desc) - r/realm-collection->list - normalize-contacts)) - -(defn chat-by-id [chat-id] - (-> (r/get-by-field :account :chat :chat-id chat-id) - (r/single-cljs) - (r/list-to-array :contacts))) - -(defn update-chat [{:keys [last-message-id chat-id] :as chat}] - (let [{old-chat-id :chat-id - :as old-chat} (chat-by-id chat-id)] - (when old-chat-id - (let [chat (-> (merge old-chat chat) - (assoc chat :last-message-id (or last-message-id "")))] - (r/write :account #(r/create :account :chat chat true)))))) - -(defn create-chat - ([{:keys [last-message-id] :as chat}] - (let [chat (assoc chat :last-message-id (or last-message-id ""))] - (r/write :account #(r/create :account :chat chat true))))) - -(defn chat-add-participants [chat-id identities] - (r/write :account - (fn [] - (let [contacts (chat-contacts chat-id) - added-at (timestamp)] - (doseq [contact-identity identities] - (if-let [contact (.find contacts (fn [object index collection] - (= contact-identity (aget object "identity"))))] - (doto contact - (aset "is-in-chat" true) - (aset "added-at" added-at)) - (.push contacts (clj->js {:identity contact-identity - :added-at added-at}))))))) - ;; TODO temp. Update chat in db atom - (dispatch [:initialize-chats])) - -(defn chat-remove-participants [chat-id identities] - (r/write :account - (fn [] - (let [query (include-query :identity identities) - chat (r/single (r/get-by-field :account :chat :chat-id chat-id))] - (-> (aget chat "contacts") - (r/filtered query) - (.forEach (fn [object _ _] - (r/delete :account object)))))))) - -(defn- groups [active?] - (r/filtered (r/get-all :account :chat) - (str "group-chat = true && is-active = " - (if active? "true" "false")))) - -(defn active-group-chats [] - (map - (fn [{:keys [chat-id public-key private-key]}] - {:chat-id chat-id - :keypair {:private private-key - :public public-key}}) - (r/realm-collection->list (groups true)))) - -(defn set-chat-active [chat-id active?] - (r/write :account - (fn [] - (-> (r/get-by-field :account :chat :chat-id chat-id) - (r/single) - (aset "is-active" active?))))) - -(defn get-property [chat-id property] - (when-let [chat (r/single (r/get-by-field :account :chat :chat-id chat-id))] - (aget chat (name property)))) - -(defn is-active? [chat-id] - (get-property chat-id :is-active)) - -(defn removed-at [chat-id] - (get-property chat-id :removed-at)) - -(defn contact [chat-id id] - (let [contacts (r/cljs-list (chat-contacts chat-id))] - (some (fn [{:keys [identity]}] - (= id identity)) - contacts))) diff --git a/src/status_im/models/contacts.cljs b/src/status_im/models/contacts.cljs deleted file mode 100644 index 5c6c3bab85..0000000000 --- a/src/status_im/models/contacts.cljs +++ /dev/null @@ -1,50 +0,0 @@ -(ns status-im.models.contacts - (:require [status-im.persistence.realm.core :as r] - [status-im.utils.identicon :refer [identicon]] - [status-im.persistence.realm-queries :refer [include-query - exclude-query]])) - -(defn get-contacts [] - (-> (r/get-all :account :contact) - (r/sorted :name :asc) - r/realm-collection->list)) - -(defn get-contact [id] - (r/get-one-by-field :account :contact :whisper-identity id)) - -(defn create-contact [{:keys [whisper-identity pending] :as contact}] - (let [{pending-db :pending - :as contact-db} (r/get-one-by-field :account :contact - :whisper-identity whisper-identity) - contact (assoc contact :pending (boolean (if contact-db - (and pending-db pending) - pending)))] - (r/create :account :contact contact (if contact-db true false)))) - -(defn save-contacts [contacts] - (r/write :account #(mapv create-contact contacts))) - - -;;;;;;;;;;;;;;;;;;;;---------------------------------------------- - -(defn contacts-list [] - (r/sorted (r/get-all :account :contact) :name :asc)) - -(defn contacts-list-exclude [exclude-idents] - (if (empty? exclude-idents) - (contacts-list) - (let [query (exclude-query :whisper-identity exclude-idents)] - (-> (r/get-all :account :contact) - (r/filtered query) - (r/sorted :name :asc))))) - -(defn contacts-list-include [include-indents] - (if (empty? include-indents) - () - (let [query (include-query :whisper-identity include-indents)] - (-> (r/get-all :account :contact) - (r/filtered query) - (r/sorted :name :asc))))) - -(defn contact-by-identity [identity] - (r/single-cljs (r/get-by-field :account :contact :whisper-identity identity))) diff --git a/src/status_im/models/messages.cljs b/src/status_im/models/messages.cljs deleted file mode 100644 index c169ebce8a..0000000000 --- a/src/status_im/models/messages.cljs +++ /dev/null @@ -1,89 +0,0 @@ -(ns status-im.models.messages - (:require [status-im.persistence.realm.core :as r] - [re-frame.core :refer [dispatch]] - [cljs.reader :refer [read-string]] - [status-im.utils.random :refer [timestamp]] - [clojure.string :refer [join split]] - [clojure.walk :refer [stringify-keys keywordize-keys]] - [status-im.constants :as c] - [status-im.commands.utils :refer [generate-hiccup]])) - -(defn- map-to-str - [m] - (join ";" (map #(join "=" %) (stringify-keys m)))) - -(defn- str-to-map - [s] - (keywordize-keys (apply hash-map (split s #"[;=]")))) - -(defn- user-statuses-to-map - [user-statuses] - (->> (vals user-statuses) - (mapv (fn [{:keys [whisper-identity] :as status}] - [whisper-identity status])) - (into {}))) - -(def default-values - {:outgoing false - :to nil - :same-author false - :same-direction false - :preview nil}) - -(defn save-message - ;; todo remove chat-id parameter - [chat-id {:keys [message-id content] - :as message}] - (when-not (r/exists? :account :message {:message-id message-id}) - (r/write :account - (fn [] - (let [content' (if (string? content) - content - (map-to-str content)) - message' (merge default-values - message - {:chat-id chat-id - :content content' - :timestamp (timestamp)})] - (r/create :account :message message' true)))))) - -(defn command-type? [type] - (contains? - #{c/content-type-command c/content-type-command-request} - type)) - -(defn get-messages - ([chat-id] (get-messages chat-id 0)) - ([chat-id from] - (->> (-> (r/get-by-field :account :message :chat-id chat-id) - (r/sorted :timestamp :desc) - (r/page from (+ from c/default-number-of-messages)) - (r/realm-collection->list)) - (mapv #(update % :user-statuses user-statuses-to-map)) - (into '()) - reverse - (keep (fn [{:keys [content-type preview] :as message}] - (if (command-type? content-type) - (-> message - (update :content str-to-map) - (assoc :rendered-preview - (when preview - (generate-hiccup (read-string preview))))) - message)))))) - -(defn update-message! [{:keys [message-id] :as message}] - (r/write :account - (fn [] - (when (r/exists? :account :message {:message-id message-id}) - (let [message (update message :user-statuses vals)] - (r/create :account :message message true)))))) - -(defn get-message [id] - (some-> (r/get-one-by-field :account :message :message-id id) - (update :user-statuses user-statuses-to-map))) - -(defn get-last-message [chat-id] - (-> (r/get-by-field :account :message :chat-id chat-id) - (r/sorted :timestamp :desc) - (r/single) - (js->clj :keywordize-keys true))) diff --git a/src/status_im/models/pending_messages.cljs b/src/status_im/models/pending_messages.cljs deleted file mode 100644 index 12a6b5d501..0000000000 --- a/src/status_im/models/pending_messages.cljs +++ /dev/null @@ -1,60 +0,0 @@ -(ns status-im.models.pending-messages - (:require [status-im.persistence.realm.core :as r] - [re-frame.core :refer [dispatch]] - [cljs.reader :refer [read-string]] - [status-im.utils.random :refer [timestamp]] - [clojure.string :refer [join split]] - [clojure.walk :refer [stringify-keys keywordize-keys]] - [status-im.constants :as c] - [status-im.utils.types :refer [clj->json json->clj]] - [status-im.commands.utils :refer [generate-hiccup]] - [cljs.reader :as reader] - [clojure.string :as str] - [status-im.utils.hex :as i])) - -(defn get-pending-messages! [] - (->> (r/get-all :account :pending-message) - r/realm-collection->list - (map (fn [message] - (update message :topics reader/read-string))))) - -(defn- get-id - [message-id to] - (let [to' (i/normalize-hex to) - to'' (when to' (subs to' 0 7)) - id' (if to'' - (str message-id "-" (subs to'' 0 7)) - message-id)] - id')) - -(defn add-pending-message! - [{:keys [id to group-id message] :as pending-message}] - (r/write :account - (fn [] - (let [{:keys [from topics payload]} message - id' (get-id id to) - chat-id (or group-id to) - message' (-> pending-message - (assoc :id id' - :from from - :message-id id - :chat-id chat-id - :payload payload - :topics (prn-str topics)) - (dissoc :message))] - (r/create :account :pending-message message' true))))) - -(defn remove-pending-message! - [{{:keys [message-id ack-of-message]} :payload}] - (r/write :account - (fn [] - (r/delete :account - (r/get-by-field :account :pending-message - :message-id (or ack-of-message message-id)))))) - -(defn remove-all-by-chat [chat-id] - (r/write - :account - (fn [] - (r/delete :account - (r/get-by-field :account :pending-message :chat-id chat-id))))) diff --git a/src/status_im/models/requests.cljs b/src/status_im/models/requests.cljs deleted file mode 100644 index 641e8a28f1..0000000000 --- a/src/status_im/models/requests.cljs +++ /dev/null @@ -1,21 +0,0 @@ -(ns status-im.models.requests - (:require [status-im.persistence.realm.core :as r])) - -(defn get-requests [] - (-> (r/get-all :account :request) - r/realm-collection->list)) - -(defn create-request [request] - (r/create :account :request request true)) - -(defn save-request [request] - (r/write :account - (fn [] - (create-request request)))) - -(defn save-requests [requests] - (r/write :account #(mapv create-request requests))) - -(defn requests-list [] - (r/get-all :account :request)) - diff --git a/src/status_im/new_group/handlers.cljs b/src/status_im/new_group/handlers.cljs index e1eebd932f..72d1aa1081 100644 --- a/src/status_im/new_group/handlers.cljs +++ b/src/status_im/new_group/handlers.cljs @@ -3,7 +3,7 @@ [re-frame.core :refer [after dispatch debug enrich]] [status-im.utils.handlers :refer [register-handler]] [status-im.components.styles :refer [default-chat-color]] - [status-im.models.chats :as chats] + [status-im.data-store.chats :as chats] [clojure.string :as s] [status-im.utils.handlers :as u] [status-im.utils.random :as random] @@ -54,7 +54,7 @@ (defn create-chat! [{:keys [new-chat]} _] - (chats/create-chat new-chat)) + (chats/save new-chat)) (defn show-chat! [{:keys [new-chat]} _] @@ -105,7 +105,7 @@ :public-key public :private-key private :contacts contacts'}] - (when (or (not (chats/chat-exists? group-id)) + (when (or (not (chats/exists? group-id)) is-active (> timestamp removed-at)) (dispatch [:add-chat group-id (assoc chat :is-active true diff --git a/src/status_im/persistence/realm/core.cljs b/src/status_im/persistence/realm/core.cljs deleted file mode 100644 index 1dad90e75c..0000000000 --- a/src/status_im/persistence/realm/core.cljs +++ /dev/null @@ -1,185 +0,0 @@ -(ns status-im.persistence.realm.core - (:require [cljs.reader :refer [read-string]] - [status-im.components.styles :refer [default-chat-color]] - [status-im.utils.types :refer [to-string]] - [status-im.utils.utils :as u] - [status-im.utils.fs :as fs] - [taoensso.timbre :as log] - [status-im.persistence.realm.schemas :refer [base account]] - [clojure.string :as str]) - (:refer-clojure :exclude [exists?])) - -(def new-account-filename "new-account") - -(def realm-class (u/require "realm")) - -(defn create-account-realm [address] - (let [opts (merge account {:path (str address ".realm")})] - (when (cljs.core/exists? js/window) - (realm-class. (clj->js opts))))) - -(def base-realm - (when (cljs.core/exists? js/window) - (realm-class. (clj->js base)))) - -(def account-realm (atom (create-account-realm new-account-filename))) - -(defn is-new-account? [] - (let [path (.-path @account-realm) - realm_file (str new-account-filename ".realm")] - (str/ends-with? path realm_file))) - -(defn realm [schema] - (case schema - :base base-realm - :account @account-realm)) - -(defn close [schema] - (let [realm-db (realm schema)] - (when realm-db - (.close realm-db)))) - -(defn close-account-realm [] - (close :account) - (reset! account-realm nil)) - -(defn reset-account [] - (when @account-realm - (close-account-realm)) - (reset! account-realm (create-account-realm new-account-filename)) - (.write @account-realm #(.deleteAll @account-realm))) - -(defn move-file-handler [address err handler] - (log/debug "Moved file with error: " err address) - (if err - (log/error "Error moving account realm: " (.-message err)) - (reset! account-realm (create-account-realm address))) - (handler err)) - -(defn change-account-realm [address new-account? handler] - (let [path (.-path @account-realm) - realm-file (str new-account-filename ".realm")] - (log/debug "closing account realm: " path) - (close-account-realm) - (log/debug "is new account? " new-account?) - (if new-account? - (let [new-path (str/replace path realm-file (str address ".realm"))] - (log/debug "Moving file to " new-path) - (fs/move-file path new-path #(move-file-handler address % handler))) - (do - (reset! account-realm (create-account-realm address)) - (handler nil))))) - -(defn get-schema-by-name [opts] - (->> (:schema opts) - (mapv (fn [{:keys [name] :as schema}] - [name schema])) - (into {}))) - -(def schema-by-name - {:base (get-schema-by-name base) - :account (get-schema-by-name account)}) - -(defn field-type [schema schema-name field] - (let [schema-by-name (get schema-by-name schema) - field-def (get-in schema-by-name [schema-name :properties field])] - (if (map? field-def) - (:type field-def) - field-def))) - -(defn write [schema f] - (.write (realm schema) f)) - -(defn create - ([schema schema-name obj] - (create schema schema-name obj false)) - ([schema schema-name obj update?] - (.create (realm schema) (to-string schema-name) (clj->js obj) update?))) - -(defn create-object - [schema schema-name obj] - (write schema (fn [] (create schema schema-name obj true)))) - -(defn and-query [queries] - (str/join " and " queries)) - -(defn or-query [queries] - (str/join " or " queries)) - -(defmulti to-query (fn [schema schema-name operator field value] - operator)) - -(defmethod to-query :eq [schema schema-name operator field value] - (let [value (to-string value) - field-type (field-type schema schema-name field) - query (str (name field) "=" (if (= "string" (name field-type)) - (str "\"" value "\"") - value))] - query)) - -(defn get-by-filter [schema schema-name filter] - (-> (.objects (realm schema) (name schema-name)) - (.filtered filter))) - -(defn get-by-field [schema schema-name field value] - (let [q (to-query schema schema-name :eq field value)] - (.filtered (.objects (realm schema) (name schema-name)) q))) - -(defn get-by-fields [schema schema-name op fields] - (let [queries (map (fn [[k v]] - (to-query schema schema-name :eq k v)) - fields)] - (.filtered (.objects (realm schema) (name schema-name)) - (case op - :and (and-query queries) - :or (or-query queries))))) - -(defn get-all [schema schema-name] - (.objects (realm schema) (to-string schema-name))) - -(defn sorted [results field-name order] - (.sorted results (to-string field-name) (if (= order :asc) - false - true))) - -(defn filtered [results filter-query] - (.filtered results filter-query)) - -(defn page [results from to] - (js/Array.prototype.slice.call results from to)) - -(defn single [result] - (-> (aget result 0))) - -(defn single-cljs [result] - (some-> (aget result 0) - (js->clj :keywordize-keys true))) - -(defn cljs-list [results] - (-> (js->clj results :keywordize-keys true) - (vals))) - -(defn list-to-array [record list-field] - (update-in record [list-field] (comp vec vals))) - -(defn decode-value [{:keys [key value]}] - (read-string value)) - -(defn delete [schema obj] - (.delete (realm schema) obj)) - -(defn exists? [schema schema-name fields] - (pos? (.-length (get-by-fields schema schema-name :and fields)))) - -(defn get-count [objs] - (.-length objs)) - -(defn get-list [schema schema-name] - (vals (js->clj (.objects (realm schema) (to-string schema-name)) :keywordize-keys true))) - -(defn realm-collection->list [collection] - (-> (.map collection (fn [object _ _] object)) - (js->clj :keywordize-keys true))) - -(defn get-one-by-field [schema schema-name field value] - (single-cljs (get-by-field schema schema-name field value))) diff --git a/src/status_im/persistence/realm/schemas.cljs b/src/status_im/persistence/realm/schemas.cljs deleted file mode 100644 index bdfc1730bd..0000000000 --- a/src/status_im/persistence/realm/schemas.cljs +++ /dev/null @@ -1,147 +0,0 @@ -(ns status-im.persistence.realm.schemas - (:require [status-im.components.styles :refer [default-chat-color]])) - -(def base {:schema [{:name :account - :primaryKey :address - :properties {:address "string" - :public-key "string" - :updates-public-key {:type :string - :optional true} - :updates-private-key {:type :string - :optional true} - :name {:type "string" :optional true} - :phone {:type "string" :optional true} - :email {:type "string" :optional true} - :status {:type "string" :optional true} - :photo-path "string" - :last-updated {:type "int" :default 0} - :signed-up? {:type :bool - :default false}}} - {:name :kv-store - :primaryKey :key - :properties {:key "string" - :value "string"}}] - :schemaVersion 0}) - -(def account {:schema [{:name :contact - :primaryKey :whisper-identity - :properties {:address {:type "string" :optional true} - :whisper-identity "string" - :name {:type "string" :optional true} - :photo-path {:type "string" :optional true} - :last-updated {:type "int" :default 0} - :last-online {:type "int" :default 0} - :pending {:type "bool" :default false} - :public-key {:type :string - :optional true} - :private-key {:type :string - :optional true} - :dapp? {:type :bool - :default false}}} - {:name :request - :properties {:message-id :string - :chat-id :string - :type :string - :status {:type :string - :default "open"} - :added :date}} - {:name :tag - :primaryKey :name - :properties {:name "string" - :count {:type "int" :optional true :default 0}}} - {:name :discovery - :primaryKey :message-id - :properties {:message-id "string" - :name {:type "string" :optional true} - :status "string" - :whisper-id "string" - :photo-path {:type "string" :optional true} - :tags {:type "list" - :objectType "tag"} - :priority {:type "int" :default 0} - :last-updated "date"}} - {:name :kv-store - :primaryKey :key - :properties {:key "string" - :value "string"}} - {:name :user-status - :primaryKey :id - :properties {:id "string" - :whisper-identity {:type "string" - :default ""} - :status "string"}} - {:name :message - :primaryKey :message-id - :properties {:message-id "string" - :from "string" - :to {:type "string" - :optional true} - :group-id {:type "string" - :optional true} - :content "string" ;; TODO make it ArrayBuffer - :content-type "string" - :timestamp "int" - :chat-id {:type "string" - :indexed true} - :outgoing "bool" - :retry-count {:type :int - :default 0} - :same-author "bool" - :same-direction "bool" - :preview {:type :string - :optional true} - :message-type {:type :string - :optional true} - :message-status {:type :string - :optional true} - :user-statuses {:type :list - :objectType "user-status"}}} - {:name :pending-message - :primaryKey :id - :properties {:id :string - :message-id :string - :chat-id {:type :string - :optional true} - :ack? :bool - :requires-ack? :bool - :from :string - :to {:type :string - :optional true} - :payload :string - :type :string - :topics :string - :attempts :int - :was-sent? :bool}} - {:name :chat-contact - :properties {:identity "string" - :is-in-chat {:type "bool" - :default true}}} - {:name :chat - :primaryKey :chat-id - :properties {:chat-id "string" - :name "string" - :color {:type "string" - :default default-chat-color} - :group-chat {:type "bool" - :indexed true} - :is-active "bool" - :timestamp "int" - :contacts {:type "list" - :objectType "chat-contact"} - :dapp-url {:type :string - :optional true} - :dapp-hash {:type :int - :optional true} - :removed-at {:type :int - :optional true} - :last-message-id "string" - :public-key {:type :string - :optional true} - :private-key {:type :string - :optional true}}} - {:name :command - :primaryKey :chat-id - :properties {:chat-id "string" - :file "string"}}] - :schemaVersion 0}) - diff --git a/src/status_im/persistence/realm_queries.cljs b/src/status_im/persistence/realm_queries.cljs deleted file mode 100644 index 93e4028ab8..0000000000 --- a/src/status_im/persistence/realm_queries.cljs +++ /dev/null @@ -1,19 +0,0 @@ -(ns status-im.persistence.realm-queries - (:require [clojure.string :as s] - [status-im.utils.types :refer [to-string]])) - -(defn include-query [field-name values] - (->> values - (map (fn [val] - (str (to-string field-name) " == " (if (string? val) - (str "'" val "'") - val)))) - (s/join " || "))) - -(defn exclude-query [field-name values] - (->> values - (map (fn [val] - (str (to-string field-name) " != " (if (string? val) - (str "'" val "'") - val)))) - (s/join " && "))) \ No newline at end of file diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index 2b51651e8f..ccd2c23b4c 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -2,10 +2,10 @@ (:require [status-im.utils.handlers :as u] [re-frame.core :refer [dispatch after]] [status-im.utils.handlers :refer [register-handler]] - [status-im.models.contacts :as contacts] - [status-im.models.messages :as messages] - [status-im.models.pending-messages :as pending-messages] - [status-im.models.chats :as chats] + [status-im.data-store.contacts :as contacts] + [status-im.data-store.messages :as messages] + [status-im.data-store.pending-messages :as pending-messages] + [status-im.data-store.chats :as chats] [status-im.protocol.core :as protocol] [status-im.constants :refer [text-content-type]] [status-im.i18n :refer [label]] @@ -17,7 +17,7 @@ (let [{:keys [public-key status updates-public-key updates-private-key]} (get-in db [:accounts current-account-id])] - (let [groups (chats/active-group-chats) + (let [groups (chats/get-active-group-chats) w3 (protocol/init-whisper! {:rpc-url "http://localhost:8545" :identity public-key @@ -32,7 +32,7 @@ :profile-keypair {:public updates-public-key :private updates-private-key} :hashtags (u/get-hashtags status) - :pending-messages (pending-messages/get-pending-messages!) + :pending-messages (pending-messages/get-all) :contacts (keep (fn [{:keys [whisper-identity public-key private-key]}] @@ -40,8 +40,7 @@ {:identity whisper-identity :keypair {:public public-key :private private-key}})) - - (contacts/get-contacts))})] + (contacts/get-all))})] (assoc db :web3 w3))))) (register-handler :incoming-message @@ -77,40 +76,40 @@ :content-type text-content-type}) (defn joined-chat-message [chat-id from message-id] - (let [contact-name (:name (contacts/contact-by-identity from))] - (messages/save-message chat-id {:from "system" - :message-id (str message-id "_" from) - :content (str (or contact-name from) " " (label :t/received-invitation)) - :content-type text-content-type}))) + (let [contact-name (:name (contacts/get-by-id from))] + (messages/save chat-id {:from "system" + :message-id (str message-id "_" from) + :content (str (or contact-name from) " " (label :t/received-invitation)) + :content-type text-content-type}))) (defn participant-invited-to-group-message [chat-id current-identity identity from message-id] - (let [inviter-name (:name (contacts/contact-by-identity from)) + (let [inviter-name (:name (contacts/get-by-id from)) invitee-name (if (= identity current-identity) (label :t/You) - (:name (contacts/contact-by-identity identity)))] - (messages/save-message chat-id {:from "system" - :message-id message-id - :content (str (or inviter-name from) " " (label :t/invited) " " (or invitee-name identity)) - :content-type text-content-type}))) + (:name (contacts/get-by-id identity)))] + (messages/save chat-id {:from "system" + :message-id message-id + :content (str (or inviter-name from) " " (label :t/invited) " " (or invitee-name identity)) + :content-type text-content-type}))) (defn participant-removed-from-group-message [chat-id identity from message-id] - (let [remover-name (:name (contacts/contact-by-identity from)) - removed-name (:name (contacts/contact-by-identity identity))] + (let [remover-name (:name (contacts/get-by-id from)) + removed-name (:name (contacts/get-by-id identity))] (->> (str (or remover-name from) " " (label :t/removed) " " (or removed-name identity)) (system-message message-id) - (messages/save-message chat-id)))) + (messages/save chat-id)))) (defn you-removed-from-group-message [chat-id from message-id] - (let [remover-name (:name (contacts/contact-by-identity from))] + (let [remover-name (:name (contacts/get-by-id from))] (->> (str (or remover-name from) " " (label :t/removed-from-chat)) (system-message message-id) - (messages/save-message chat-id)))) + (messages/save chat-id)))) (defn participant-left-group-message [chat-id from message-id] - (let [left-name (:name (contacts/contact-by-identity from))] + (let [left-name (:name (contacts/get-by-id from))] (->> (str (or left-name from) " " (label :t/left)) (system-message message-id) - (messages/save-message chat-id)))) + (messages/save chat-id)))) (register-handler :group-chat-invite-acked (u/side-effect! @@ -122,7 +121,7 @@ (u/side-effect! (fn [_ [action from group-id identity message-id]] (log/debug action message-id from group-id identity) - (chats/chat-remove-participants group-id [identity]) + (chats/remove-contacts group-id [identity]) (participant-removed-from-group-message group-id identity from message-id)))) (register-handler :you-removed-from-group @@ -130,7 +129,7 @@ (fn [_ [action from group-id message-id]] (log/debug action message-id from group-id) (you-removed-from-group-message group-id from message-id) - (chats/set-chat-active group-id false)))) + (chats/set-active group-id false)))) (register-handler :participant-left-group (u/side-effect! @@ -153,7 +152,7 @@ (register-handler ::remove-identity-from-chat! (u/side-effect! (fn [_ [_ group-id identity]] - (chats/chat-remove-participants group-id [identity])))) + (chats/remove-contacts group-id [identity])))) (register-handler :participant-invited-to-group (u/side-effect! @@ -167,7 +166,7 @@ (register-handler :add-contact-to-group! (u/side-effect! (fn [_ [_ group-id identity]] - (when-not (chats/contact group-id identity) + (when-not (chats/has-contact? group-id identity) (dispatch [::add-contact group-id identity]) (dispatch [::store-contact! group-id identity]))))) @@ -178,14 +177,14 @@ (register-handler ::store-contact! (u/side-effect! (fn [_ [_ group-id identity]] - (chats/chat-add-participants group-id [identity])))) + (chats/add-contacts group-id [identity])))) (defn save-message-status! [status] (fn [_ [_ {:keys [from] {:keys [message-id ack-of-message group-id]} :payload}]] (let [message-id' (or ack-of-message message-id)] - (when-let [{:keys [message-status] :as message} (messages/get-message message-id')] + (when-let [{:keys [message-status] :as message} (messages/get-by-id message-id')] (when-not (= (keyword message-status) :seen) (let [group? (boolean group-id) message (if (and group? (not= status :sent)) @@ -198,7 +197,7 @@ old-status status)})) (assoc message :message-status status))] - (messages/update-message! message))))))) + (messages/update message))))))) (defn update-message-status [status] @@ -242,10 +241,10 @@ (register-handler :pending-message-upsert (after (fn [_ [_ {:keys [type id] :as pending-message}]] - (pending-messages/add-pending-message! pending-message) + (pending-messages/save pending-message) (when (#{:message :group-message} type) - (messages/update-message! {:message-id id - :delivery-status :pending})))) + (messages/update {:message-id id + :delivery-status :pending})))) (fn [db [_ {:keys [type id to group-id]}]] (if (#{:message :group-message} type) (let [chat-id (or group-id to) @@ -258,7 +257,7 @@ (register-handler :pending-message-remove (u/side-effect! (fn [_ [_ message]] - (pending-messages/remove-pending-message! message)))) + (pending-messages/delete message)))) (register-handler :contact-request-received (u/side-effect!