Add more apis for db graphs

1. get_all_tags
2. get_all_properties
3. get_tag_objects
This commit is contained in:
Tienson Qin
2025-10-07 22:07:03 +08:00
parent 3cc530a16f
commit 4800ed2ec6
9 changed files with 190 additions and 156 deletions

View File

@@ -1,14 +1,12 @@
(ns frontend.db.model
"Core db functions."
(:require [clojure.set :as set]
[clojure.string :as string]
(:require [clojure.string :as string]
[clojure.walk :as walk]
[datascript.core :as d]
[frontend.common.graph-view :as graph-view]
[frontend.config :as config]
[frontend.date :as date]
[frontend.db.conn :as conn]
[frontend.db.file-based.model :as file-model]
[frontend.db.react :as react]
[frontend.db.utils :as db-utils]
[frontend.state :as state]

View File

@@ -40,11 +40,13 @@
[logseq.common.util :as common-util]
[logseq.db :as ldb]
[logseq.db.common.entity-plus :as entity-plus]
[logseq.db.common.entity-util :as common-entity-util]
[logseq.db.common.initial-data :as common-initial-data]
[logseq.db.common.order :as db-order]
[logseq.db.common.reference :as db-reference]
[logseq.db.common.sqlite :as common-sqlite]
[logseq.db.common.view :as db-view]
[logseq.db.frontend.class :as db-class]
[logseq.db.frontend.schema :as db-schema]
[logseq.db.sqlite.create-graph :as sqlite-create-graph]
[logseq.db.sqlite.export :as sqlite-export]
@@ -700,6 +702,12 @@
(let [db @(worker-state/get-datascript-conn repo)]
(db-view/get-view-data db view-id option)))
(def-thread-api :thread-api/get-class-objects
[repo class-id]
(let [db @(worker-state/get-datascript-conn repo)]
(->> (db-class/get-class-objects db class-id)
(map common-entity-util/entity->map))))
(def-thread-api :thread-api/get-property-values
[repo {:keys [property-ident] :as option}]
(let [conn (worker-state/get-datascript-conn repo)]

View File

@@ -870,136 +870,6 @@
(editor-handler/expand-block! block-uuid))
nil)))))
;; properties (db only)
(defn -get-property
[^js plugin k]
(when-let [k' (and (string? k) (api-block/sanitize-user-property-name k))]
(let [property-ident (api-block/get-db-ident-from-property-name k' plugin)]
(db-utils/pull property-ident))))
(defn ^:export get_property
[k]
(this-as this
(p/let [prop (-get-property this k)]
(some-> prop
(assoc :type (:logseq.property/type prop))
(sdk-utils/normalize-keyword-for-json)
(bean/->js)))))
(defn ^:export upsert_property
"schema:
{:type :default | :number | :date | :datetime | :checkbox | :url | :node | :json | :string
:cardinality :many | :one
:hide? true
:view-context :page
:public? false}
"
[k ^js schema ^js opts]
(this-as this
(when-not (string/blank? k)
(p/let [opts (or (some-> opts bean/->clj) {})
property-ident (api-block/get-db-ident-from-property-name k this)
_ (api-block/ensure-property-upsert-control this property-ident k)
schema (or (some-> schema (bean/->clj)
(update-keys #(if (contains? #{:hide :public} %)
(keyword (str (name %) "?")) %))) {})
schema (cond-> schema
(string? (:cardinality schema))
(-> (assoc :db/cardinality (keyword (:cardinality schema)))
(dissoc :cardinality))
(string? (:type schema))
(-> (assoc :logseq.property/type (keyword (:type schema)))
(dissoc :type)))
p (db-property-handler/upsert-property! property-ident schema
(assoc opts :property-name name))
p (db-utils/pull (:db/id p))]
(bean/->js (sdk-utils/normalize-keyword-for-json p))))))
(defn ^:export remove_property
[k]
(this-as
this
(p/let [property (-get-property this k)]
(db-api/remove-property property))))
;; block properties
(defn ^:export upsert_block_property
[block-uuid key ^js value ^js options]
(this-as
this
(p/let [keyname (api-block/sanitize-user-property-name key)
opts (bean/->clj options)
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
repo (state/get-current-repo)
block (<get-block block-uuid {:children? false})
db-based? (db-graph?)
key' (-> (if (keyword? keyname) (name keyname) keyname) (util/trim-safe))
value (bean/->clj value)]
(when block
(if db-based?
(db-api/upsert-block-property this block key' value (:schema opts))
(property-handler/set-block-property! repo block-uuid key' value))))))
(defn ^:export remove_block_property
[block-uuid key]
(this-as this
(p/let [key (api-block/sanitize-user-property-name key)
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
_block (<get-block block-uuid {:children? false})
db-based? (db-graph?)
key-ns? (and (keyword? key) (namespace key))
key (if key-ns? key (if (keyword? key) (name key) key))
key (if (and db-based? (not key-ns?))
(api-block/get-db-ident-from-property-name
key (api-block/resolve-property-prefix-for-db this))
key)]
(property-handler/remove-block-property!
(state/get-current-repo)
block-uuid key))))
(defn ^:export get_block_property
[block-uuid key]
(this-as this
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
_block (<get-block block-uuid {:children? false})]
(when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
(when (seq properties)
(let [key (api-block/sanitize-user-property-name key)
property-name (if (keyword? key) (name key) key)
ident (api-block/get-db-ident-from-property-name
property-name (api-block/resolve-property-prefix-for-db this))
property-value (or (get properties key)
(get properties (keyword property-name))
(get properties ident))
property-value (if-let [property-id (:db/id property-value)]
(db/pull property-id) property-value)
property-value (cond-> property-value
(map? property-value)
(assoc
:value (or (:logseq.property/value property-value)
(:block/title property-value))
:ident ident))
parsed-value (api-block/parse-property-json-value-if-need ident property-value)]
(or parsed-value
(bean/->js (sdk-utils/normalize-keyword-for-json property-value)))))))))
(def ^:export get_block_properties
(fn [block-uuid]
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
block (<get-block block-uuid {:children? false})]
(when block
(let [properties (if (db-graph?)
(api-block/into-readable-db-properties (:block/properties block))
(:block/properties block))]
(db-api/result->js properties))))))
(defn ^:export get_page_properties
[id-or-page-name]
(p/let [page (<get-block id-or-page-name {:children? false})]
(when-let [id (:block/uuid page)]
(get_block_properties id))))
(def ^:export get_current_page_blocks_tree
(fn []
(when-let [page (state/get-current-page)]
@@ -1188,6 +1058,141 @@
[]
true)
;; block properties
(defn ^:export upsert_block_property
[block-uuid key ^js value ^js options]
(this-as
this
(p/let [keyname (api-block/sanitize-user-property-name key)
opts (bean/->clj options)
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
repo (state/get-current-repo)
block (<get-block block-uuid {:children? false})
db-based? (db-graph?)
key' (-> (if (keyword? keyname) (name keyname) keyname) (util/trim-safe))
value (bean/->clj value)]
(when block
(if db-based?
(db-api/upsert-block-property this block key' value (:schema opts))
(property-handler/set-block-property! repo block-uuid key' value))))))
(defn ^:export remove_block_property
[block-uuid key]
(this-as this
(p/let [key (api-block/sanitize-user-property-name key)
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
_block (<get-block block-uuid {:children? false})
db-based? (db-graph?)
key-ns? (and (keyword? key) (namespace key))
key (if key-ns? key (if (keyword? key) (name key) key))
key (if (and db-based? (not key-ns?))
(api-block/get-db-ident-from-property-name
key (api-block/resolve-property-prefix-for-db this))
key)]
(property-handler/remove-block-property!
(state/get-current-repo)
block-uuid key))))
(defn ^:export get_block_property
[block-uuid key]
(this-as this
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
_block (<get-block block-uuid {:children? false})]
(when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
(when (seq properties)
(let [key (api-block/sanitize-user-property-name key)
property-name (if (keyword? key) (name key) key)
ident (api-block/get-db-ident-from-property-name
property-name (api-block/resolve-property-prefix-for-db this))
property-value (or (get properties key)
(get properties (keyword property-name))
(get properties ident))
property-value (if-let [property-id (:db/id property-value)]
(db/pull property-id) property-value)
property-value (cond-> property-value
(map? property-value)
(assoc
:value (or (:logseq.property/value property-value)
(:block/title property-value))
:ident ident))
parsed-value (api-block/parse-property-json-value-if-need ident property-value)]
(or parsed-value
(bean/->js (sdk-utils/normalize-keyword-for-json property-value)))))))))
(def ^:export get_block_properties
(fn [block-uuid]
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
block (<get-block block-uuid {:children? false})]
(when block
(let [properties (if (db-graph?)
(api-block/into-readable-db-properties (:block/properties block))
(:block/properties block))]
(db-api/result->js properties))))))
(defn ^:export get_page_properties
[id-or-page-name]
(p/let [page (<get-block id-or-page-name {:children? false})]
(when-let [id (:block/uuid page)]
(get_block_properties id))))
;; db based graph APIs
;; properties (db only)
(defn -get-property
[^js plugin k]
(when-let [k' (and (string? k) (api-block/sanitize-user-property-name k))]
(let [property-ident (api-block/get-db-ident-from-property-name k' plugin)]
(db-utils/pull property-ident))))
(defn ^:export get_property
[k]
(this-as this
(p/let [prop (-get-property this k)]
(some-> prop
(assoc :type (:logseq.property/type prop))
(sdk-utils/normalize-keyword-for-json)
(bean/->js)))))
(defn ^:export upsert_property
"schema:
{:type :default | :number | :date | :datetime | :checkbox | :url | :node | :json | :string
:cardinality :many | :one
:hide? true
:view-context :page
:public? false}
"
[k ^js schema ^js opts]
(this-as this
(when-not (string/blank? k)
(p/let [opts (or (some-> opts bean/->clj) {})
property-ident (api-block/get-db-ident-from-property-name k this)
_ (api-block/ensure-property-upsert-control this property-ident k)
schema (or (some-> schema (bean/->clj)
(update-keys #(if (contains? #{:hide :public} %)
(keyword (str (name %) "?")) %))) {})
schema (cond-> schema
(string? (:cardinality schema))
(-> (assoc :db/cardinality (keyword (:cardinality schema)))
(dissoc :cardinality))
(string? (:type schema))
(-> (assoc :logseq.property/type (keyword (:type schema)))
(dissoc :type)))
p (db-property-handler/upsert-property! property-ident schema
(assoc opts :property-name name))
p (db-utils/pull (:db/id p))]
(bean/->js (sdk-utils/normalize-keyword-for-json p))))))
(defn ^:export remove_property
[k]
(this-as
this
(p/let [property (-get-property this k)]
(db-api/remove-property property))))
(def ^:export get_all_tags db-api/get-all-tags)
(def ^:export get-all-properties db-api/get-all-properties)
(def ^:export get-tag-objects db-api/get-tag-objects)
;; file based graph APIs
(def ^:export get_current_graph_templates file-api/get_current_graph_templates)
(def ^:export get_template file-api/get_template)

View File

@@ -2,7 +2,6 @@
"Block related apis"
(:require [cljs-bean.core :as bean]
[clojure.string :as string]
[frontend.config :as config]
[frontend.db :as db]
[frontend.db.async :as db-async]
[frontend.db.model :as db-model]
@@ -69,10 +68,6 @@
(db-pu/readable-properties
{:original-key? true :key-fn str})))
(defn- entity->map
[e]
(assoc (into {} e) :db/id (:db/id e)))
(defn parse-property-json-value-if-need
[ident property-value]
(when-let [prop (and (string? property-value)

View File

@@ -5,6 +5,7 @@
[clojure.walk :as walk]
[datascript.core :as d]
[frontend.db :as db]
[frontend.db.model :as db-model]
[frontend.handler.common.page :as page-common-handler]
[frontend.handler.editor :as editor-handler]
[frontend.handler.page :as page-handler]
@@ -96,7 +97,24 @@
{key schema})}]
(api-block/db-based-save-block-properties! block {key' value} opts)))
;; TODO:
;; get all tags
;; get all properties
;; get tag objects
(defn get-all-tags
[]
(-> (db-model/get-all-classes (state/get-current-repo)
{:except-root-class? true})
result->js))
(defn get-all-properties
[]
(-> (ldb/get-all-properties (db/get-db))
result->js))
(defn get-tag-objects
[class-uuid]
(let [id (sdk-utils/uuid-or-throw-error class-uuid)
class (db/entity [:block/uuid id])]
(if-not class
(throw (ex-info (str "Tag not exists with id: " class-uuid) {}))
(p/let [result (state/<invoke-db-worker :thread-api/get-class-objects
(state/get-current-repo)
(:db/id class))]
(result->js result)))))

View File

@@ -6,6 +6,7 @@
[frontend.db :as db]
[frontend.util :as util]
[goog.object :as gobj]
[logseq.db.common.entity-util :as common-entity-util]
[logseq.db.frontend.content :as db-content]))
(defn- keep-json-keyword?
@@ -14,12 +15,6 @@
(contains? #{"block" "db" "file"})
(not)))
(defn- entity->map
"Convert a db Entity to a map"
[e]
(assert (de/entity? e))
(assoc (into {} e) :db/id (:db/id e)))
(defn remove-hidden-properties
[m]
(->> (remove (fn [[k _v]]
@@ -32,9 +27,9 @@
([input camel-case?]
(when input
(let [input (cond
(de/entity? input) (entity->map input)
(de/entity? input) (common-entity-util/entity->map input)
(sequential? input) (map #(if (de/entity? %)
(entity->map %)
(common-entity-util/entity->map %)
%) input)
:else input)]
(walk/prewalk