Fix multi-valued properties and enable first property graph test

Run db prop test with: DB_GRAPH=1 node static/tests.js -i focus
pull/10016/head
Gabriel Horner 2023-07-24 16:42:36 -04:00
parent 4920b3a98e
commit 0ca7d1a4de
4 changed files with 98 additions and 15 deletions

View File

@ -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)

View File

@ -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]

View File

@ -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))))

View File

@ -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