mirror of
https://github.com/logseq/logseq.git
synced 2026-05-03 10:26:35 +00:00
refactor(db): move some fn into react
This commit is contained in:
@@ -5,20 +5,159 @@
|
||||
solution.
|
||||
"
|
||||
(:require [frontend.db.conn :as conn]
|
||||
[frontend.db.utils :as db-utils]
|
||||
[frontend.db.model :as model]
|
||||
[frontend.db.base :as base]
|
||||
[frontend.state :as state]
|
||||
[frontend.date :as date]
|
||||
[frontend.util :as util :refer-macros [profile] :refer [react]]
|
||||
[clojure.string :as string]
|
||||
[frontend.config :as config]
|
||||
[frontend.format :as format]
|
||||
[cljs-time.core :as t]
|
||||
[cljs-time.coerce :as tc]
|
||||
[frontend.utf8 :as utf8]
|
||||
[datascript.core :as d]
|
||||
[lambdaisland.glogi :as log]))
|
||||
|
||||
;; Query atom of map of Key ([repo q inputs]) -> atom
|
||||
;; TODO: replace with LRUCache, only keep the latest 20 or 50 items?
|
||||
|
||||
(defonce query-state (atom {}))
|
||||
|
||||
(def ^:dynamic *query-component*)
|
||||
|
||||
;; key -> components
|
||||
(defonce query-components (atom {}))
|
||||
|
||||
(defn set-new-result!
|
||||
[k new-result]
|
||||
(when-let [result-atom (get-in @query-state [k :result])]
|
||||
(reset! result-atom new-result)))
|
||||
|
||||
;; KV
|
||||
|
||||
(defn kv
|
||||
[key value]
|
||||
{:db/id -1
|
||||
:db/ident key
|
||||
key value})
|
||||
|
||||
(defn remove-key!
|
||||
[repo-url key]
|
||||
(base/transact! repo-url [[:db.fn/retractEntity [:db/ident key]]])
|
||||
(set-new-result! [repo-url :kv key] nil))
|
||||
|
||||
(defn clear-query-state!
|
||||
[]
|
||||
(reset! query-state {}))
|
||||
|
||||
(defn clear-query-state-without-refs-and-embeds!
|
||||
[]
|
||||
(let [state @query-state
|
||||
state (->> (filter (fn [[[_repo k] v]]
|
||||
(contains? #{:blocks :block/block :custom} k)) state)
|
||||
(into {}))]
|
||||
(reset! query-state state)))
|
||||
|
||||
;; TODO: Add components which subscribed to a specific query
|
||||
(defn add-q!
|
||||
[k query inputs result-atom transform-fn query-fn inputs-fn]
|
||||
(swap! query-state assoc k {:query query
|
||||
:inputs inputs
|
||||
:result result-atom
|
||||
:transform-fn transform-fn
|
||||
:query-fn query-fn
|
||||
:inputs-fn inputs-fn})
|
||||
result-atom)
|
||||
|
||||
(defn remove-q!
|
||||
[k]
|
||||
(swap! query-state dissoc k))
|
||||
|
||||
(defn add-query-component!
|
||||
[key component]
|
||||
(swap! query-components update key
|
||||
(fn [components]
|
||||
(distinct (conj components component)))))
|
||||
|
||||
(defn remove-query-component!
|
||||
[component]
|
||||
(reset!
|
||||
query-components
|
||||
(->> (for [[k components] @query-components
|
||||
:let [new-components (remove #(= component %) components)]]
|
||||
(if (empty? new-components) ; no subscribed components
|
||||
(do (remove-q! k)
|
||||
nil)
|
||||
[k new-components]))
|
||||
(keep identity)
|
||||
(into {}))))
|
||||
|
||||
(defn get-page-blocks-cache-atom
|
||||
[repo page-id]
|
||||
(:result (get @query-state [repo :page/blocks page-id])))
|
||||
|
||||
(defn get-block-blocks-cache-atom
|
||||
[repo block-id]
|
||||
(:result (get @query-state [repo :block/block block-id])))
|
||||
|
||||
;; TODO: rename :custom to :query/custom
|
||||
(defn remove-custom-query!
|
||||
[repo query]
|
||||
(remove-q! [repo :custom query]))
|
||||
|
||||
;; Reactive query
|
||||
|
||||
|
||||
(defn query-entity-in-component
|
||||
([id-or-lookup-ref]
|
||||
(base/entity (state/get-current-repo) id-or-lookup-ref))
|
||||
([repo id-or-lookup-ref]
|
||||
(let [k [:entity id-or-lookup-ref]
|
||||
result-atom (:result (get @query-state k))]
|
||||
(when-let [component *query-component*]
|
||||
(add-query-component! k component))
|
||||
(when-let [db (conn/get-conn repo)]
|
||||
(let [result (d/entity db id-or-lookup-ref)
|
||||
result-atom (or result-atom (atom nil))]
|
||||
(set! (.-state result-atom) result)
|
||||
(add-q! k nil nil result-atom identity identity identity))))))
|
||||
|
||||
(defn q
|
||||
[repo k {:keys [use-cache? files-db? transform-fn query-fn inputs-fn]
|
||||
:or {use-cache? true
|
||||
files-db? false
|
||||
transform-fn identity}} query & inputs]
|
||||
(let [kv? (and (vector? k) (= :kv (first k)))
|
||||
k (vec (cons repo k))]
|
||||
(when-let [conn (if files-db?
|
||||
(when-let [files-conn (conn/get-files-conn repo)]
|
||||
(deref files-conn))
|
||||
(conn/get-conn repo))]
|
||||
(let [result-atom (:result (get @query-state k))]
|
||||
(when-let [component *query-component*]
|
||||
(add-query-component! k component))
|
||||
(if (and use-cache? result-atom)
|
||||
result-atom
|
||||
(let [result (cond
|
||||
query-fn
|
||||
(query-fn conn)
|
||||
|
||||
inputs-fn
|
||||
(let [inputs (inputs-fn)]
|
||||
(apply d/q query conn inputs))
|
||||
|
||||
kv?
|
||||
(d/entity conn (last k))
|
||||
|
||||
(seq inputs)
|
||||
(apply d/q query conn inputs)
|
||||
|
||||
:else
|
||||
(d/q query conn))
|
||||
result (transform-fn result)
|
||||
result-atom (or result-atom (atom nil))]
|
||||
;; Don't notify watches now
|
||||
(set! (.-state result-atom) result)
|
||||
(add-q! k query inputs result-atom transform-fn query-fn inputs-fn)))))))
|
||||
|
||||
|
||||
|
||||
;; TODO: Extract several parts to handlers
|
||||
|
||||
(defn get-current-page
|
||||
@@ -39,7 +178,7 @@
|
||||
(date/journal-name))]
|
||||
(when page
|
||||
(let [page-name (util/url-decode (string/lower-case page))]
|
||||
(model/entity (if tag?
|
||||
(base/entity (if tag?
|
||||
[:tag/name page-name]
|
||||
[:page/name page-name]))))))
|
||||
|
||||
@@ -106,7 +245,7 @@
|
||||
(apply concat
|
||||
(for [{:block/keys [ref-pages]} blocks]
|
||||
(map (fn [page]
|
||||
(when-let [page (model/entity [:page/name (:page/name page)])]
|
||||
(when-let [page (base/entity [:page/name (:page/name page)])]
|
||||
[:page/refed-blocks (:db/id page)]))
|
||||
ref-pages)))
|
||||
|
||||
@@ -126,14 +265,14 @@
|
||||
(filter (fn [v]
|
||||
(and (= (first v) (state/get-current-repo))
|
||||
(= (second v) :custom)))
|
||||
(keys @model/query-state))
|
||||
(keys @query-state))
|
||||
(map (fn [v]
|
||||
(vec (drop 1 v)))))
|
||||
block-blocks (some->>
|
||||
(filter (fn [v]
|
||||
(and (= (first v) (state/get-current-repo))
|
||||
(= (second v) :block/block)))
|
||||
(keys @model/query-state))
|
||||
(keys @query-state))
|
||||
(map (fn [v]
|
||||
(vec (drop 1 v)))))]
|
||||
(->>
|
||||
@@ -162,7 +301,7 @@
|
||||
handler-keys (get-handler-keys handler-opts)]
|
||||
(doseq [handler-key handler-keys]
|
||||
(let [handler-key (vec (cons repo-url handler-key))]
|
||||
(when-let [cache (get @model/query-state handler-key)]
|
||||
(when-let [cache (get @query-state handler-key)]
|
||||
(let [{:keys [query inputs transform-fn query-fn inputs-fn]} cache]
|
||||
(when (or query query-fn)
|
||||
(let [new-result (->
|
||||
@@ -177,7 +316,7 @@
|
||||
(apply d/q query db inputs))
|
||||
|
||||
(keyword? query)
|
||||
(model/get-key-value repo-url query)
|
||||
(base/get-key-value repo-url query)
|
||||
|
||||
(seq inputs)
|
||||
(apply d/q query db inputs)
|
||||
@@ -185,7 +324,7 @@
|
||||
:else
|
||||
(d/q query db))
|
||||
transform-fn)]
|
||||
(model/set-new-result! handler-key new-result))))))))))
|
||||
(set-new-result! handler-key new-result))))))))))
|
||||
(catch js/Error e
|
||||
;; FIXME: check error type and notice user
|
||||
(log/error :db/transact! e)))))
|
||||
@@ -193,9 +332,9 @@
|
||||
(defn set-key-value
|
||||
[repo-url key value]
|
||||
(if value
|
||||
(transact-react! repo-url [(model/kv key value)]
|
||||
(transact-react! repo-url [(kv key value)]
|
||||
{:key [:kv key]})
|
||||
(model/remove-key! repo-url key)))
|
||||
(remove-key! repo-url key)))
|
||||
|
||||
(defn set-file-content!
|
||||
[repo path content]
|
||||
|
||||
Reference in New Issue
Block a user