1
0
Эх сурвалжийг харах

fix: correctly detect property type

for property values containing text and refs.
Also allow import script to only import a file for testing.
Part of LOG-2985
Gabriel Horner 1 жил өмнө
parent
commit
44d60808c1

+ 20 - 3
deps/graph-parser/script/db_import.cljs

@@ -6,6 +6,7 @@
             [datascript.core :as d]
             ["path" :as node-path]
             ["os" :as os]
+            ["fs" :as fs]
             ["fs/promises" :as fsp]
             [nbb.core :as nbb]
             [babashka.cli :as cli]
@@ -31,11 +32,15 @@
     (->> (common-graph/get-files dir)
          (mapv #(hash-map :rpath %)))))
 
+(defn- <read-file
+  [file]
+  (p/let [s (fsp/readFile (:rpath file))]
+    (str s)))
+
 (defn- import-file-graph-to-db [file-graph-dir conn user-options]
   (p/let [*files (build-graph-files file-graph-dir)
           config-file (first (filter #(string/ends-with? (:rpath %) "logseq/config.edn") *files))
           _ (assert config-file "No 'logseq/config.edn' found for file graph dir")
-          <read-file #(p/let [s (fsp/readFile (:rpath %))] (str s))
           ;; TODO: Add :default-config option
           config (gp-exporter/import-config-file! conn config-file <read-file {:notify-user prn})
           files (remove-hidden-files file-graph-dir config *files)
@@ -52,6 +57,15 @@
      (gp-exporter/import-logseq-files conn logseq-files <read-file {:notify-user prn})
      (gp-exporter/import-from-doc-files! conn doc-files <read-file import-options))))
 
+(defn- import-files-to-db [file conn user-options]
+  (let [import-options (gp-exporter/setup-import-options
+                        @conn
+                        {}
+                        user-options
+                        {:notify-user prn})
+        files [{:rpath file}]]
+    (gp-exporter/import-from-doc-files! conn files <read-file import-options)))
+
 (def spec
   "Options spec"
   {:help {:alias :h
@@ -78,9 +92,12 @@
                           ((juxt node-path/dirname node-path/basename) graph-dir'))
                         [(node-path/join (os/homedir) "logseq" "graphs") db-graph-dir])
         file-graph' (node-path/join (or js/process.env.ORIGINAL_PWD ".") file-graph)
-        conn (create-graph/init-conn dir db-name)]
+        conn (create-graph/init-conn dir db-name)
+        directory? (.isDirectory (fs/statSync file-graph'))]
     (p/do!
-     (import-file-graph-to-db file-graph' conn (merge options {:graph-name db-name}))
+     (if directory?
+       (import-file-graph-to-db file-graph' conn (merge options {:graph-name db-name}))
+       (import-files-to-db file-graph' conn (merge options {:graph-name db-name})))
      (when (:verbose options) (println "Transacted" (count (d/datoms @conn :eavt)) "datoms"))
      (println "Created graph" (str db-name "!")))))
 

+ 34 - 9
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -99,22 +99,46 @@
    ;; Not supported as they have been ignored for a long time and cause invalid built-in pages
    :now :later :doing :done :canceled :cancelled :in-progress :todo :wait :waiting])
 
+(defn- text-with-refs?
+  "Detects if a property value has text with refs e.g. `#Logseq is #awesome`
+  instead of `#Logseq #awesome`. If so the property type is :default instead of :page"
+  [vals val-text]
+  (let [replace-regex (re-pattern
+                       ;; Regex removes all characters of a tag or page-ref
+                       ;; so that only ref chars are left
+                       (str "([#[])"
+                            "("
+                            ;; Sorts ref names in descending order so that longer names
+                            ;; come first. Order matters since (foo-bar|foo) correctly replaces
+                            ;; "foo-bar" whereas (foo|foo-bar) does not
+                            (->> vals (sort >) (map common-util/escape-regex-chars) (string/join "|"))
+                            ")"))
+        remaining-text (string/replace val-text replace-regex "$1")
+        non-ref-char (some #(if (or (string/blank? %) (#{"[" "]" "," "#"} %))
+                              false
+                              %)
+                           remaining-text)]
+    (some? non-ref-char)))
+
 (defn- infer-property-schema-and-get-property-change
   "Infers a property's schema from the given _user_ property value and adds new ones to
   the property-schemas atom. If a property's :type changes, returns a map of
   the schema attribute changed and how it changed e.g. `{:type {:from :default :to :url}}`"
-  [prop-val prop refs property-schemas macros]
+  [prop-val prop prop-val-text refs property-schemas macros]
   ;; Explicitly fail an unexpected case rather cause silent downstream failures
   (when (and (coll? prop-val) (not (every? string? prop-val)))
     (throw (ex-info "Import cannot infer schema of unknown property value"
                     {:value prop-val :property prop})))
-  (let [prop-type (if (and (coll? prop-val)
-                           (seq prop-val)
-                           (set/subset? prop-val
-                                        (set (keep #(when (:block/journal? %) (:block/original-name %)) refs))))
-                    :date
-                    (db-property-type/infer-property-type-from-value
-                     (macro-util/expand-value-if-macro prop-val macros)))
+  (let [prop-type (cond (and (coll? prop-val)
+                             (seq prop-val)
+                             (set/subset? prop-val
+                                          (set (keep #(when (:block/journal? %) (:block/original-name %)) refs))))
+                        :date
+                        (and (coll? prop-val) (seq prop-val) (text-with-refs? prop-val prop-val-text))
+                        :default
+                        :else
+                        (db-property-type/infer-property-type-from-value
+                         (macro-util/expand-value-if-macro prop-val macros)))
         prev-type (get-in @property-schemas [prop :type])]
     (when-not prev-type
       (let [schema (cond-> {:type prop-type}
@@ -245,7 +269,8 @@
               property-changes
               (->> properties-to-infer
                    (keep (fn [[prop val]]
-                           (when-let [property-change (infer-property-schema-and-get-property-change val prop refs (:property-schemas import-state) macros)]
+                           (when-let [property-change
+                                      (infer-property-schema-and-get-property-change val prop (get (:block/properties-text-values block) prop) refs (:property-schemas import-state) macros)]
                              [prop property-change])))
                    (into {}))
               _ (when (seq property-changes) (log-fn :PROP-CHANGES property-changes))