Split out query operators that are tested

This commit is contained in:
Gabriel Horner
2022-02-25 17:17:05 -05:00
parent 5c38aa36cc
commit b248c95ce3

View File

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