mirror of
https://github.com/logseq/logseq.git
synced 2026-04-27 15:45:00 +00:00
Split out query operators that are tested
This commit is contained in:
@@ -141,7 +141,7 @@
|
||||
l)
|
||||
@vars))
|
||||
|
||||
;; TODO: Convert -> fns to rules
|
||||
;; TODO: Convert ->*query fns to rules
|
||||
(defn ->property-query
|
||||
([k v]
|
||||
(->property-query k v '?v))
|
||||
@@ -166,10 +166,158 @@
|
||||
[(list '= '?v v)]
|
||||
[(list 'contains? '?v v)])])
|
||||
|
||||
(defn- build-query-property-two-arg
|
||||
[e current-filter counter]
|
||||
(let [k (string/replace (name (nth e 1)) "_" "-")
|
||||
v (nth e 2)
|
||||
v (if-not (nil? v)
|
||||
(text/parse-property k v)
|
||||
v)
|
||||
v (if (coll? v) (first v) v)
|
||||
sym (if (= current-filter 'or)
|
||||
'?v
|
||||
(uniq-symbol counter "?v"))]
|
||||
(->property-query k v sym)))
|
||||
|
||||
(defn- build-query-and-or-not-result
|
||||
[fe clauses current-filter nested-and?]
|
||||
(cond
|
||||
(= fe 'not)
|
||||
(let [clauses (if (coll? (first clauses))
|
||||
(apply concat clauses)
|
||||
clauses)
|
||||
clauses (if (and (= 1 (count clauses))
|
||||
(= 'and (ffirst clauses)))
|
||||
;; unflatten
|
||||
(rest (first clauses))
|
||||
clauses)]
|
||||
(cons fe (seq clauses)))
|
||||
|
||||
(coll? (first clauses))
|
||||
(cond
|
||||
(= current-filter 'not)
|
||||
(->> (apply concat clauses)
|
||||
(apply list fe))
|
||||
|
||||
(or (= current-filter 'or)
|
||||
nested-and?)
|
||||
(apply concat clauses)
|
||||
|
||||
:else
|
||||
(->> (map (fn [result]
|
||||
(let [result (if (vector? (ffirst result))
|
||||
(apply concat result)
|
||||
result)]
|
||||
(cons 'and (seq result)))) clauses)
|
||||
(apply list fe)))
|
||||
|
||||
:else
|
||||
(apply list fe clauses)))
|
||||
|
||||
(declare build-query)
|
||||
|
||||
(defn- build-query-and-or-not
|
||||
[repo e {:keys [current-filter vars] :as env} level fe]
|
||||
(let [clauses (->> (map (fn [form]
|
||||
(build-query repo form (assoc env :current-filter fe) (inc level)))
|
||||
(rest e))
|
||||
remove-nil?
|
||||
(distinct))
|
||||
nested-and? (and (= fe 'and) (= current-filter 'and))]
|
||||
(when (seq clauses)
|
||||
(let [result (build-query-and-or-not-result
|
||||
fe clauses current-filter nested-and?)
|
||||
vars' (set/union (set @vars) (collect-vars result))]
|
||||
(reset! vars vars')
|
||||
(cond
|
||||
;; TODO: more thoughts
|
||||
(and (= current-filter 'and)
|
||||
(= 'or fe)
|
||||
(= #{'?b} vars'))
|
||||
[(concat result [['?b]])]
|
||||
|
||||
nested-and?
|
||||
result
|
||||
|
||||
(and (zero? level) (= 'and fe))
|
||||
(distinct (apply concat clauses))
|
||||
|
||||
(and (zero? level) (= 'or fe))
|
||||
result
|
||||
|
||||
:else
|
||||
[result])))))
|
||||
|
||||
(defn- build-query-between-two-arg
|
||||
[e]
|
||||
(let [start (->journal-day-int (nth e 1))
|
||||
end (->journal-day-int (nth e 2))
|
||||
[start end] (sort [start end])]
|
||||
[['?b :block/page '?p]
|
||||
['?p :block/journal? true]
|
||||
['?p :block/journal-day '?d]
|
||||
[(list '>= '?d start)]
|
||||
[(list '<= '?d end)]]))
|
||||
|
||||
(defn- build-query-property-one-arg
|
||||
[e]
|
||||
(let [k (string/replace (name (nth e 1)) "_" "-")]
|
||||
[['?b :block/properties '?prop]
|
||||
[(list 'missing? '$ '?b :block/name)]
|
||||
[(list 'get '?prop (keyword k)) '?prop-v]
|
||||
[true]]))
|
||||
|
||||
(defn- build-query-todo
|
||||
[e]
|
||||
(let [markers (if (coll? (first (rest e)))
|
||||
(first (rest e))
|
||||
(rest e))]
|
||||
(when (seq markers)
|
||||
(let [markers (set (map (comp string/upper-case name) markers))]
|
||||
[['?b :block/marker '?marker]
|
||||
[(list 'contains? markers '?marker)]]))))
|
||||
|
||||
(defn- build-query-priority
|
||||
[e]
|
||||
(let [priorities (if (coll? (first (rest e)))
|
||||
(first (rest e))
|
||||
(rest e))]
|
||||
(when (seq priorities)
|
||||
(let [priorities (set (map (comp string/upper-case name) priorities))]
|
||||
[['?b :block/priority '?priority]
|
||||
[(list 'contains? priorities '?priority)]]))))
|
||||
|
||||
(defn- build-page-property
|
||||
[e]
|
||||
(let [[k v] (rest e)
|
||||
k (string/replace (name k) "_" "-")]
|
||||
(if-not (nil? v)
|
||||
(let [v (text/parse-property k v)
|
||||
v (if (coll? v) (first v) v)]
|
||||
(->page-property-query k v))
|
||||
[['?p :block/name]
|
||||
['?p :block/properties '?prop]
|
||||
[(list 'get '?prop (keyword k)) '?prop-v]
|
||||
[true]])))
|
||||
|
||||
(defn- build-query-page-tags
|
||||
[e counter]
|
||||
(let [tags (if (coll? (first (rest e)))
|
||||
(first (rest e))
|
||||
(rest e))
|
||||
tags (map (comp string/lower-case name) tags)]
|
||||
(when (seq tags)
|
||||
(let [tags (set (map (comp text/page-ref-un-brackets! string/lower-case name) tags))
|
||||
sym-1 (uniq-symbol counter "?t")
|
||||
sym-2 (uniq-symbol counter "?tag")]
|
||||
[['?p :block/tags sym-1]
|
||||
[sym-1 :block/name sym-2]
|
||||
[(list 'contains? tags sym-2)]]))))
|
||||
|
||||
(defn ^:large-vars/cleanup-todo build-query
|
||||
([repo e env]
|
||||
(build-query repo e (assoc env :vars (atom {})) 0))
|
||||
([repo e {:keys [sort-by blocks? sample counter current-filter vars] :as env} level]
|
||||
([repo e {:keys [sort-by blocks? sample counter current-filter] :as env} level]
|
||||
;; TODO: replace with multi-methods for extensibility.
|
||||
(let [fe (first e)
|
||||
fe (when fe (symbol (string/lower-case (name fe))))
|
||||
@@ -191,79 +339,14 @@
|
||||
(do
|
||||
(reset! blocks? true)
|
||||
[['?b :block/content '?content]
|
||||
[(list 'clojure.string/includes? '?content e)]])
|
||||
[(list 'clojure.string/includes? '?content e)]])
|
||||
|
||||
(contains? #{'and 'or 'not} fe)
|
||||
(let [clauses (->> (map (fn [form]
|
||||
(build-query repo form (assoc env :current-filter fe) (inc level)))
|
||||
(rest e))
|
||||
remove-nil?
|
||||
(distinct))
|
||||
nested-and? (and (= fe 'and) (= current-filter 'and))]
|
||||
(when (seq clauses)
|
||||
(let [result (cond
|
||||
(= fe 'not)
|
||||
(let [clauses (if (coll? (first clauses))
|
||||
(apply concat clauses)
|
||||
clauses)
|
||||
clauses (if (and (= 1 (count clauses))
|
||||
(= 'and (ffirst clauses)))
|
||||
;; unflatten
|
||||
(rest (first clauses))
|
||||
clauses)]
|
||||
(cons fe (seq clauses)))
|
||||
|
||||
(coll? (first clauses))
|
||||
(cond
|
||||
(= current-filter 'not)
|
||||
(->> (apply concat clauses)
|
||||
(apply list fe))
|
||||
|
||||
(or (= current-filter 'or)
|
||||
nested-and?)
|
||||
(apply concat clauses)
|
||||
|
||||
:else
|
||||
(->> (map (fn [result]
|
||||
(let [result (if (vector? (ffirst result))
|
||||
(apply concat result)
|
||||
result)]
|
||||
(cons 'and (seq result)))) clauses)
|
||||
(apply list fe)))
|
||||
|
||||
:else
|
||||
(apply list fe clauses))
|
||||
vars' (set/union (set @vars) (collect-vars result))]
|
||||
(reset! vars vars')
|
||||
(cond
|
||||
;; TODO: more thoughts
|
||||
(and (= current-filter 'and)
|
||||
(= 'or fe)
|
||||
(= #{'?b} vars'))
|
||||
[(concat result [['?b]])]
|
||||
|
||||
nested-and?
|
||||
result
|
||||
|
||||
(and (zero? level) (= 'and fe))
|
||||
(distinct (apply concat clauses))
|
||||
|
||||
(and (zero? level) (= 'or fe))
|
||||
result
|
||||
|
||||
:else
|
||||
[result]))))
|
||||
(build-query-and-or-not repo e env level fe)
|
||||
|
||||
(and (= 'between fe)
|
||||
(= 3 (count e)))
|
||||
(let [start (->journal-day-int (nth e 1))
|
||||
end (->journal-day-int (nth e 2))
|
||||
[start end] (sort [start end])]
|
||||
[['?b :block/page '?p]
|
||||
['?p :block/journal? true]
|
||||
['?p :block/journal-day '?d]
|
||||
[(list '>= '?d start)]
|
||||
[(list '<= '?d end)]])
|
||||
(build-query-between-two-arg e)
|
||||
|
||||
;; (between created_at -1d today)
|
||||
(and (= 'between fe)
|
||||
@@ -274,7 +357,7 @@
|
||||
(string/replace "-" "_"))]
|
||||
(when (contains? #{"created_at" "last_modified_at"} k)
|
||||
(let [start (->timestamp (nth e 2))
|
||||
end (->timestamp (nth e 3))]
|
||||
end (->timestamp (nth e 3))]
|
||||
(when (and start end)
|
||||
(let [[start end] (sort [start end])
|
||||
sym '?v]
|
||||
@@ -285,42 +368,17 @@
|
||||
|
||||
(and (= 'property fe)
|
||||
(= 3 (count e)))
|
||||
(let [k (string/replace (name (nth e 1)) "_" "-")
|
||||
v (nth e 2)
|
||||
v (if-not (nil? v)
|
||||
(text/parse-property k v)
|
||||
v)
|
||||
v (if (coll? v) (first v) v)
|
||||
sym (if (= current-filter 'or)
|
||||
'?v
|
||||
(uniq-symbol counter "?v"))]
|
||||
(->property-query k v sym))
|
||||
(build-query-property-two-arg e current-filter counter)
|
||||
|
||||
(and (= 'property fe)
|
||||
(= 2 (count e)))
|
||||
(let [k (string/replace (name (nth e 1)) "_" "-")]
|
||||
[['?b :block/properties '?prop]
|
||||
[(list 'missing? '$ '?b :block/name)]
|
||||
[(list 'get '?prop (keyword k)) '?prop-v]
|
||||
[true]])
|
||||
(build-query-property-one-arg e)
|
||||
|
||||
(or (= 'todo fe) (= 'task fe))
|
||||
(let [markers (if (coll? (first (rest e)))
|
||||
(first (rest e))
|
||||
(rest e))]
|
||||
(when (seq markers)
|
||||
(let [markers (set (map (comp string/upper-case name) markers))]
|
||||
[['?b :block/marker '?marker]
|
||||
[(list 'contains? markers '?marker)]])))
|
||||
(build-query-todo e)
|
||||
|
||||
(= 'priority fe)
|
||||
(let [priorities (if (coll? (first (rest e)))
|
||||
(first (rest e))
|
||||
(rest e))]
|
||||
(when (seq priorities)
|
||||
(let [priorities (set (map (comp string/upper-case name) priorities))]
|
||||
[['?b :block/priority '?priority]
|
||||
[(list 'contains? priorities '?priority)]])))
|
||||
(build-query-priority e)
|
||||
|
||||
(= 'sort-by fe)
|
||||
(let [[k order] (rest e)
|
||||
@@ -361,29 +419,10 @@
|
||||
['?parent :block/name page]]))
|
||||
|
||||
(= 'page-property fe)
|
||||
(let [[k v] (rest e)
|
||||
k (string/replace (name k) "_" "-")]
|
||||
(if-not (nil? v)
|
||||
(let [v (text/parse-property k v)
|
||||
v (if (coll? v) (first v) v)]
|
||||
(->page-property-query k v))
|
||||
[['?p :block/name]
|
||||
['?p :block/properties '?prop]
|
||||
[(list 'get '?prop (keyword k)) '?prop-v]
|
||||
[true]]))
|
||||
(build-page-property e)
|
||||
|
||||
(= 'page-tags fe)
|
||||
(let [tags (if (coll? (first (rest e)))
|
||||
(first (rest e))
|
||||
(rest e))
|
||||
tags (map (comp string/lower-case name) tags)]
|
||||
(when (seq tags)
|
||||
(let [tags (set (map (comp text/page-ref-un-brackets! string/lower-case name) tags))
|
||||
sym-1 (uniq-symbol counter "?t")
|
||||
sym-2 (uniq-symbol counter "?tag")]
|
||||
[['?p :block/tags sym-1]
|
||||
[sym-1 :block/name sym-2]
|
||||
[(list 'contains? tags sym-2)]])))
|
||||
(build-query-page-tags e counter)
|
||||
|
||||
(= 'all-page-tags fe)
|
||||
[['?e :block/tags '?p]]
|
||||
|
||||
Reference in New Issue
Block a user