Explorar o código

fix: importer fails to find classes with property-parent-classes option

when on pages that have the same name as a built-in
Gabriel Horner hai 9 meses
pai
achega
697147540f

+ 25 - 20
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -735,24 +735,25 @@
    {:keys [user-options log-fn import-state] :as options}]
   (let [{:keys [block properties-tx]} (handle-page-and-block-properties block* db page-names-to-uuids refs options)
         block'
-        (if (seq properties)
-          (let [parent-classes-from-properties (->> (select-keys properties (:property-parent-classes user-options))
-                                                    (mapcat (fn [[_k v]] (if (coll? v) v [v])))
-                                                    distinct)]
-            ;; TODO: Mv new classes from these find-or-create-class to :classes-tx as they are the only ones
-            ;; that aren't conrolled by :classes-tx
-            (cond-> block
-              (seq parent-classes-from-properties)
-              (merge (find-or-create-class db ((some-fn ::original-title :block/title) block) (:all-idents import-state) block))
-              (seq parent-classes-from-properties)
-              (assoc :logseq.property/parent
-                     (let [new-class (first parent-classes-from-properties)
-                           class-m (find-or-create-class db new-class (:all-idents import-state))]
-                       (when (> (count parent-classes-from-properties) 1)
-                         (log-fn :skipped-parent-classes "Only one parent class is allowed so skipped ones after the first one" :classes parent-classes-from-properties))
-                       (merge class-m
-                              {:block/uuid (find-or-gen-class-uuid page-names-to-uuids (common-util/page-name-sanity-lc new-class) (:db/ident class-m))})))))
-          (dissoc block* :block/properties))
+        (if-let [parent-classes-from-properties (->> (select-keys properties (:property-parent-classes user-options))
+                                                     (mapcat (fn [[_k v]] (if (coll? v) v [v])))
+                                                     distinct
+                                                     seq)]
+          (let [_ (swap! (:classes-from-property-parents import-state) conj (:block/title block*))
+                ;; TODO: Mv new classes from these find-or-create-class to :classes-tx as they are the only ones
+                ;; that aren't conrolled by :classes-tx
+                class-m (find-or-create-class db ((some-fn ::original-title :block/title) block) (:all-idents import-state) block)
+                class-m' (-> block
+                             (merge class-m)
+                             (assoc :logseq.property/parent
+                                    (let [new-class (first parent-classes-from-properties)
+                                          class-m (find-or-create-class db new-class (:all-idents import-state))]
+                                      (when (> (count parent-classes-from-properties) 1)
+                                        (log-fn :skipped-parent-classes "Only one parent class is allowed so skipped ones after the first one" :classes parent-classes-from-properties))
+                                      (merge class-m
+                                             {:block/uuid (find-or-gen-class-uuid page-names-to-uuids (common-util/page-name-sanity-lc new-class) (:db/ident class-m))}))))]
+            class-m')
+          block)
         block'' (replace-namespace-with-parent block' page-names-to-uuids)]
     {:block block'' :properties-tx properties-tx}))
 
@@ -915,7 +916,7 @@
   "Returns a map of unique page names mapped to their uuids. The page names
    are in a format that is compatible with extract/extract e.g. namespace pages have
    their full hierarchy in the name"
-  [db]
+  [db classes-from-property-parents]
   (->> db
        ;; don't fetch built-in as that would give the wrong entity if a user used
        ;; a db-only built-in property name e.g. description
@@ -924,6 +925,8 @@
        (map #(d/entity db %))
        (map #(vector
               (if-let [parents (and (or (ldb/internal-page? %) (ldb/class? %))
+                                    ;; These classes have parents now but don't in file graphs (and in extract)
+                                    (not (contains? classes-from-property-parents (:block/title %)))
                                     (->> (ldb/get-page-parents %)
                                          (remove (fn [e] (= :logseq.class/Root (:db/ident e))))
                                          seq))]
@@ -1000,7 +1003,7 @@
                         ;; remove file path relative
                         (map #(dissoc % :block/file)))
         ;; Fetch all named ents once per import file to speed up named lookups
-        all-existing-page-uuids (get-all-existing-page-uuids @conn)
+        all-existing-page-uuids (get-all-existing-page-uuids @conn @(:classes-from-property-parents import-state))
         all-pages (map #(modify-page-tx % all-existing-page-uuids) all-pages*)
         all-new-page-uuids (->> all-pages
                                 (remove #(all-existing-page-uuids (or (::original-name %) (:block/name %))))
@@ -1110,6 +1113,8 @@
    :property-schemas (atom {})
    ;; Map of property or class names (keyword) to db-ident keywords
    :all-idents (atom {})
+   ;; Set of children pages turned into classes by :property-parent-classes option
+   :classes-from-property-parents (atom #{})
    ;; Map of block uuids to their :block/properties-text-values value.
    ;; Used if a property value changes to :default
    :block-properties-text-values (atom {})})

+ 3 - 2
deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs

@@ -660,7 +660,8 @@
 (deftest-async export-files-with-property-parent-classes-option
   (p/let [file-graph-dir "test/resources/exporter-test-graph"
           files (mapv #(node-path/join file-graph-dir %) ["pages/CreativeWork.md" "pages/Movie.md" "pages/type.md"
-                                                          "pages/Whiteboard___Tool.md" "pages/Whiteboard___Arrow_head_toggle.md"])
+                                                          "pages/Whiteboard___Tool.md" "pages/Whiteboard___Arrow_head_toggle.md"
+                                                          "pages/Property.md" "pages/url.md"])
           conn (db-test/create-conn)
           _ (import-files-to-db files conn {:property-parent-classes ["parent"]
                                             ;; Also add this option to trigger some edge cases with namespace pages
@@ -670,7 +671,7 @@
         "Created graph has no validation errors")
 
     (is (= #{:user.class/Movie :user.class/CreativeWork :user.class/Thing
-             :user.class/Class :user.class/Tool :user.class/Whiteboard___Tool}
+             :user.class/Class :user.class/Tool :user.class/Whiteboard___Tool :user.class/Property}
            (->> @conn
                 (d/q '[:find [?ident ...]
                        :where [?b :block/tags :logseq.class/Tag] [?b :db/ident ?ident] (not [?b :logseq.property/built-in?])])

+ 1 - 0
deps/graph-parser/test/resources/exporter-test-graph/pages/Property.md

@@ -0,0 +1 @@
+parent:: [[Thing]]

+ 1 - 1
deps/graph-parser/test/resources/exporter-test-graph/pages/url.md

@@ -1,4 +1,4 @@
 type:: [[Property]]
 url:: {{docs-base-url url}}
 sameAs:: https://schema.org/url
-rangeIncludes:: [[Uri]]
+rangeIncludes:: [[Property]]