From 5abdfca0ec99f0de1ebf9d77fb73335de374b4c8 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 10 Mar 2025 09:16:34 +0800 Subject: [PATCH] unify data loading for class/property objects and all pages --- deps/db/src/logseq/db/frontend/class.cljs | 14 +++ deps/db/src/logseq/db/frontend/view.cljs | 120 ++++++++++++++-------- src/main/frontend/components/objects.cljs | 32 +----- src/main/frontend/db/async.cljs | 12 --- src/main/frontend/db/model.cljs | 11 +- 5 files changed, 94 insertions(+), 95 deletions(-) diff --git a/deps/db/src/logseq/db/frontend/class.cljs b/deps/db/src/logseq/db/frontend/class.cljs index 3805a796a6..9e06fd7342 100644 --- a/deps/db/src/logseq/db/frontend/class.cljs +++ b/deps/db/src/logseq/db/frontend/class.cljs @@ -1,9 +1,11 @@ (ns logseq.db.frontend.class "Class related fns for DB graphs and frontend/datascript usage" (:require [clojure.set :as set] + [datascript.core :as d] [flatland.ordered.map :refer [ordered-map]] [logseq.common.defkeywords :refer [defkeywords]] [logseq.db.frontend.db-ident :as db-ident] + [logseq.db.frontend.rules :as rules] [logseq.db.sqlite.util :as sqlite-util])) ;; Main class vars @@ -115,6 +117,18 @@ "Built-in classes that are hidden in a few contexts like property values" #{:logseq.class/Page :logseq.class/Root :logseq.class/Asset}) +(defn get-structured-children + [db eid] + (->> + (d/q '[:find [?children ...] + :in $ ?parent % + :where + (parent ?parent ?children)] + db + eid + (:parent rules/rules)) + (remove #{eid}))) + ;; Helper fns ;; ========== diff --git a/deps/db/src/logseq/db/frontend/view.cljs b/deps/db/src/logseq/db/frontend/view.cljs index ad2ad9d603..a396098a03 100644 --- a/deps/db/src/logseq/db/frontend/view.cljs +++ b/deps/db/src/logseq/db/frontend/view.cljs @@ -8,7 +8,8 @@ [logseq.db.frontend.class :as db-class] [logseq.db.frontend.entity-util :as entity-util] [logseq.db.frontend.property :as db-property] - [logseq.db.frontend.property.type :as db-property-type])) + [logseq.db.frontend.property.type :as db-property-type] + [logseq.db.frontend.rules :as rules])) (defn get-property-value-for-search [block property] @@ -89,7 +90,7 @@ (sort (by sorting') rows))) (defn sort-rows - "Support multiple sorts" + "Support multiple properties sort" [db sorting rows] (let [[single-property asc?] (case (count sorting) 0 @@ -205,47 +206,78 @@ result))) (:filters filters)))) +(defn- get-entities + [db view feat-type property-ident] + (let [view-for (:logseq.property/view-for view) + non-hidden-e (fn [id] (let [e (d/entity db id)] + (when-not (entity-util/hidden? e) + e)))] + (case feat-type + :all-pages + (keep (fn [d] + (let [e (d/entity db (:e d))] + (when-not (hidden-or-internal-tag? e) + e))) + (d/datoms db :avet property-ident)) + :class-objects + (let [class-id (:db/id view-for) + class-children (db-class/get-structured-children db class-id) + class-ids (distinct (conj class-children class-id)) + datoms (mapcat (fn [id] (d/datoms db :avet :block/tags id)) class-ids)] + (keep (fn [d] (non-hidden-e (:e d))) datoms)) + :property-objects + (->> + (d/q + '[:find [?b ...] + :in $ % ?prop + :where + (has-property-or-default-value? ?b ?prop)] + db + (rules/extract-rules rules/db-query-dsl-rules [:has-property-or-default-value] + {:deps rules/rules-dependencies}) + property-ident) + (keep (fn [id] (non-hidden-e id)))) + nil))) + (defn get-view-data [db view-id] - (let [view (d/entity db view-id) - feat-type (:logseq.property.view/feature-type view) - index-attr (case feat-type - :all-pages - :block/name - :class-objects - :block/tags - :property-objects - (let [view-for (:logseq.property/view-for view)] - (:db/ident view-for)) - nil) - all-pages? (= feat-type :all-pages) - filters (:logseq.property.table/filters view)] - (when index-attr - (let [datoms (d/datoms db :avet index-attr) - entities (->> datoms - (keep (fn [d] - (let [e (d/entity db (:e d))] - (when-not (and all-pages? (hidden-or-internal-tag? e)) - e))))) - sorting (let [sorting* (:logseq.property.table/sorting view)] - (if (or (= sorting* :logseq.property/empty-placeholder) (empty? sorting*)) - [{:id :block/updated-at, :asc? false}] - sorting*)) - data (->> - ;; filter - (cond->> entities - (seq filters) - (filter (fn [row] (row-matched? db row filters)))) - ;; sort - (sort-rows db sorting) - ;; pagination - (take 100) - ;; convert entity to map for serialization - (map (fn [e] - (cond-> - (-> (into {} e) - (assoc :db/id (:db/id e))) - all-pages? - (assoc :block.temp/refs-count (count (:block/_refs e)))))))] - {:count (count entities) - :data (vec data)})))) + (time + (let [view (d/entity db view-id) + feat-type (:logseq.property.view/feature-type view) + index-attr (case feat-type + :all-pages + :block/name + :class-objects + :block/tags + :property-objects + (let [view-for (:logseq.property/view-for view)] + (:db/ident view-for)) + nil) + all-pages? (= feat-type :all-pages) + filters (:logseq.property.table/filters view)] + (when index-attr + (let [entities (get-entities db view feat-type index-attr) + sorting (let [sorting* (:logseq.property.table/sorting view)] + (if (or (= sorting* :logseq.property/empty-placeholder) (empty? sorting*)) + [{:id :block/updated-at, :asc? false}] + sorting*)) + data (->> + ;; filter + (cond->> entities + (seq filters) + (filter (fn [row] (row-matched? db row filters)))) + ;; sort + (sort-rows db sorting) + ;; pagination + (take 100) + ;; convert entity to map for serialization + (map (fn [e] + (cond-> + (-> (into {} e) + (assoc + :id (:db/id e) + :db/id (:db/id e))) + all-pages? + (assoc :block.temp/refs-count (count (:block/_refs e)))))))] + {:count (count entities) + :data (vec data)}))))) diff --git a/src/main/frontend/components/objects.cljs b/src/main/frontend/components/objects.cljs index f83a44b216..7948952528 100644 --- a/src/main/frontend/components/objects.cljs +++ b/src/main/frontend/components/objects.cljs @@ -4,11 +4,8 @@ [frontend.components.views :as views] [frontend.db :as db] [frontend.db-mixins :as db-mixins] - [frontend.db.async :as db-async] [frontend.db.model :as db-model] - [frontend.db.react :as react] [frontend.handler.editor :as editor-handler] - [frontend.hooks :as hooks] [frontend.mixins :as mixins] [frontend.modules.outliner.op :as outliner-op] [frontend.modules.outliner.ui :as ui-outliner-tx] @@ -48,8 +45,7 @@ (rum/defc class-objects-inner < rum/static [config class objects properties] - (let [[loading? set-loading?] (rum/use-state nil) - [data set-data!] (rum/use-state objects) + (let [[data set-data!] (rum/use-state objects) ;; Properties can be nil for published private graphs properties' (remove nil? properties) columns* (views/build-columns config properties' {:add-tags-column? (or (= (:db/ident class) :logseq.class/Root) @@ -67,17 +63,6 @@ (concat before-cols [(build-asset-file-column config)] after-cols)) columns)] - (hooks/use-effect! - (fn [] - (when (nil? loading?) - (set-loading? true) - (p/let [_result (db-async/> - (d/q '[:find [?children ...] - :in $ ?parent % - :where - (parent ?parent ?children)] - (conn/get-db repo) - eid - (:parent rules/rules)) - (remove #{eid}))) + (db-class/get-structured-children (conn/get-db repo) eid)) (defn get-class-objects [repo class-id]