Ver Fonte

Fix multi-valued properties and enable first property graph test

Run db prop test with: DB_GRAPH=1 node static/tests.js -i focus
Gabriel Horner há 2 anos atrás
pai
commit
0ca7d1a4de

+ 8 - 5
deps/db/src/logseq/db/rules.cljc

@@ -156,11 +156,14 @@
      [?prop-b :block/type "property"]
      [?prop-b :block/uuid ?prop-uuid]
      [(get ?prop ?prop-uuid) ?v]
-     [(str ?val) ?str-val]
-     (or [(= ?v ?val)]
-         [(contains? ?v ?val)]
-         ;; For integer pages that aren't strings
-         [(contains? ?v ?str-val)])]
+     ;; TODO: Need to find a more performant way to do this
+     (or-join [?v]
+              [(= ?v ?val)]
+              (and [(str ?val) ?str-val]
+                    ;; str-val is for integer pages that aren't strings
+                   [?prop-val-b :block/original-name ?str-val]
+                   [?prop-val-b :block/uuid ?val-uuid]
+                   [(contains? ?v ?val-uuid)]))]
 
    :page-ref
    '[(page-ref ?b ?page-name)

+ 0 - 1
src/main/frontend/handler/property.cljs

@@ -2,7 +2,6 @@
   "Block properties handler."
   (:require [clojure.edn :as edn]
             [clojure.string :as string]
-            [clojure.set :as set]
             [frontend.db :as db]
             [frontend.db.model :as model]
             [frontend.handler.notification :as notification]

+ 8 - 3
src/test/frontend/db/query_dsl_test.cljs

@@ -86,8 +86,13 @@ prop-c:: [[page a]], [[page b]], [[page c]]
 prop-linked-num:: [[3000]]
 prop-d:: [[no-space-link]]
 - b4
-prop-d:: nada"}])
-
+prop-d:: nada"
+                     :file/blocks [["b1" {:prop-a "val-a" :prop-num 2000}]
+                                   ["b2" {:prop-a "val-a" :prop-b "val-b"}]
+                                   ["b3" {:prop-c #{"page a" "page b" "page c"}
+                                           :prop-linked-num #{"3000"}
+                                           :prop-d #{"no-space-link"}}]
+                                   ["b4" {:prop-d "nada"}]]}])
   (testing "Blocks have given property value"
     (is (= #{"b1" "b2"}
            (set (map (comp first str/split-lines :block/content)
@@ -139,7 +144,7 @@ prop-d:: nada"}])
               (dsl-query "(property prop-d)")))
       "Blocks that have a property"))
 
-(deftest block-property-queries
+(deftest ^:focus block-property-queries
   (testing "block property tests with default config"
     (test-helper/with-config {}
       (block-property-queries-test))))

+ 82 - 6
src/test/frontend/test/helper.cljs

@@ -2,9 +2,14 @@
   "Common helper fns for tests"
   (:require [frontend.handler.repo :as repo-handler]
             [frontend.state :as state]
-            [frontend.db.conn :as conn]))
+            [frontend.db.conn :as conn]
+            [clojure.string :as string]
+            [clojure.set :as set]
+            [frontend.modules.outliner.core :as outliner-core]
+            [frontend.db :as db]
+            [datascript.core :as d]))
 
-(defonce test-db "test-db")
+(defonce test-db (if (some? js/process.env.DB_GRAPH) "logseq_db_test-db" "test-db"))
 
 (defn start-test-db!
   []
@@ -19,15 +24,86 @@
   (destroy-test-db!)
   (start-test-db!))
 
+;; Currently this only works for load-test-files that have added a :file/blocks for each file arg
+(defn- load-test-files-for-db-graph
+  [files*]
+  (let [files (mapv #(assoc % :file/content
+                            (string/join "\n"
+                                         (map (fn [x] (str "- " (first x))) (:file/blocks %))))
+                    files*)]
+    ;; TODO: Use sqlite instead of file graph to create client db
+    (repo-handler/parse-files-and-load-to-db!
+     test-db
+     files
+     {:re-render? false :verbose false :refresh? true})
+    (let [content-uuid-map (into {} (d/q
+                                     '[:find ?content ?uuid
+                                       :where
+                                       [?b :block/content ?content]
+                                       [?b :block/uuid ?uuid]]
+                                     (frontend.db/get-db test-db)))
+          property-uuids (->> files
+                              (mapcat #(->> % :file/blocks (map second) (mapcat keys)))
+                              set
+                              (map #(vector % (random-uuid)))
+                              (into {}))
+            ;; from upsert-property!
+          property-tx (mapv (fn [[prop-name uuid]]
+                              (outliner-core/block-with-timestamps
+                               {:block/schema {:type :default}
+                                :block/original-name (name prop-name)
+                                :block/name (string/lower-case (name prop-name))
+                                :block/uuid uuid
+                                :block/type "property"}))
+                            property-uuids)
+          page-uuids (->> files
+                          (mapcat #(->> %
+                                        :file/blocks
+                                        (map second)
+                                        (mapcat (fn [m]
+                                                  (->> m vals (filter set?) (apply set/union))))))
+                          set
+                          (map #(vector % (random-uuid)))
+                          (into {}))
+          page-tx (mapv (fn [[page-name uuid]]
+                          (outliner-core/block-with-timestamps
+                           {:block/name (string/lower-case page-name)
+                            :block/original-name page-name
+                            :block/uuid uuid}))
+                        page-uuids)
+            ;; from add-property!
+          block-tx (mapcat
+                    (fn [file]
+                      (map
+                       (fn [[content props]]
+                         {:block/uuid (or (content-uuid-map content)
+                                          (throw (ex-info "No uuid for content" {:content content})))
+                          :block/properties
+                          (->> props
+                               (map
+                                (fn [[prop-name val]]
+                                  [(or (property-uuids prop-name)
+                                       (throw (ex-info "No uuid for property" {:name prop-name})))
+                                   (if (set? val)
+                                     (set (map (fn [p] (or (page-uuids p) (throw (ex-info "No uuid for page" {:name p}))))
+                                               val))
+                                     val)]))
+                               (into {}))})
+                       (:file/blocks file)))
+                    files)]
+      (db/transact! test-db (vec (concat page-tx property-tx block-tx))))))
+
 (defn load-test-files
   "Given a collection of file maps, loads them into the current test-db.
 This can be called in synchronous contexts as no async fns should be invoked"
   [files]
-  (repo-handler/parse-files-and-load-to-db!
-   test-db
-   files
+  (if js/process.env.DB_GRAPH
+    (load-test-files-for-db-graph files)
+    (repo-handler/parse-files-and-load-to-db!
+     test-db
+     files
    ;; Set :refresh? to avoid creating default files in after-parse
-   {:re-render? false :verbose false :refresh? true}))
+     {:re-render? false :verbose false :refresh? true})))
 
 (defn start-and-destroy-db
   "Sets up a db connection and current repo like fixtures/reset-datascript. It