mirror of https://github.com/logseq/logseq
fix: sort-by filter for db graphs
Also fixed a dsl-query sorting bug where nil property values where incorrectly being treated as greater than non-nil values. Also fixed a bug where blocks with an explicit :block/created-at weren't being set for sqlite-buildexperiment/tanstack-table
parent
29faedc4d0
commit
8f6f52d630
|
@ -109,8 +109,8 @@
|
||||||
(seq pvalue-tx-m)
|
(seq pvalue-tx-m)
|
||||||
(into (mapcat #(if (set? %) % [%]) (vals pvalue-tx-m)))
|
(into (mapcat #(if (set? %) % [%]) (vals pvalue-tx-m)))
|
||||||
true
|
true
|
||||||
(conj (merge (dissoc m :build/properties)
|
(conj (merge (sqlite-util/block-with-timestamps new-block)
|
||||||
(sqlite-util/block-with-timestamps new-block)
|
(dissoc m :build/properties)
|
||||||
(when (seq properties)
|
(when (seq properties)
|
||||||
(->block-properties (merge properties (db-property-build/build-properties-with-ref-values pvalue-tx-m))
|
(->block-properties (merge properties (db-property-build/build-properties-with-ref-values pvalue-tx-m))
|
||||||
page-uuids all-idents))
|
page-uuids all-idents))
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
[frontend.db.model :as model]
|
[frontend.db.model :as model]
|
||||||
[frontend.db.query-react :as query-react]
|
[frontend.db.query-react :as query-react]
|
||||||
[frontend.db.utils :as db-utils]
|
[frontend.db.utils :as db-utils]
|
||||||
[frontend.db.conn :as conn]
|
|
||||||
[datascript.core :as d]
|
|
||||||
[logseq.db.frontend.rules :as rules]
|
[logseq.db.frontend.rules :as rules]
|
||||||
[frontend.template :as template]
|
[frontend.template :as template]
|
||||||
[logseq.graph-parser.text :as text]
|
[logseq.graph-parser.text :as text]
|
||||||
|
@ -370,7 +368,11 @@
|
||||||
order (if (contains? #{:asc :desc} order*)
|
order (if (contains? #{:asc :desc} order*)
|
||||||
order*
|
order*
|
||||||
:desc)
|
:desc)
|
||||||
comp (if (= order :desc) >= <=)]
|
comp (if (= order :desc)
|
||||||
|
;; Handle nil so that is always less than a value e.g. treated as a "" for a string.
|
||||||
|
;; Otherwise sort bugs occur that prevent non-nil values from being sorted
|
||||||
|
#(if (nil? %2) true (>= %1 %2))
|
||||||
|
#(if (nil? %1) true (<= %1 %2)))]
|
||||||
(reset! sort-by_
|
(reset! sort-by_
|
||||||
(fn sort-results [result property-val-fn]
|
(fn sort-results [result property-val-fn]
|
||||||
;; first because there is one binding result in query-wrapper
|
;; first because there is one binding result in query-wrapper
|
||||||
|
@ -615,18 +617,20 @@ Some bindings in this fn:
|
||||||
[col]
|
[col]
|
||||||
;; Only modify result shapes that we know of
|
;; Only modify result shapes that we know of
|
||||||
(if (map? (ffirst col))
|
(if (map? (ffirst col))
|
||||||
(let [prop-uuid-names (->> (d/datoms (conn/get-db) :avet :block/type "property")
|
|
||||||
(map :e)
|
|
||||||
(db-utils/pull-many '[:block/uuid :block/name])
|
|
||||||
(map #(vector (:block/uuid %) (keyword (:block/name %))))
|
|
||||||
(into {}))]
|
|
||||||
(map (fn [blocks]
|
(map (fn [blocks]
|
||||||
(mapv (fn [block]
|
(mapv (fn [block]
|
||||||
(assoc block
|
(assoc block
|
||||||
:block/properties-by-name
|
:block/properties-by-name
|
||||||
(update-keys (:block/properties block) #(prop-uuid-names % %))))
|
(->> (db-property/properties block)
|
||||||
|
(map (fn [[k v]]
|
||||||
|
[(:block/original-name (db-utils/entity k))
|
||||||
|
(or (some->> (:db/id v)
|
||||||
|
db-utils/entity
|
||||||
|
db-property/get-property-value-name)
|
||||||
|
v)]))
|
||||||
|
(into {}))))
|
||||||
blocks))
|
blocks))
|
||||||
col))
|
col)
|
||||||
col))
|
col))
|
||||||
|
|
||||||
(defn get-db-property-value
|
(defn get-db-property-value
|
||||||
|
@ -636,7 +640,14 @@ Some bindings in this fn:
|
||||||
(case prop
|
(case prop
|
||||||
:created-at (:block/created-at m)
|
:created-at (:block/created-at m)
|
||||||
:updated-at (:block/updated-at m)
|
:updated-at (:block/updated-at m)
|
||||||
(get-in m [:block/properties-by-name prop])))
|
(get-in m [:block/properties-by-name (name prop)])))
|
||||||
|
|
||||||
|
(def db-block-attrs
|
||||||
|
"Like ldb/block-attrs but for query dsl an db graphs"
|
||||||
|
;; '*' needed as we need to pull user properties and don't know their names in advance
|
||||||
|
'[*
|
||||||
|
{:block/page [:db/id :block/name :block/original-name :block/journal-day]}
|
||||||
|
{:block/_parent ...}])
|
||||||
|
|
||||||
(defn query
|
(defn query
|
||||||
"Runs a dsl query with query as a string. Primary use is from '{{query }}'"
|
"Runs a dsl query with query as a string. Primary use is from '{{query }}'"
|
||||||
|
@ -645,7 +656,9 @@ Some bindings in this fn:
|
||||||
([repo query-string query-opts]
|
([repo query-string query-opts]
|
||||||
(when (and (string? query-string) (not= "\"\"" query-string))
|
(when (and (string? query-string) (not= "\"\"" query-string))
|
||||||
(let [{:keys [query rules sort-by blocks? sample]} (parse-query query-string)]
|
(let [{:keys [query rules sort-by blocks? sample]} (parse-query query-string)]
|
||||||
(when-let [query' (some-> query (query-wrapper {:blocks? blocks?}))]
|
(when-let [query' (some-> query (query-wrapper {:blocks? blocks?
|
||||||
|
:block-attrs (when (config/db-based-graph? repo)
|
||||||
|
db-block-attrs)}))]
|
||||||
(let [random-samples (if @sample
|
(let [random-samples (if @sample
|
||||||
(fn [col]
|
(fn [col]
|
||||||
(take @sample (shuffle col)))
|
(take @sample (shuffle col)))
|
||||||
|
@ -670,8 +683,10 @@ Some bindings in this fn:
|
||||||
[repo query-m query-opts]
|
[repo query-m query-opts]
|
||||||
(when (seq (:query query-m))
|
(when (seq (:query query-m))
|
||||||
(let [query-string (template/resolve-dynamic-template! (pr-str (:query query-m)))
|
(let [query-string (template/resolve-dynamic-template! (pr-str (:query query-m)))
|
||||||
{:keys [query sort-by blocks? rules]} (parse query-string {:db-graph? (config/db-based-graph? repo)})]
|
db-graph? (config/db-based-graph? repo)
|
||||||
(when-let [query' (some-> query (query-wrapper {:blocks? blocks?}))]
|
{:keys [query sort-by blocks? rules]} (parse query-string {:db-graph? db-graph?})]
|
||||||
|
(when-let [query' (some-> query (query-wrapper {:blocks? blocks?
|
||||||
|
:block-attrs (when db-graph? db-block-attrs)}))]
|
||||||
(query-react/react-query repo
|
(query-react/react-query repo
|
||||||
(merge
|
(merge
|
||||||
query-m
|
query-m
|
||||||
|
@ -681,7 +696,7 @@ Some bindings in this fn:
|
||||||
query-opts
|
query-opts
|
||||||
(when sort-by
|
(when sort-by
|
||||||
{:transform-fn
|
{:transform-fn
|
||||||
(if (config/db-based-graph? repo)
|
(if db-graph?
|
||||||
(comp (fn [col] (sort-by col get-db-property-value)) sort-by-prep)
|
(comp (fn [col] (sort-by col get-db-property-value)) sort-by-prep)
|
||||||
#(sort-by % (fn [m prop] (get-in m [:block/properties prop]))))})))))))
|
#(sort-by % (fn [m prop] (get-in m [:block/properties prop]))))})))))))
|
||||||
|
|
||||||
|
|
|
@ -550,33 +550,34 @@ created-at:: 1608968448115
|
||||||
- 26-b4
|
- 26-b4
|
||||||
created-at:: 1608968448116
|
created-at:: 1608968448116
|
||||||
"}])
|
"}])
|
||||||
|
(let [task-filter (if js/process.env.DB_GRAPH "(task todo done)" "(task later done)")]
|
||||||
(testing "sort-by user block property fruit"
|
(testing "sort-by user block property fruit"
|
||||||
(let [result (->> (dsl-query "(and (task now later done) (sort-by fruit))")
|
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by fruit))"))
|
||||||
(map #(get-property-value % :fruit)))]
|
(map #(get-property-value % :fruit)))]
|
||||||
(is (= ["plum" "apple" nil]
|
(is (= ["plum" "apple" nil]
|
||||||
result)
|
result)
|
||||||
"sort-by correctly defaults to desc"))
|
"sort-by correctly defaults to desc"))
|
||||||
|
|
||||||
(let [result (->> (dsl-query "(and (task now later done) (sort-by fruit desc))")
|
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by fruit desc))"))
|
||||||
(map #(get-property-value % :fruit)))]
|
(map #(get-property-value % :fruit)))]
|
||||||
(is (= ["plum" "apple" nil]
|
(is (= ["plum" "apple" nil]
|
||||||
result)
|
result)
|
||||||
"sort-by desc"))
|
"sort-by desc"))
|
||||||
|
|
||||||
(let [result (->> (dsl-query "(and (task now later done) (sort-by fruit asc))")
|
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by fruit asc))"))
|
||||||
(map #(get-property-value % :fruit)))]
|
(map #(get-property-value % :fruit)))]
|
||||||
(is (= ["apple" "plum" nil]
|
(is (= [nil "apple" "plum"]
|
||||||
result)
|
result)
|
||||||
"sort-by asc")))
|
"sort-by asc")))
|
||||||
|
|
||||||
(testing "sort-by hidden, built-in block property created-at"
|
(testing "sort-by hidden, built-in block property created-at"
|
||||||
(let [result (->> (dsl-query "(and (task now later done) (sort-by created-at desc))")
|
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by created-at desc))"))
|
||||||
(map #(get-property-value % :created-at)))]
|
(map #(get-property-value % :created-at)))]
|
||||||
(is (= [1608968448115 1608968448114 1608968448113]
|
(is (= [1608968448115 1608968448114 1608968448113]
|
||||||
result))
|
result))
|
||||||
"sorted-by desc")
|
"sorted-by desc")
|
||||||
|
|
||||||
(let [result (->> (dsl-query "(and (todo now later done) (sort-by created-at asc))")
|
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by created-at asc))"))
|
||||||
(map #(get-property-value % :created-at)))]
|
(map #(get-property-value % :created-at)))]
|
||||||
(is (= [1608968448113 1608968448114 1608968448115]
|
(is (= [1608968448113 1608968448114 1608968448115]
|
||||||
result)
|
result)
|
||||||
|
@ -585,9 +586,9 @@ created-at:: 1608968448116
|
||||||
(testing "user page property rating"
|
(testing "user page property rating"
|
||||||
(is (= [10 8]
|
(is (= [10 8]
|
||||||
(->> (dsl-query "(and (page-property rating) (sort-by rating))")
|
(->> (dsl-query "(and (page-property rating) (sort-by rating))")
|
||||||
(map #(get-property-value % :rating)))))))
|
(map #(get-property-value % :rating))))))))
|
||||||
|
|
||||||
(deftest simplify-query
|
(deftest ^:done simplify-query
|
||||||
(are [x y] (= (query-dsl/simplify-query x) y)
|
(are [x y] (= (query-dsl/simplify-query x) y)
|
||||||
'(and [[foo]])
|
'(and [[foo]])
|
||||||
'[[foo]]
|
'[[foo]]
|
||||||
|
|
Loading…
Reference in New Issue