unify data loading for class/property objects and all pages

This commit is contained in:
Tienson Qin
2025-03-10 09:16:34 +08:00
parent 555c2d92f3
commit 5abdfca0ec
5 changed files with 94 additions and 95 deletions

View File

@@ -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
;; ==========

View File

@@ -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)})))))

View File

@@ -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/<get-tag-objects (state/get-current-repo) (:db/id class))]
(react/refresh! (state/get-current-repo)
[[:frontend.worker.react/objects (:db/id class)]])
(set-data! (get-class-objects class))
(set-loading? false))))
[])
(views/view {:config config
:data data
:set-data! set-data!
@@ -151,21 +136,8 @@
(rum/defc property-related-objects-inner < rum/static
[config property 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)
columns (views/build-columns config properties)]
(hooks/use-effect!
(fn []
(when (nil? loading?)
(set-loading? true)
(p/let [result (db-async/<get-property-objects (state/get-current-repo) (:db/ident property))]
(set-data! (mapv (fn [m]
(let [e (db/entity (:db/id m))]
(assoc e :id (:db/id m)))) result))
(set-loading? false))))
[])
(views/view {:config config
:data data
:view-parent property

View File

@@ -18,7 +18,6 @@
[frontend.util :as util]
[logseq.db :as ldb]
[logseq.db.frontend.property :as db-property]
[logseq.db.frontend.rules :as rules]
[promesa.core :as p]))
(def <q db-async-util/<q)
@@ -287,17 +286,6 @@
[?page :block/name]]
tag-id))
(defn <get-property-objects
[graph property-ident]
(<q graph {:transact-db? true}
'[:find [(pull ?b [*]) ...]
:in $ % ?prop
:where
(has-property-or-default-value? ?b ?prop)]
(rules/extract-rules rules/db-query-dsl-rules [:has-property-or-default-value]
{:deps rules/rules-dependencies})
property-ident))
(defn <get-tag-objects
[graph class-id]
(let [class-children (db-model/get-structured-children graph class-id)

View File

@@ -17,6 +17,7 @@
[logseq.common.util :as common-util]
[logseq.common.util.date-time :as date-time-util]
[logseq.db :as ldb]
[logseq.db.frontend.class :as db-class]
[logseq.db.frontend.content :as db-content]
[logseq.db.frontend.rules :as rules]
[logseq.graph-parser.db :as gp-db]))
@@ -822,15 +823,7 @@ independent of format as format specific heading characters are stripped"
(defn get-structured-children
[repo eid]
(->>
(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]