Browse Source

enhance: add :block/link support for export+import edn

Gabriel Horner 9 months ago
parent
commit
16930aa23c

+ 12 - 6
deps/db/src/logseq/db/sqlite/build.cljs

@@ -618,12 +618,18 @@
                                  m))
                                  m))
                              properties-tx)
                              properties-tx)
         pages-and-blocks-tx (build-pages-and-blocks-tx pages-and-blocks' all-idents page-uuids
         pages-and-blocks-tx (build-pages-and-blocks-tx pages-and-blocks' all-idents page-uuids
-                                                       (assoc options :properties properties))]
-    ;; Properties first b/c they have schema and are referenced by all. Then classes b/c they can be referenced by pages. Then pages
-    (split-blocks-tx (concat properties-tx'
-                             classes-tx
-                             pages-and-blocks-tx)
-                     properties)))
+                                                       (assoc options :properties properties))
+        ;; Properties first b/c they have schema and are referenced by all. Then
+        ;; classes b/c they can be referenced by pages. Then pages
+        split-txs (split-blocks-tx (concat properties-tx' classes-tx pages-and-blocks-tx)
+                                   properties)]
+    (cond-> split-txs
+      ;; Just add indices option as there are too many out of order uuid cases with importing user content
+      (:build-existing-tx? options)
+      (update :init-tx
+              (fn [init-tx]
+                (let [indices (mapv #(select-keys % [:block/uuid]) (filter :block/uuid init-tx))]
+                  (into indices init-tx)))))))
 
 
 ;; Public API
 ;; Public API
 ;; ==========
 ;; ==========

+ 8 - 2
deps/db/src/logseq/db/sqlite/export.cljs

@@ -183,6 +183,8 @@
         build-tags (when (seq (:block/tags entity)) (->build-tags (:block/tags entity)))
         build-tags (when (seq (:block/tags entity)) (->build-tags (:block/tags entity)))
         new-properties (when-not shallow-copy? (build-node-properties db entity ent-properties properties))
         new-properties (when-not shallow-copy? (build-node-properties db entity ent-properties properties))
         build-node (cond-> {:block/title (block-title entity)}
         build-node (cond-> {:block/title (block-title entity)}
+                     (:block/link entity)
+                     (assoc :block/link [:block/uuid (:block/uuid (:block/link entity))])
                      (include-uuid-fn (:block/uuid entity))
                      (include-uuid-fn (:block/uuid entity))
                      (assoc :block/uuid (:block/uuid entity) :build/keep-uuid? true)
                      (assoc :block/uuid (:block/uuid entity) :build/keep-uuid? true)
                      (and (not shallow-copy?) (seq build-tags))
                      (and (not shallow-copy?) (seq build-tags))
@@ -245,12 +247,16 @@
       classes (assoc :classes classes))))
       classes (assoc :classes classes))))
 
 
 (defn- build-content-ref-export
 (defn- build-content-ref-export
-  "Builds an export config (and additional info) for refs in the given blocks. All the exported
+  "Builds an export config (and additional info) for refs in the given blocks. Refs are detected
+   if they are a :block/link or if a `[[UUID]]` ref in the content. All the exported
    entities found in block refs include their uuid in order to preserve the relationship to the blocks"
    entities found in block refs include their uuid in order to preserve the relationship to the blocks"
   [db blocks*]
   [db blocks*]
   (let [;; Remove property value blocks that can't have content refs
   (let [;; Remove property value blocks that can't have content refs
         blocks (remove :logseq.property/value blocks*)
         blocks (remove :logseq.property/value blocks*)
-        content-ref-uuids (set (mapcat (comp db-content/get-matched-ids block-title) blocks))
+        block-links (->> (filter :block/link blocks)
+                         (map #(:block/uuid (:block/link %))))
+        content-ref-uuids (into (set (mapcat (comp db-content/get-matched-ids block-title) blocks))
+                                block-links)
         content-ref-ents (map #(d/entity db [:block/uuid %]) content-ref-uuids)
         content-ref-ents (map #(d/entity db [:block/uuid %]) content-ref-uuids)
         content-ref-pages (filter #(or (entity-util/internal-page? %) (entity-util/journal? %)) content-ref-ents)
         content-ref-pages (filter #(or (entity-util/internal-page? %) (entity-util/journal? %)) content-ref-ents)
         {:keys [properties classes]}
         {:keys [properties classes]}

+ 21 - 0
deps/db/test/logseq/db/sqlite/export_test.cljs

@@ -311,6 +311,27 @@
                                       (into (vec (remove #(= "hola" (:block/title %)) bs))
                                       (into (vec (remove #(= "hola" (:block/title %)) bs))
                                             bs))})))
                                             bs))})))
 
 
+(deftest import-page-with-block-links
+  (let [block-uuid (random-uuid)
+        original-data
+        {:pages-and-blocks
+         [{:page {:block/title "page1"}
+           :blocks [{:block/title "b1" :block/uuid block-uuid :build/keep-uuid? true}
+                    {:block/title "" :block/link [:block/uuid block-uuid]}]}]}
+        ;; add option to test out of order uuids
+        conn (db-test/create-conn-with-blocks (assoc original-data :build-existing-tx? true))
+        conn2 (db-test/create-conn)
+        imported-page (export-page-and-import-to-another-graph conn conn2 "page1")]
+    (is (= (:pages-and-blocks original-data) (:pages-and-blocks imported-page))
+        "Page's blocks are imported")
+
+    (import-second-time-assertions conn conn2 "page1" original-data
+                                   {:transform-expected-blocks
+                                    (fn [bs]
+                                      ;; internal referenced block doesn't get copied b/c it already exists
+                                      (into (vec (remove #(= "b1" (:block/title %)) bs))
+                                            bs))})))
+
 (deftest import-page-with-different-page-and-classes
 (deftest import-page-with-different-page-and-classes
   (let [original-data
   (let [original-data
         {:properties {:user.property/p1 {:logseq.property/type :default}
         {:properties {:user.property/p1 {:logseq.property/type :default}