Browse Source

enhance: export+import refs in property values

Gabriel Horner 8 tháng trước cách đây
mục cha
commit
cdf6183852

+ 23 - 10
deps/db/src/logseq/db/sqlite/export.cljs

@@ -49,7 +49,10 @@
         (if (= :node (:logseq.property/type property-ent))
           ;; Have to distinguish from block references that don't exist like closed values
           ^::existing-property-value? [:block/uuid (:block/uuid pvalue)]
-          (or (:db/ident pvalue) (db-property/property-value-content pvalue)))))
+          (or (:db/ident pvalue)
+              ;; nbb-compatible version of db-property/property-value-content
+              (or (block-title pvalue)
+                  (:logseq.property/value pvalue))))))
 
 (defn- buildable-properties
   "Originally copied from db-test/readable-properties. Modified so that property values are
@@ -208,7 +211,11 @@
        set))
 
 (defn- merge-export-maps [& export-maps]
-  (let [pages-and-blocks (reduce into [] (keep :pages-and-blocks export-maps))
+  (let [pages-and-blocks
+        (->> (mapcat :pages-and-blocks export-maps)
+             ;; TODO: Group by more correct identity, same as check-for-existing-entities
+             (group-by #(get-in % [:page :block/title]))
+             (mapv #(apply merge (second %))))
         ;; Use merge-with to preserve new-property? and to allow full copies to overwrite shallow ones
         properties (apply merge-with merge (keep :properties export-maps))
         classes (apply merge-with merge (keep :classes export-maps))]
@@ -221,8 +228,10 @@
 (defn- build-content-ref-export
   "Builds an export config (and additional info) for refs in the given blocks. All the exported
    entities found in block refs include their uuid in order to preserve the relationship to the blocks"
-  [db page-blocks]
-  (let [content-ref-uuids (set (mapcat (comp db-content/get-matched-ids block-title) page-blocks))
+  [db blocks*]
+  (let [;; Remove property value blocks that can't have content refs
+        blocks (remove :logseq.property/value blocks*)
+        content-ref-uuids (set (mapcat (comp db-content/get-matched-ids block-title) blocks))
         content-ref-ents (map #(d/entity db [:block/uuid %]) content-ref-uuids)
         content-ref-pages (filter #(or (ldb/internal-page? %) (entity-util/journal? %)) content-ref-ents)
         content-ref-properties (when-let [prop-ids (seq (map :db/ident (filter ldb/property? content-ref-ents)))]
@@ -322,7 +331,11 @@
   "Exports block for given block eid"
   [db eid]
   (let [block-entity (d/entity db eid)
-        {:keys [content-ref-uuids content-ref-ents] :as content-ref-export} (build-content-ref-export db [block-entity])
+        property-value-ents (->> (dissoc (db-property/properties block-entity) :block/tags)
+                                 vals
+                                 (filter de/entity?))
+        {:keys [content-ref-uuids content-ref-ents] :as content-ref-export}
+        (build-content-ref-export db (into [block-entity] property-value-ents))
         node-export (build-node-export db block-entity {:include-uuid-fn content-ref-uuids})
         pvalue-uuids (get-pvalue-uuids (:node node-export))
         uuid-block-export (build-uuid-block-export db pvalue-uuids content-ref-ents {})
@@ -345,12 +358,12 @@
   (let [page-entity (d/entity db eid)
         datoms (d/datoms db :avet :block/page eid)
         block-eids (mapv :e datoms)
-        page-blocks (->> block-eids
-                         (map #(d/entity db %))
+        page-blocks* (map #(d/entity db %) block-eids)
+        {:keys [content-ref-uuids content-ref-ents] :as content-ref-export} (build-content-ref-export db page-blocks*)
+        page-blocks (->> page-blocks*
                          (sort-by :block/order)
-                         ;; Remove property value blocks as they are included in the block they belong to
+                         ;; Remove property value blocks as they are exported in a block's :build/properties
                          (remove #(:logseq.property/created-from-property %)))
-        {:keys [content-ref-uuids content-ref-ents] :as content-ref-export} (build-content-ref-export db page-blocks)
         {:keys [pvalue-uuids] :as blocks-export}
         (build-blocks-export db page-blocks {:include-uuid-fn content-ref-uuids})
         uuid-block-export (build-uuid-block-export db pvalue-uuids content-ref-ents {:page-entity page-entity})
@@ -469,7 +482,7 @@
                                          :e
                                          (d/entity db))]
                      (assoc-in m [:page :block/uuid] (:block/uuid ent))
-                     ;; For now only check page uniqueness by title. Could handle more uniqueness checks later
+                     ;; TODO: For now only check page uniqueness by title. Could handle more uniqueness checks later
                      (if-let [ent (some->> (get-in m [:page :block/title]) (ldb/get-case-page db))]
                        (assoc-in m [:page :block/uuid] (:block/uuid ent))
                        m)))

+ 15 - 5
deps/db/test/logseq/db/sqlite/export_test.cljs

@@ -112,11 +112,15 @@
 
 (deftest import-block-with-block-ref
   (let [page-uuid (random-uuid)
+        block-uuid (random-uuid)
         original-data
-        {:pages-and-blocks
+        {:properties {:user.property/p1 {:logseq.property/type :default}}
+         :pages-and-blocks
          [{:page {:block/title "page1"}
-           :blocks [{:block/title (str "page ref to " (page-ref/->page-ref page-uuid))}]}
-          {:page {:block/title "another page" :block/uuid page-uuid :build/keep-uuid? true}}]}
+           :blocks [{:block/title (str "page ref to " (page-ref/->page-ref page-uuid))
+                     :build/properties {:user.property/p1 (str "block ref to " (page-ref/->page-ref block-uuid))}}]}
+          {:page {:block/title "another page" :block/uuid page-uuid :build/keep-uuid? true}
+           :blocks [{:block/title "b1" :block/uuid block-uuid :build/keep-uuid? true}]}]}
         conn (db-test/create-conn-with-blocks original-data)
         conn2 (db-test/create-conn-with-blocks
                {:pages-and-blocks [{:page {:block/title "page2"}
@@ -207,6 +211,7 @@
         internal-block-uuid (random-uuid)
         class-uuid (random-uuid)
         page-uuid (random-uuid)
+        pvalue-page-uuid (random-uuid)
         property-uuid (random-uuid)
         journal-uuid (random-uuid)
         block-object-uuid (random-uuid)
@@ -217,11 +222,15 @@
                       {:logseq.property/type :node
                        :block/uuid property-uuid
                        :build/keep-uuid? true
-                       :build/property-classes [:user.class/NodeClass]}}
+                       :build/property-classes [:user.class/NodeClass]}
+                      :user.property/p2
+                      {:logseq.property/type :default}}
          :pages-and-blocks
          [{:page {:block/title "page1"}
            :blocks [{:block/title (str "page ref to " (page-ref/->page-ref page-uuid))}
                     {:block/title (str "block ref to " (page-ref/->page-ref block-uuid))}
+                    {:block/title "ref in properties"
+                     :build/properties {:user.property/p2 (str "pvalue ref to " (page-ref/->page-ref pvalue-page-uuid))}}
                     {:block/title "hola" :block/uuid internal-block-uuid :build/keep-uuid? true}
                     {:block/title (str "internal block ref to " (page-ref/->page-ref internal-block-uuid))}
                     {:block/title (str "class ref to " (page-ref/->page-ref class-uuid))}
@@ -231,7 +240,8 @@
           {:page {:block/title "page with block ref"}
            :blocks [{:block/title "hi" :block/uuid block-uuid :build/keep-uuid? true
                      :build/properties {:user.property/p1 [:block/uuid block-object-uuid]}}]}
-          {:page {:block/title "another page" :block/uuid page-uuid :build/keep-uuid? true}}
+          {:page {:block/title "page ref page" :block/uuid page-uuid :build/keep-uuid? true}}
+          {:page {:block/title "pvalue ref page" :block/uuid pvalue-page-uuid :build/keep-uuid? true}}
           {:page {:build/journal 20250207 :block/uuid journal-uuid :build/keep-uuid? true}}
           {:page {:block/title "Blocks"}
            :blocks [{:block/title "myclass object"