Skip to content

Commit

Permalink
Merge pull request logseq#11634 from logseq/refactor/tag-as-type
Browse files Browse the repository at this point in the history
refactor: replace :block/type with :block/tags
  • Loading branch information
tiensonqin authored Dec 24, 2024
2 parents 94d44f0 + 48cb4d2 commit fbefade
Show file tree
Hide file tree
Showing 94 changed files with 2,397 additions and 1,695 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ resources/electron.js
.clj-kondo/metosin/malli
.clj-kondo/rewrite-clj
.clj-kondo/taoensso
.clj-kondo/funcool
/libs/dist/
charlie/
.vscode
Expand Down
2 changes: 2 additions & 0 deletions deps/db/.carve/ignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ logseq.db.frontend.inputs/resolve-input
;; API
logseq.db.frontend.class/build-new-class
;; API
logseq.db.frontend.class/page-children-classes
;; API
logseq.db.frontend.db-ident/ensure-unique-db-ident
;; API
logseq.db.sqlite.build/create-blocks
83 changes: 54 additions & 29 deletions deps/db/src/logseq/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
[logseq.db.sqlite.util :as sqlite-util]
[logseq.db.frontend.property :as db-property]
[logseq.common.util.namespace :as ns-util]
[logseq.common.util.page-ref :as page-ref])
[logseq.common.util.page-ref :as page-ref]
[clojure.walk :as walk])
(:refer-clojure :exclude [object?]))

(defonce *transact-fn (atom nil))
Expand All @@ -40,11 +41,25 @@
m))
tx-data)))

(defn assert-no-entities
[tx-data]
(walk/prewalk
(fn [f]
(if (de/entity? f)
(throw (ex-info "ldb/transact! doesn't support Entity"
{:entity f
:tx-data tx-data}))
f))
tx-data))

(defn transact!
"`repo-or-conn`: repo for UI thread and conn for worker/node"
([repo-or-conn tx-data]
(transact! repo-or-conn tx-data nil))
([repo-or-conn tx-data tx-meta]
(when (and (exists? js/goog)
(aget js/goog "DEBUG"))
(assert-no-entities tx-data))
(let [tx-data (map (fn [m]
(if (map? m)
(dissoc m :block/children :block/meta :block/top? :block/bottom? :block/anchor
Expand Down Expand Up @@ -85,6 +100,10 @@
(def object? entity-util/object?)
(def asset? entity-util/asset?)
(def public-built-in-property? db-property/public-built-in-property?)
(def get-entity-types entity-util/get-entity-types)
(def internal-tags db-class/internal-tags)
(def private-tags db-class/private-tags)
(def hidden-tags db-class/hidden-tags)

(defn sort-by-order
[blocks]
Expand Down Expand Up @@ -176,33 +195,39 @@
(def db-based-graph? entity-util/db-based-graph?)

(defn page-exists?
"Whether a page exists with the `type`."
[db page-name type']
"Returns truthy value if page exists.
For db graphs, returns all page db ids that given title and one of the given `tags`.
For file graphs, returns page entity if it exists"
[db page-name tags]
(when page-name
(if (db-based-graph? db)
;; Classes and properties are case sensitive
(if (#{"class" "property"} type')
(seq
(d/q
'[:find [?p ...]
:in $ ?name ?type
:where
[?p :block/title ?name]
[?p :block/type ?type]]
db
page-name
type'))
;; TODO: Decouple db graphs from file specific :block/name
(seq
(d/q
'[:find [?p ...]
:in $ ?name ?type
:where
[?p :block/name ?name]
[?p :block/type ?type]]
db
(common-util/page-name-sanity-lc page-name)
type')))
(let [tags' (if (coll? tags) (set tags) #{tags})]
;; Classes and properties are case sensitive and can be looked up
;; as such in case-sensitive contexts e.g. no Page
(if (and (seq tags') (every? #{:logseq.class/Tag :logseq.class/Property} tags'))
(seq
(d/q
'[:find [?p ...]
:in $ ?name [?tag-ident ...]
:where
[?p :block/title ?name]
[?p :block/tags ?tag]
[?tag :db/ident ?tag-ident]]
db
page-name
tags'))
;; TODO: Decouple db graphs from file specific :block/name
(seq
(d/q
'[:find [?p ...]
:in $ ?name [?tag-ident ...]
:where
[?p :block/name ?name]
[?p :block/tags ?tag]
[?tag :db/ident ?tag-ident]]
db
(common-util/page-name-sanity-lc page-name)
tags'))))
(d/entity db [:block/name (common-util/page-name-sanity-lc page-name)]))))

(defn get-page
Expand Down Expand Up @@ -448,7 +473,7 @@
(d/datoms db :avet :block/name)
(keep (fn [d]
(let [e (d/entity db (:e d))]
(when-not (hidden? e)
(when-not (or (hidden? e) (internal-tags (:db/ident e)))
e))))))

(defn built-in?
Expand Down Expand Up @@ -535,7 +560,7 @@

(defn get-all-properties
[db]
(->> (d/datoms db :avet :block/type "property")
(->> (d/datoms db :avet :block/tags :logseq.class/Property)
(map (fn [d]
(d/entity db (:e d))))))

Expand All @@ -554,7 +579,7 @@

(defn get-title-with-parents
[entity]
(if (contains? #{"page" "class"} (:block/type entity))
(if (or (entity-util/class? entity) (entity-util/internal-page? entity))
(let [parents' (->> (get-page-parents entity)
(remove (fn [e] (= :logseq.class/Root (:db/ident e))))
vec)]
Expand Down
51 changes: 46 additions & 5 deletions deps/db/src/logseq/db/frontend/class.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,35 @@
"Class related fns for DB graphs and frontend/datascript usage"
(:require [logseq.db.sqlite.util :as sqlite-util]
[logseq.db.frontend.db-ident :as db-ident]
[clojure.set :as set]
[flatland.ordered.map :refer [ordered-map]]))

;; Main class vars
;; ===============

(def ^:large-vars/data-var built-in-classes
"Map of built-in classes for db graphs with their :db/ident as keys"
(ordered-map
:logseq.class/Root {:title "Root Tag"}

:logseq.class/Task
{:title "Task"
:schema {:properties [:logseq.task/status :logseq.task/priority :logseq.task/deadline]}}
:logseq.class/Tag {:title "Tag"}

:logseq.class/Property {:title "Property"}

:logseq.class/Page {:title "Page"}

:logseq.class/Journal
{:title "Journal"
:properties {:logseq.property.journal/title-format "MMM do, yyyy"}}
:properties {:logseq.property/parent :logseq.class/Page
:logseq.property.journal/title-format "MMM do, yyyy"}}

:logseq.class/Whiteboard
{:title "Whiteboard"
:properties {:logseq.property/parent :logseq.class/Page}}

:logseq.class/Task
{:title "Task"
:schema {:properties [:logseq.task/status :logseq.task/priority :logseq.task/deadline]}}

:logseq.class/Query
{:title "Query"
Expand Down Expand Up @@ -66,6 +81,31 @@
;; TODO: Add more classes such as :book, :paper, :movie, :music, :project)
))

(def page-children-classes
"Children of :logseq.class/Page"
(set
(keep (fn [[class-ident m]]
(when (= (get-in m [:properties :logseq.property/parent]) :logseq.class/Page) class-ident))
built-in-classes)))

(def internal-tags
"Built-in classes that are hidden on a node and all pages view"
#{:logseq.class/Page :logseq.class/Property :logseq.class/Tag :logseq.class/Root
:logseq.class/Asset})

(def private-tags
"Built-in classes that are private and should not be used by a user directly.
These used to be in :block/type"
(set/union internal-tags
#{:logseq.class/Journal :logseq.class/Whiteboard}))

(def hidden-tags
"Built-in classes that are hidden in a few contexts like property values"
#{:logseq.class/Page :logseq.class/Root :logseq.class/Asset})

;; Helper fns
;; ==========

(defn create-user-class-ident-from-name
"Creates a class :db/ident for a default user namespace.
NOTE: Only use this when creating a db-ident for a new class."
Expand All @@ -78,5 +118,6 @@
[db page-m]
{:pre [(string? (:block/title page-m))]}
(let [db-ident (create-user-class-ident-from-name (:block/title page-m))
db-ident' (db-ident/ensure-unique-db-ident db db-ident)]
db-ident' (or (:db/ident page-m)
(db-ident/ensure-unique-db-ident db db-ident))]
(sqlite-util/build-new-class (assoc page-m :db/ident db-ident'))))
4 changes: 2 additions & 2 deletions deps/db/src/logseq/db/frontend/entity_plus.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
[^Entity e k default-value]
(let [db (.-db e)
db-based? (db-based-graph? db)]
(if (and db-based? (= "journal" (:block/type e)))
(if (and db-based? (entity-util/journal? e))
(get-journal-title db e)
(let [search? (get (.-kv e) :block.temp/search?)]
(or
Expand Down Expand Up @@ -65,7 +65,7 @@
(let [db (.-db e)]
(case k
:block/raw-title
(if (and (db-based-graph? db) (= "journal" (:block/type e)))
(if (and (db-based-graph? db) (entity-util/journal? e))
(get-journal-title db e)
(lookup-entity e :block/title default-value))

Expand Down
69 changes: 52 additions & 17 deletions deps/db/src/logseq/db/frontend/entity_util.cljs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
(ns logseq.db.frontend.entity-util
"Lower level entity util fns used across db namespaces"
(:require [datascript.core :as d]
[clojure.string :as string])
[clojure.string :as string]
[datascript.impl.entity :as de])
(:refer-clojure :exclude [object?]))

(defn db-based-graph?
Expand All @@ -10,36 +11,60 @@
(when db
(= "db" (:kv/value (d/entity db :logseq.kv/db-type)))))

(defn page?
[block]
(contains? #{"page" "journal" "whiteboard" "class" "property"}
(:block/type block)))
(defn- has-tag?
[entity tag-ident]
(let [tags (:block/tags entity)]
(some (fn [t] (or (= (:db/ident t) tag-ident)
(= t tag-ident)))
(if (coll? tags) tags [tags]))))

(defn internal-page?
[entity]
(= (:block/type entity) "page"))
(has-tag? entity :logseq.class/Page))

(defn class?
[entity]
(= (:block/type entity) "class"))
(or (= (:db/ident entity) :logseq.class/Tag)
(has-tag? entity :logseq.class/Tag)))

(defn property?
[entity]
(= (:block/type entity) "property"))

(defn closed-value?
[entity]
(= (:block/type entity) "closed value"))
(has-tag? entity :logseq.class/Property))

(defn whiteboard?
"Given a page entity or map, check if it is a whiteboard page"
[page]
(= (:block/type page) "whiteboard"))
[entity]
(or
;; db based graph
(has-tag? entity :logseq.class/Whiteboard)
;; file based graph
(= "whiteboard" (:block/type entity))))

(defn closed-value?
[entity]
(some? (:block/closed-value-property entity)))

(defn journal?
"Given a page entity or map, check if it is a journal page"
[page]
(= (:block/type page) "journal"))
[entity]
(or
;; db based graph
(has-tag? entity :logseq.class/Journal)
;; file based graph
(= "journal" (:block/type entity))))

(defn page?
[entity]
(or
;; db based graph
(internal-page? entity)
(class? entity)
(property? entity)
(whiteboard? entity)
(journal? entity)

;; file based graph
(contains? #{"page" "journal" "whiteboard"} (:block/type entity))))

(defn asset?
"Given an entity or map, check if it is an asset block"
Expand All @@ -52,9 +77,19 @@
(when page
(if (string? page)
(string/starts-with? page "$$$")
(when (map? page)
(when (or (map? page) (de/entity? page))
(false? (get-in page [:block/schema :public?]))))))

(defn object?
[node]
(seq (:block/tags node)))

(defn get-entity-types
"Get entity types from :block/tags"
[entity]
(let [ident->type {:logseq.class/Tag :class
:logseq.class/Property :property
:logseq.class/Journal :journal
:logseq.class/Whiteboard :whiteboard
:logseq.class/Page :page}]
(set (map #(ident->type (:db/ident %)) (:block/tags entity)))))
Loading

0 comments on commit fbefade

Please sign in to comment.