diff --git a/deps/db/src/logseq/db/common/entity_util.cljs b/deps/db/src/logseq/db/common/entity_util.cljs index a21736b5f1..97efc7f07f 100644 --- a/deps/db/src/logseq/db/common/entity_util.cljs +++ b/deps/db/src/logseq/db/common/entity_util.cljs @@ -1,6 +1,7 @@ (ns logseq.db.common.entity-util "Lower level entity util fns for DB and file graphs" - (:require [logseq.db.file-based.entity-util :as file-entity-util] + (:require [datascript.impl.entity :as de] + [logseq.db.file-based.entity-util :as file-entity-util] [logseq.db.frontend.entity-util :as entity-util])) (defn whiteboard? @@ -17,3 +18,9 @@ [entity] (or (entity-util/page? entity) (file-entity-util/page? entity))) + +(defn entity->map + "Convert a db Entity to a map" + [e] + (assert (de/entity? e)) + (assoc (into {} e) :db/id (:db/id e))) diff --git a/deps/db/src/logseq/db/common/view.cljs b/deps/db/src/logseq/db/common/view.cljs index 96c9218114..0e172123c0 100644 --- a/deps/db/src/logseq/db/common/view.cljs +++ b/deps/db/src/logseq/db/common/view.cljs @@ -318,11 +318,7 @@ (get-entities-for-all-pages db sorting property-ident {:db-based? db-based?}) :class-objects - (let [class-id view-for-id - 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)) + (db-class/get-class-objects db view-for-id) :property-objects (->> diff --git a/deps/db/src/logseq/db/frontend/class.cljs b/deps/db/src/logseq/db/frontend/class.cljs index 77455564c0..a26df9fe75 100644 --- a/deps/db/src/logseq/db/frontend/class.cljs +++ b/deps/db/src/logseq/db/frontend/class.cljs @@ -7,6 +7,7 @@ [flatland.ordered.map :refer [ordered-map]] [logseq.common.defkeywords :refer [defkeywords]] [logseq.db.frontend.db-ident :as db-ident] + [logseq.db.frontend.entity-util :as entity-util] [logseq.db.frontend.rules :as rules] [logseq.db.sqlite.util :as sqlite-util])) @@ -173,3 +174,14 @@ "Determines if namespace string is a user class" [s] (string/includes? s ".class")) + +(defn get-class-objects + "Get class objects including children classes'" + [db class-id] + (let [class-children (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) + non-hidden-e (fn [id] (let [e (d/entity db id)] + (when-not (entity-util/hidden? e) + e)))] + (keep (fn [d] (non-hidden-e (:e d))) datoms))) diff --git a/src/main/frontend/db/model.cljs b/src/main/frontend/db/model.cljs index 1807ab5e4c..bc702411bc 100644 --- a/src/main/frontend/db/model.cljs +++ b/src/main/frontend/db/model.cljs @@ -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] diff --git a/src/main/frontend/worker/db_worker.cljs b/src/main/frontend/worker/db_worker.cljs index 795703ad57..4218ef5fa3 100644 --- a/src/main/frontend/worker/db_worker.cljs +++ b/src/main/frontend/worker/db_worker.cljs @@ -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)] diff --git a/src/main/logseq/api.cljs b/src/main/logseq/api.cljs index 7f642a623e..c55b4214d1 100644 --- a/src/main/logseq/api.cljs +++ b/src/main/logseq/api.cljs @@ -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 ( (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 ( 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 (js properties)))))) - -(defn ^:export get_page_properties - [id-or-page-name] - (p/let [page (clj options) + block-uuid (sdk-utils/uuid-or-throw-error block-uuid) + repo (state/get-current-repo) + block ( (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 ( 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 (js properties)))))) + +(defn ^:export get_page_properties + [id-or-page-name] + (p/let [page ( 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) diff --git a/src/main/logseq/api/block.cljs b/src/main/logseq/api/block.cljs index c9052d5b07..f70aade179 100644 --- a/src/main/logseq/api/block.cljs +++ b/src/main/logseq/api/block.cljs @@ -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) diff --git a/src/main/logseq/api/db.cljs b/src/main/logseq/api/db.cljs index 5abe60a70e..e93b07c177 100644 --- a/src/main/logseq/api/db.cljs +++ b/src/main/logseq/api/db.cljs @@ -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/js result))))) diff --git a/src/main/logseq/sdk/utils.cljs b/src/main/logseq/sdk/utils.cljs index 621ff630f2..f913794503 100644 --- a/src/main/logseq/sdk/utils.cljs +++ b/src/main/logseq/sdk/utils.cljs @@ -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