From 64786bb2589cf13192d24b9aeeaf0d5d0ba158b7 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Fri, 10 May 2024 15:19:10 -0400 Subject: [PATCH] fix: create :number and :url properties from scripts --- .../src/logseq/db/frontend/malli_schema.cljs | 3 +- .../logseq/db/frontend/property/build.cljs | 15 +++- .../src/logseq/db/frontend/property/type.cljs | 6 +- .../logseq/tasks/db_graph/create_graph.cljs | 68 ++++++++++++++----- .../create_graph_with_properties.cljs | 52 +++++++------- .../frontend/handler/db_based/property.cljs | 14 +--- 6 files changed, 100 insertions(+), 58 deletions(-) diff --git a/deps/db/src/logseq/db/frontend/malli_schema.cljs b/deps/db/src/logseq/db/frontend/malli_schema.cljs index ba8db0cc77..89367f5334 100644 --- a/deps/db/src/logseq/db/frontend/malli_schema.cljs +++ b/deps/db/src/logseq/db/frontend/malli_schema.cljs @@ -288,7 +288,8 @@ property-common-schema-attrs (remove #(not (db-property-type/property-type-allows-schema-attribute? prop-type (first %))) property-type-schema-attrs)))]) - db-property-type/user-built-in-property-types))) + ;; TODO: Remove :string once it is user facing or unused + (conj db-property-type/user-built-in-property-types :string)))) (def user-property (vec diff --git a/deps/db/src/logseq/db/frontend/property/build.cljs b/deps/db/src/logseq/db/frontend/property/build.cljs index 4f23a572c7..8df04a8f92 100644 --- a/deps/db/src/logseq/db/frontend/property/build.cljs +++ b/deps/db/src/logseq/db/frontend/property/build.cljs @@ -2,7 +2,8 @@ "Builds core property concepts" (:require [logseq.db.sqlite.util :as sqlite-util] [logseq.db.frontend.property.type :as db-property-type] - [logseq.db.frontend.order :as db-order])) + [logseq.db.frontend.order :as db-order] + [datascript.core :as d])) (defonce hidden-page-name-prefix "$$$") @@ -66,3 +67,15 @@ (:closed-values property))] closed-value-blocks-tx))] (into [property-tx] hidden-tx))) + +(defn property-create-new-block + [block property value parse-block] + (-> {:block/uuid (d/squuid) + :block/format :markdown + :block/content value + :block/page (:db/id (:block/page block)) + :block/parent (:db/id block) + :logseq.property/created-from-property (or (:db/id property) + {:db/ident (:db/ident property)})} + sqlite-util/block-with-timestamps + parse-block)) diff --git a/deps/db/src/logseq/db/frontend/property/type.cljs b/deps/db/src/logseq/db/frontend/property/type.cljs index dbbe2e1fb7..207166c9f0 100644 --- a/deps/db/src/logseq/db/frontend/property/type.cljs +++ b/deps/db/src/logseq/db/frontend/property/type.cljs @@ -24,9 +24,13 @@ (assert (set/subset? closed-value-property-types (set (conj user-built-in-property-types :string))) "All closed value types are valid property types") +(def value-ref-property-types + "Property value ref types" + #{:default :url :number}) + (def ref-property-types "User facing ref types" - #{:default :page :date :number :url}) + (into #{:page :date} value-ref-property-types)) (assert (set/subset? ref-property-types (set user-built-in-property-types)) diff --git a/scripts/src/logseq/tasks/db_graph/create_graph.cljs b/scripts/src/logseq/tasks/db_graph/create_graph.cljs index b32107bde8..8e90fc9cea 100644 --- a/scripts/src/logseq/tasks/db_graph/create_graph.cljs +++ b/scripts/src/logseq/tasks/db_graph/create_graph.cljs @@ -16,7 +16,8 @@ ["path" :as node-path] [nbb.classpath :as cp] [logseq.db.frontend.property :as db-property] - [logseq.db.frontend.order :as db-order])) + [logseq.db.frontend.order :as db-order] + [logseq.db.frontend.property.type :as db-property-type])) (defn- find-on-classpath [rel-path] (some (fn [dir] @@ -111,17 +112,52 @@ "Provides the next temp :db/id to use in a create-graph transact!" #(swap! current-db-id dec)) -(defn- ->block-tx [m uuid-maps all-idents page-id] - (merge (dissoc m :properties) - (sqlite-util/block-with-timestamps - {:db/id (new-db-id) - :block/format :markdown - :block/page {:db/id page-id} - :block/order (db-order/gen-key nil) - :block/parent {:db/id page-id}}) - (when (seq (:properties m)) - (merge (->block-properties (:properties m) uuid-maps all-idents) - {:block/refs (build-property-refs (:properties m) all-idents)})))) +(defn- create-property-value + [block property value] + (db-property-build/property-create-new-block + block + property + ;; FIXME: Remove when fixed in UI + (str value) + ;; TODO: One day would be nice to parse block for refs + #(assoc % :block/order (db-order/gen-key nil)))) + +(defn- create-pvalue-entities + "Given a new block and its properties, creates a map of properties which have property values as entities" + [new-block properties properties-config all-idents] + (->> properties + (map (fn [[k v]] + (when (db-property-type/value-ref-property-types (get-in properties-config [k :block/schema :type])) + [k (if (set? v) + (set (map #(create-property-value new-block {:db/ident (get-ident all-idents k)} %) v)) + (create-property-value new-block {:db/ident (get-ident all-idents k)} v))]))) + (into {}))) + +(defn- ->block-tx [{:keys [properties] :as m} properties-config uuid-maps all-idents page-id] + (let [new-block {:db/id (new-db-id) + :block/format :markdown + :block/page {:db/id page-id} + :block/order (db-order/gen-key nil) + :block/parent {:db/id page-id}} + pvalue-ents (create-pvalue-entities new-block properties properties-config all-idents) + block-props (when (seq properties) + (->block-properties (merge properties + (update-vals pvalue-ents + (fn [v] + (if (set? v) + (set (map #(vector :block/uuid (:block/uuid %)) v)) + (vector :block/uuid (:block/uuid v)))))) + uuid-maps all-idents))] + (cond-> [] + ;; Place property values first since they are referenced by block + (seq pvalue-ents) + (into (mapcat #(if (set? %) % [%]) (vals pvalue-ents))) + true + (conj (merge (dissoc m :properties) + (sqlite-util/block-with-timestamps new-block) + (when (seq properties) + (merge block-props + {:block/refs (build-property-refs properties all-idents)}))))))) (defn- build-properties-tx [properties uuid-maps all-idents] (let [property-db-ids (->> (keys properties) @@ -207,8 +243,8 @@ (map :page pages-and-blocks))] (assert (empty? invalid-pages) (str "The following pages did not have a name attribute: " invalid-pages)) - (assert (every? :block/schema (vals properties)) - "All properties must have :block/schema") + (assert (every? #(get-in % [:block/schema :type]) (vals properties)) + "All properties must have :block/schema and :type") (assert (empty? undeclared-properties) (str "The following properties used in EDN were not declared in :properties: " undeclared-properties)))) @@ -323,8 +359,8 @@ :block/path-refs (build-property-refs (:properties page) all-idents)})))] ;; blocks tx (reduce (fn [acc m] - (conj acc - (->block-tx m uuid-maps all-idents (page-id-fn new-page)))) + (into acc + (->block-tx m properties uuid-maps all-idents (page-id-fn new-page)))) [] blocks)))) pages-and-blocks'))] diff --git a/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs b/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs index 2d55735c13..4814ffb555 100644 --- a/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs +++ b/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs @@ -97,20 +97,20 @@ {:block/content "string-closed property block" :properties {:string-closed (random-closed-value :string-closed)}} {:block/content "url property block" :properties {:url "https://logseq.com"}} {:block/content "url-many property block" :properties {:url-many #{"https://logseq.com" "https://docs.logseq.com"}}} - {:block/content "url-closed property block" :properties {:url-closed (random-closed-value :url-closed)}} + ;; {:block/content "url-closed property block" :properties {:url-closed (random-closed-value :url-closed)}} {:block/content "checkbox property block" :properties {:checkbox true}} {:block/content "number property block" :properties {:number 5}} {:block/content "number-many property block" :properties {:number-many #{5 10}}} - {:block/content "number-closed property block" :properties {:number-closed (random-closed-value :number-closed)}} - {:block/content "page property block" :properties {:page [:page "page 1"]}} - {:block/content "page-many property block" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}} - ;; :page-closed and :date-closed disabled for now since they're not supported - #_{:block/content "page-closed property block" :properties {:page-closed (random-closed-value :page-closed)}} - {:block/content "date property block" :properties {:date [:page (date-journal-title today)]}} - {:block/content "date-many property block" :properties {:date-many #{[:page (date-journal-title today)] + ;; {:block/content "number-closed property block" :properties {:number-closed (random-closed-value :number-closed)}} + ;; {:block/content "page property block" :properties {:page [:page "page 1"]}} + ;; {:block/content "page-many property block" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}} + ;; ;; :page-closed and :date-closed disabled for now since they're not supported + ;; #_{:block/content "page-closed property block" :properties {:page-closed (random-closed-value :page-closed)}} + ;; {:block/content "date property block" :properties {:date [:page (date-journal-title today)]}} + #_{:block/content "date-many property block" :properties {:date-many #{[:page (date-journal-title today)] [:page (date-journal-title yesterday)]}}} #_{:block/content "date-closed property block" :properties {:date-closed (random-closed-value :date-closed)}}]} - {:page {:block/original-name "Block Property Queries"} + #_{:page {:block/original-name "Block Property Queries"} :blocks [{:block/content "{{query (property :string \"haha\")}}"} {:block/content "{{query (property :string-many \"haw\")}}"} @@ -131,24 +131,24 @@ ;; Page property pages and queries ;; {:page {:block/name "default page" :properties {:default "yolo block"}}} - {:page {:block/name "string page" :properties {:string "yolo"}}} - {:page {:block/name "string-many page" :properties {:string-many #{"yee" "haw" "sir"}}}} - {:page {:block/name "string-closed page" :properties {:string-closed (random-closed-value :string-closed)}}} - {:page {:block/name "url page" :properties {:url "https://logseq.com"}}} - {:page {:block/name "url-many page" :properties {:url-many #{"https://logseq.com" "https://docs.logseq.com"}}}} - {:page {:block/name "url-closed page" :properties {:url-closed (random-closed-value :url-closed)}}} - {:page {:block/name "checkbox page" :properties {:checkbox true}}} - {:page {:block/name "number page" :properties {:number 5}}} - {:page {:block/name "number-many page" :properties {:number-many #{5 10}}}} - {:page {:block/name "number-closed page" :properties {:number-closed (random-closed-value :number-closed)}}} - {:page {:block/name "page page" :properties {:page [:page "page 1"]}}} - {:page {:block/name "page-many page" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}}} - #_{:page {:block/name "page-closed page" :properties {:page-closed (random-closed-value :page-closed)}}} - {:page {:block/name "date page" :properties {:date [:page (date-journal-title today)]}}} - {:page {:block/name "date-many page" :properties {:date-many #{[:page (date-journal-title today)] + ;; {:page {:block/name "string page" :properties {:string "yolo"}}} + ;; {:page {:block/name "string-many page" :properties {:string-many #{"yee" "haw" "sir"}}}} + ;; {:page {:block/name "string-closed page" :properties {:string-closed (random-closed-value :string-closed)}}} + ;; {:page {:block/name "url page" :properties {:url "https://logseq.com"}}} + ;; {:page {:block/name "url-many page" :properties {:url-many #{"https://logseq.com" "https://docs.logseq.com"}}}} + ;; {:page {:block/name "url-closed page" :properties {:url-closed (random-closed-value :url-closed)}}} + ;; {:page {:block/name "checkbox page" :properties {:checkbox true}}} + ;; {:page {:block/name "number page" :properties {:number 5}}} + ;; {:page {:block/name "number-many page" :properties {:number-many #{5 10}}}} + ;; {:page {:block/name "number-closed page" :properties {:number-closed (random-closed-value :number-closed)}}} + ;; {:page {:block/name "page page" :properties {:page [:page "page 1"]}}} + ;; {:page {:block/name "page-many page" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}}} + ;; #_{:page {:block/name "page-closed page" :properties {:page-closed (random-closed-value :page-closed)}}} + ;; {:page {:block/name "date page" :properties {:date [:page (date-journal-title today)]}}} + #_{:page {:block/name "date-many page" :properties {:date-many #{[:page (date-journal-title today)] [:page (date-journal-title yesterday)]}}}} #_{:page {:block/name "date-closed page" :properties {:date-closed (random-closed-value :date-closed)}}} - {:page {:block/original-name "Page Property Queries"} + #_{:page {:block/original-name "Page Property Queries"} :blocks [{:block/content "{{query (page-property :string \"yolo\")}}"} {:block/content "{{query (page-property :string-many \"haw\")}}"} @@ -176,7 +176,7 @@ (into (mapv #(vector (keyword (str (name %) "-closed")) {:closed-values (closed-values-config (keyword (str (name %) "-closed"))) :block/schema {:type %}}) - [:string :url :number #_:page #_:date])) + [:string :url :number :page :date])) (into {}))})) (def spec diff --git a/src/main/frontend/handler/db_based/property.cljs b/src/main/frontend/handler/db_based/property.cljs index 73fd21b148..fd2083f65e 100644 --- a/src/main/frontend/handler/db_based/property.cljs +++ b/src/main/frontend/handler/db_based/property.cljs @@ -20,7 +20,6 @@ [logseq.db.frontend.property :as db-property] [frontend.handler.property.util :as pu] [promesa.core :as p] - [frontend.db.async :as db-async] [logseq.db :as ldb] [logseq.db.frontend.malli-schema :as db-malli-schema] [logseq.db.frontend.order :as db-order])) @@ -429,22 +428,11 @@ (and (seq properties) (not= properties [:logseq.property/icon]))))) -(defn property-create-new-block - [block property value parse-block] - (-> {:block/uuid (db/new-block-id) - :block/format :markdown - :block/content value - :block/page (:db/id (:block/page block)) - :block/parent (:db/id block) - :logseq.property/created-from-property (:db/id property)} - sqlite-util/block-with-timestamps - parse-block)) - (defn create-property-text-block! [block property value parse-block {:keys [class-schema?]}] (assert (e/entity? property)) (let [repo (state/get-current-repo) - new-value-block (property-create-new-block block property value parse-block) + new-value-block (db-property-build/property-create-new-block block property value parse-block) class? (contains? (:block/type block) "class") property-id (:db/ident property)] (p/let [_ (db/transact! repo [new-value-block] {:outliner-op :insert-blocks})]