Browse Source

wip: use :block/tags to represent block types

Tienson Qin 11 months ago
parent
commit
9e10dc1737

+ 24 - 23
deps/db/src/logseq/db.cljs

@@ -176,33 +176,34 @@
 (def db-based-graph? entity-util/db-based-graph?)
 
 (defn page-exists?
-  "Whether a page exists with the `type`."
-  [db page-name type']
+  "Whether a page exists with the `tags`."
+  [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'))
+      (let [tags (if (coll? tags) (set tags) #{tags})]
+        (if (set/intersection #{:logseq.class/Class :logseq.class/Property} tags)
+          (seq
+           (d/q
+            '[:find [?p ...]
+              :in $ ?name [?tag ...]
+              :where
+              [?p :block/title ?name]
+              [?p :block/tags ?tag]]
+            db
+            page-name
+            tags))
         ;; 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')))
+          (seq
+           (d/q
+            '[:find [?p ...]
+              :in $ ?name [?tag ...]
+              :where
+              [?p :block/name ?name]
+              [?p :block/tags ?tag]]
+            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

+ 6 - 0
deps/db/src/logseq/db/frontend/class.cljs

@@ -9,6 +9,12 @@
   (ordered-map
    :logseq.class/Root {:title "Root Tag"}
 
+   :logseq.class/Page {:title "Page"}
+   :logseq.class/Whiteboard {:title "Whiteboard"}
+   :logseq.class/Class {:title "Tag"}
+   :logseq.class/Property {:title "Property"}
+   :logseq.class/Closed-Value {:title "Closed Value"}
+
    :logseq.class/Task
    {:title "Task"
     :schema {:properties [:logseq.task/status :logseq.task/priority :logseq.task/deadline]}}

+ 23 - 15
deps/db/src/logseq/db/frontend/entity_util.cljs

@@ -10,36 +10,44 @@
   (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]
+  (some (fn [t] (or (= (:db/ident t) tag-ident)
+                    (= t tag-ident))) (:block/tags entity)))
 
 (defn internal-page?
   [entity]
-  (= (:block/type entity) "page"))
+  (has-tag? entity :logseq.class/Page))
 
 (defn class?
   [entity]
-  (= (:block/type entity) "class"))
+  (has-tag? entity :logseq.class/Class))
 
 (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]
+  (has-tag? entity :logseq.class/Whiteboard))
+
+(defn closed-value?
+  [entity]
+  (has-tag? entity :logseq.class/Closed-Value))
 
 (defn journal?
   "Given a page entity or map, check if it is a journal page"
-  [page]
-  (= (:block/type page) "journal"))
+  [entity]
+  (has-tag? entity :logseq.class/Journal))
+
+(defn page?
+  [entity]
+  (or (internal-page? entity)
+      (class? entity)
+      (property? entity)
+      (whiteboard? entity)
+      (journal? entity)))
 
 (defn asset?
   "Given an entity or map, check if it is an asset block"

+ 1 - 3
deps/db/src/logseq/db/frontend/malli_schema.cljs

@@ -188,7 +188,6 @@
 ;; ==================
 ;; These schemas should be data vars to remain as simple and reusable as possible
 
-
 (def ^:dynamic *db-for-validate-fns*
   "Used by validate-fns which need db as input"
   nil)
@@ -228,7 +227,6 @@
   "Common attributes for pages"
   [[:block/name :string]
    [:block/title :string]
-   [:block/type [:enum "page" "class" "property" "whiteboard" "journal"]]
    [:block/alias {:optional true} [:set :int]]
     ;; TODO: Should this be here or in common?
    [:block/path-refs {:optional true} [:set :int]]
@@ -364,7 +362,7 @@
   (vec
    (concat
     [:map]
-    [[:block/type [:= "closed value"]]
+    [;; [:block/tags [:= :logseq.class/Closed-Value]]
      ;; for built-in properties
      [:db/ident {:optional true} logseq-property-ident]
      [:block/title {:optional true} :string]

+ 4 - 4
deps/db/src/logseq/db/frontend/order.cljs

@@ -10,8 +10,8 @@
    (reset-max-key! *max-key key))
   ([max-key-atom key]
    (when (and key (or (nil? @max-key-atom)
-                     (> (compare key @max-key-atom) 0)))
-    (reset! max-key-atom key))))
+                      (> (compare key @max-key-atom) 0)))
+     (reset! max-key-atom key))))
 
 (defn gen-key
   ([]
@@ -50,7 +50,7 @@
                 (when (and (< (compare (:block/order e) (:block/order value)) 0)
                            (not= (:db/id e) (:db/id value)))
                   (:block/order e))) values))
-      (let [properties (->> (d/datoms db :avet :block/type "property")
+      (let [properties (->> (d/datoms db :avet :block/tags :logseq.class/Property)
                             (map (fn [d] (d/entity db (:e d))))
                             (sort-by :block/order)
                             reverse)]
@@ -68,7 +68,7 @@
                 (when (and (> (compare (:block/order e) (:block/order value)) 0)
                            (not= (:db/id e) (:db/id value)))
                   (:block/order e))) values))
-      (let [properties (->> (d/datoms db :avet :block/type "property")
+      (let [properties (->> (d/datoms db :avet :block/tags :logseq.class/Property)
                             (map (fn [d] (d/entity db (:e d))))
                             (sort-by :block/order))]
         (some (fn [property]

+ 1 - 7
deps/db/src/logseq/db/frontend/property.cljs

@@ -48,12 +48,6 @@
                                         :schema {:type :any
                                                  :public? false
                                                  :hide? true}}
-   :block/type           {:title "Node Type"
-                          :attribute :block/type
-                          :schema {:type :string
-                                   :public? false
-                                   :hide? true}
-                          :queryable? true}
    :block/schema         {:title "Node schema"
                           :attribute :block/schema
                           :schema {:type :map
@@ -436,7 +430,7 @@
 
 (def db-attribute-properties
   "Internal properties that are also db schema attributes"
-  #{:block/alias :block/tags :block/type :block/schema :block/parent
+  #{:block/alias :block/tags :block/schema :block/parent
     :block/order :block/collapsed? :block/page
     :block/refs :block/path-refs :block/link
     :block/title :block/closed-value-property

+ 1 - 1
deps/db/src/logseq/db/frontend/property/build.cljs

@@ -8,7 +8,7 @@
 (defn- closed-value-new-block
   [block-id block-type value property]
   (let [property-id (:db/ident property)]
-    (merge {:block/type "closed value"
+    (merge {:block/tags [:logseq.class/Closed-Value]
             :block/format :markdown
             :block/uuid block-id
             :block/page property-id

+ 1 - 1
deps/db/src/logseq/db/frontend/property/type.cljs

@@ -138,7 +138,7 @@
   [db val]
   (when-let [ent (d/entity db val)]
     (and (some? (:block/title ent))
-         (= (:block/type ent) "journal"))))
+         (entity-util/journal? ent))))
 
 (def built-in-validation-schemas
   "Map of types to malli validation schemas that validate a property value for that type"

+ 11 - 5
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -347,10 +347,11 @@
                   {:block/created-at current-ms
                    :block/updated-at current-ms}))
               (if journal-day
-                (cond-> {:block/type "journal"
-                         :block/journal-day journal-day}
+                (cond-> {:block/journal-day journal-day}
                   db-based?
-                  (assoc :block/tags [:logseq.class/Journal]))
+                  (assoc :block/tags [:logseq.class/Journal])
+                  (not db-based?)
+                  (assoc :block/type "journal"))
                 {}))]
     [page page-entity]))
 
@@ -388,8 +389,13 @@
                                                  nil)]
                                   [page nil]))]
       (when page
-        (let [type (if class? "class" (or (:block/type page) "page"))]
-          (assoc page :block/type type))))))
+        (if (ldb/db-based-graph? db)
+          (let [tags (if class? [:logseq.class/Class]
+                         (or (:block/tags page)
+                             [:logseq.class/Page]))]
+            (assoc page :block/tags tags))
+          (let [type (if class? "class" (or (:block/type page) "page"))]
+            (assoc page :block/type type)))))))
 
 (defn- db-namespace-page?
   "Namespace page that're not journal pages"

+ 0 - 7
src/main/frontend/components/all_pages.cljs

@@ -21,13 +21,6 @@
          :cell (fn [_table row _column]
                  (component-block/page-cp {} row))
          :type :string}
-        {:id :block/type
-         :name "Type"
-         :cell (fn [_table row _column]
-                 (let [type (get row :block/type)]
-                   [:div.capitalize (if (= type "class") "tag" type)]))
-         :get-value (fn [row] (get row :block/type))
-         :type :string}
         {:id :block.temp/refs-count
          :name (t :page/backlinks)
          :cell (fn [_table row _column] (:block.temp/refs-count row))

+ 1 - 1
src/main/frontend/components/editor.cljs

@@ -156,7 +156,7 @@
                            ;; reorder, shortest and starts-with first.
                            (let [matched-pages-with-new-page
                                  (fn [partial-matched-pages]
-                                   (if (or (db/page-exists? q (if db-tag? "class" "page"))
+                                   (if (or (db/page-exists? q (if db-tag? #{:logseq.class/Class} #{:logseq.class/Page}))
                                            (and db-tag? (some ldb/class? (:block/_alias (db/get-page q)))))
                                      partial-matched-pages
                                      (if db-tag?

+ 3 - 2
src/main/frontend/components/page.cljs

@@ -301,10 +301,11 @@
 (rum/defc page-title-editor < rum/reactive
   [page {:keys [*input-value *title-value *edit? untitled? page-name old-name whiteboard-page?]}]
   (let [input-ref (rum/create-ref)
+        tag-idents (map :db/ident (:block/tags page))
         collide? #(and (not= (util/page-name-sanity-lc page-name)
                              (util/page-name-sanity-lc @*title-value))
-                       (db/page-exists? page-name (:block/type page))
-                       (db/page-exists? @*title-value (:block/type page)))
+                       (db/page-exists? page-name tag-idents)
+                       (db/page-exists? @*title-value tag-idents))
         rollback-fn #(let [old-name (if untitled? "" old-name)]
                        (reset! *title-value old-name)
                        (gobj/set (rum/deref input-ref) "value" old-name)

+ 1 - 1
src/main/frontend/db/async.cljs

@@ -55,7 +55,7 @@
   [graph & {:keys [remove-built-in-property? remove-non-queryable-built-in-property?]
             :or {remove-built-in-property? true
                  remove-non-queryable-built-in-property? false}}]
-  (let [result (->> (d/datoms (db/get-db graph) :avet :block/type "property")
+  (let [result (->> (d/datoms (db/get-db graph) :avet :block/tags :logseq.class/Property)
                     (map (fn [datom] (db/entity (:e datom))))
                     (sort-by (juxt ldb/built-in? :block/title)))]
     (cond->> result

+ 67 - 34
src/main/frontend/db/model.cljs

@@ -383,10 +383,10 @@ independent of format as format specific heading characters are stripped"
 
 (defn page-exists?
   "Whether a page exists."
-  [page-name type]
+  [page-name tags]
   (let [repo (state/get-current-repo)]
     (when-let [db (conn/get-db repo)]
-      (ldb/page-exists? db page-name type))))
+      (ldb/page-exists? db page-name tags))))
 
 (defn page-empty?
   "Whether a page is empty. Does it has a non-page block?
@@ -531,14 +531,23 @@ independent of format as format specific heading characters are stripped"
 (defn get-journals-length
   []
   (let [today (date-time-util/date->int (js/Date.))]
-    (d/q '[:find (count ?page) .
-           :in $ ?today
-           :where
-           [?page :block/type "journal"]
-           [?page :block/journal-day ?journal-day]
-           [(<= ?journal-day ?today)]]
-         (conn/get-db (state/get-current-repo))
-         today)))
+    (if (config/db-based-graph?)
+      (d/q '[:find (count ?page) .
+             :in $ ?today
+             :where
+             [?page :block/tags :logseq.class/Journal]
+             [?page :block/journal-day ?journal-day]
+             [(<= ?journal-day ?today)]]
+           (conn/get-db (state/get-current-repo))
+           today)
+      (d/q '[:find (count ?page) .
+             :in $ ?today
+             :where
+             [?page :block/type "journal"]
+             [?page :block/journal-day ?journal-day]
+             [(<= ?journal-day ?today)]]
+           (conn/get-db (state/get-current-repo))
+           today))))
 
 (defn get-latest-journals
   ([n]
@@ -749,17 +758,29 @@ independent of format as format specific heading characters are stripped"
 
 (defn get-all-whiteboards
   [repo]
-  (d/q
-   '[:find [(pull ?page [:db/id
-                         :block/uuid
-                         :block/name
-                         :block/title
-                         :block/created-at
-                         :block/updated-at]) ...]
-     :where
-     [?page :block/name]
-     [?page :block/type "whiteboard"]]
-   (conn/get-db repo)))
+  (if (config/db-based-graph?)
+    (d/q
+     '[:find [(pull ?page [:db/id
+                           :block/uuid
+                           :block/name
+                           :block/title
+                           :block/created-at
+                           :block/updated-at]) ...]
+       :where
+       [?page :block/name]
+       [?page :block/tags :logseq.class/Whiteboard]]
+     (conn/get-db repo))
+    (d/q
+     '[:find [(pull ?page [:db/id
+                           :block/uuid
+                           :block/name
+                           :block/title
+                           :block/created-at
+                           :block/updated-at]) ...]
+       :where
+       [?page :block/name]
+       [?page :block/type "whiteboard"]]
+     (conn/get-db repo))))
 
 (defn get-whiteboard-id-nonces
   [repo page-id]
@@ -780,7 +801,7 @@ independent of format as format specific heading characters are stripped"
   [repo & {:keys [except-root-class?]
            :or {except-root-class? false}}]
   (let [db (conn/get-db repo)
-        classes (->> (d/datoms db :avet :block/type "class")
+        classes (->> (d/datoms db :avet :block/tags :logseq.class/Class)
                      (map (fn [d]
                             (db-utils/entity db (:e d)))))]
     (if except-root-class?
@@ -849,18 +870,30 @@ independent of format as format specific heading characters are stripped"
 (defn get-pages-relation
   [repo with-journal?]
   (when-let [db (conn/get-db repo)]
-    (let [q (if with-journal?
-              '[:find ?p ?ref-page
-                :where
-                [?block :block/page ?p]
-                [?block :block/refs ?ref-page]]
-              '[:find ?p ?ref-page
-                :where
-                [?block :block/page ?p]
-                [(get-else $ ?p :block/type "N/A") ?type]
-                [(not= ?type "journal")]
-                [?block :block/refs ?ref-page]])]
-      (d/q q db))))
+    (if (config/db-based-graph?)
+      (let [q (if with-journal?
+                '[:find ?p ?ref-page
+                  :where
+                  [?block :block/page ?p]
+                  [?block :block/refs ?ref-page]]
+                '[:find ?p ?ref-page
+                  :where
+                  [?block :block/page ?p]
+                  [?p :block/tags]
+                  (not [?p :block/tags :logseq.class/Journal])
+                  [?block :block/refs ?ref-page]])]
+        (d/q q db))
+      (let [q (if with-journal?
+                '[:find ?p ?ref-page
+                  :where
+                  [?block :block/page ?p]
+                  [?block :block/refs ?ref-page]]
+                '[:find ?p ?ref-page
+                  :where
+                  [?block :block/page ?p]
+                  (not [?p :block/type "journal"])
+                  [?block :block/refs ?ref-page]])]
+        (d/q q db)))))
 
 (defn get-namespace-pages
   "Accepts both sanitized and unsanitized namespaces"

+ 1 - 1
src/main/frontend/db/query_dsl.cljs

@@ -323,7 +323,7 @@
     (or (some->> (name property-name)
                  (db-utils/q '[:find [(pull ?b [:db/ident]) ...]
                                :in $ ?title
-                               :where [?b :block/type "property"] [?b :block/title ?title]])
+                               :where [?b :block/tags :logseq.class/Property] [?b :block/title ?title]])
                  first
                  :db/ident)
         ;; Don't return nil as that incorrectly matches all properties

+ 1 - 1
src/main/frontend/handler/journal.cljs

@@ -15,7 +15,7 @@
   (when (and page (state/enable-journals? (state/get-current-repo)))
     (p/do!
      (db-async/<get-block (state/get-current-repo) page :children? false)
-     (if (db-model/page-exists? page "journal")
+     (if (db-model/page-exists? page #{:logseq.class/Journal})
        (route-handler/redirect! {:to          :page
                                  :path-params {:name page}})
        (page-handler/<create! page)))))

+ 1 - 1
src/main/frontend/worker/db_worker.cljs

@@ -318,7 +318,7 @@
 
         (when-not db-based?
           (try
-            (when-not (ldb/page-exists? @conn common-config/views-page-name "page")
+            (when-not (ldb/page-exists? @conn common-config/views-page-name #{:logseq.class/property})
               (ldb/transact! conn (sqlite-create-graph/build-initial-views)))
             (catch :default _e)))
 

+ 2 - 2
src/main/frontend/worker/handler/page.cljs

@@ -30,8 +30,8 @@
 
    * :create-first-block?      - when true, create an empty block if the page is empty.
    * :uuid                     - when set, use this uuid instead of generating a new one.
-   * :class?                   - when true, adds a :block/type 'class'
-   * :whiteboard?              - when true, adds a :block/type 'whiteboard'
+   * :class?                   - when true, adds a :block/tags ':logseq.class/Class'
+   * :whiteboard?              - when true, adds a :block/tags ':logseq.class/Whiteboard'
    * :tags                     - tag uuids that are added to :block/tags
    * :persist-op?              - when true, add an update-page op
    * :properties               - properties to add to the page

+ 31 - 30
src/main/frontend/worker/handler/page/db_based/page.cljs

@@ -13,30 +13,29 @@
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.text :as text]
-            [logseq.outliner.validate :as outliner-validate]))
+            [logseq.outliner.validate :as outliner-validate]
+            [logseq.db.frontend.entity-util :as entity-util]))
 
 (defn- build-page-tx [conn properties page {:keys [whiteboard? class? tags]}]
   (when (:block/uuid page)
-    (let [page (assoc page :block/type (cond class? "class"
-                                             whiteboard? "whiteboard"
-                                             (:block/type page) (:block/type page)
-                                             :else "page"))
-          page' (cond-> page
-                  (seq tags)
-                  (update :block/tags
-                          (fnil into [])
-                          (mapv (fn [tag]
-                                  (let [v (if (uuid? tag)
-                                            (d/entity @conn [:block/uuid tag])
-                                            tag)]
-                                    (cond
-                                      (de/entity? v)
-                                      (:db/id v)
-                                      (map? v)
-                                      (:db/id v)
-                                      :else
-                                      v)))
-                                tags)))
+    (let [type-tag (cond class? :logseq.class/Class
+                         whiteboard? :logseq.class/Whiteboard
+                         :else :logseq.class/Page)
+          tags' (conj tags type-tag)
+          page' (update page :block/tags
+                        (fnil into [])
+                        (mapv (fn [tag]
+                                (let [v (if (uuid? tag)
+                                          (d/entity @conn [:block/uuid tag])
+                                          tag)]
+                                  (cond
+                                    (de/entity? v)
+                                    (:db/id v)
+                                    (map? v)
+                                    (:db/id v)
+                                    :else
+                                    v)))
+                              tags'))
           property-vals-tx-m
           ;; Builds property values for built-in properties like logseq.property.pdf/file
           (db-property-build/build-property-values-tx-m
@@ -95,10 +94,12 @@
 
 (defn- split-namespace-pages
   [db page date-formatter]
-  (let [{:block/keys [title] block-uuid :block/uuid block-type :block/type} page]
+  (let [{:block/keys [title] block-uuid :block/uuid} page]
     (->>
-     (if (and (contains? #{"page" "class"} block-type) (ns-util/namespace-page? title))
-       (let [class? (= block-type "class")
+     (if (and (or (entity-util/class? page)
+                  (entity-util/page? page))
+              (ns-util/namespace-page? title))
+       (let [class? (entity-util/class? page)
              parts (->> (string/split title ns-util/parent-re)
                         (map string/trim)
                         (remove string/blank?))
@@ -169,14 +170,14 @@
         date-formatter (:logseq.property.journal/title-format (d/entity db :logseq.class/Journal))
         title (sanitize-title title*)
         type (cond class?
-                   "class"
+                   :logseq.class/Class
                    whiteboard?
-                   "whiteboard"
+                   :logseq.class/Whiteboard
                    today-journal?
-                   "journal"
+                   :logseq.class/Journal
                    :else
-                   "page")]
-    (when-not (ldb/page-exists? db title type)
+                   :logseq.class/Page)]
+    (when-not (ldb/page-exists? db title #{type})
       (let [format    :markdown
             page      (-> (gp-block/page-name->map title @conn true date-formatter
                                                    {:class? class?
@@ -191,7 +192,7 @@
                              [page nil])]
         (when page
           ;; Don't validate journal names because they can have '/'
-          (when (not= "journal" type)
+          (when (not= :logseq.class/Journal type)
             (outliner-validate/validate-page-title-characters (str (:block/title page)) {:node page})
             (doseq [parent parents]
               (outliner-validate/validate-page-title-characters (str (:block/title parent)) {:node parent})))

+ 1 - 1
src/main/frontend/worker/rtc/db_listener.cljs

@@ -22,7 +22,7 @@
 
 (def ^:private watched-attrs
   #{:block/title :block/created-at :block/updated-at :block/alias
-    :block/tags :block/type :block/schema :block/link :block/journal-day
+    :block/tags :block/schema :block/link :block/journal-day
     :property/schema.classes :property.value/content
     :db/index :db/valueType :db/cardinality})
 

+ 0 - 1
src/main/frontend/worker/rtc/remote_update.cljs

@@ -353,7 +353,6 @@
     :block/updated-at
     :block/created-at
     :block/alias
-    :block/type
     :block/schema
     :block/tags
     :block/link

+ 0 - 7
src/main/frontend/worker/search.cljs

@@ -332,13 +332,6 @@ DROP TRIGGER IF EXISTS blocks_au;
   (drop-tables-and-triggers! db)
   (create-tables-and-triggers! db))
 
-(comment
-  (defn- property-value-when-closed
-    "Returns property value if the given entity is type 'closed value' or nil"
-    [ent]
-    (when (= (:block/type ent) "closed value")
-      (:block/title ent))))
-
 (comment
   (defn- get-db-properties-str
     "Similar to db-pu/readable-properties but with a focus on making property values searchable"