Просмотр исходного кода

Split out query operators that are tested

Gabriel Horner 3 лет назад
Родитель
Сommit
b248c95ce3
1 измененных файлов с 160 добавлено и 121 удалено
  1. 160 121
      src/main/frontend/db/query_dsl.cljs

+ 160 - 121
src/main/frontend/db/query_dsl.cljs

@@ -141,7 +141,7 @@
      l)
      l)
     @vars))
     @vars))
 
 
-;; TODO: Convert -> fns to rules
+;; TODO: Convert ->*query fns to rules
 (defn ->property-query
 (defn ->property-query
   ([k v]
   ([k v]
    (->property-query k v '?v))
    (->property-query k v '?v))
@@ -166,10 +166,158 @@
     [(list '= '?v v)]
     [(list '= '?v v)]
     [(list 'contains? '?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
 (defn ^:large-vars/cleanup-todo build-query
   ([repo e env]
   ([repo e env]
    (build-query repo e (assoc env :vars (atom {})) 0))
    (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.
    ;; TODO: replace with multi-methods for extensibility.
    (let [fe (first e)
    (let [fe (first e)
          fe (when fe (symbol (string/lower-case (name fe))))
          fe (when fe (symbol (string/lower-case (name fe))))
@@ -191,79 +339,14 @@
        (do
        (do
          (reset! blocks? true)
          (reset! blocks? true)
          [['?b :block/content '?content]
          [['?b :block/content '?content]
-         [(list 'clojure.string/includes? '?content e)]])
+          [(list 'clojure.string/includes? '?content e)]])
 
 
        (contains? #{'and 'or 'not} fe)
        (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)
        (and (= 'between fe)
             (= 3 (count e)))
             (= 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)
        ;; (between created_at -1d today)
        (and (= 'between fe)
        (and (= 'between fe)
@@ -274,7 +357,7 @@
                    (string/replace "-" "_"))]
                    (string/replace "-" "_"))]
          (when (contains? #{"created_at" "last_modified_at"} k)
          (when (contains? #{"created_at" "last_modified_at"} k)
            (let [start (->timestamp (nth e 2))
            (let [start (->timestamp (nth e 2))
-                 end (->timestamp (nth e 3))]
+                  end (->timestamp (nth e 3))]
              (when (and start end)
              (when (and start end)
                (let [[start end] (sort [start end])
                (let [[start end] (sort [start end])
                      sym '?v]
                      sym '?v]
@@ -285,42 +368,17 @@
 
 
        (and (= 'property fe)
        (and (= 'property fe)
             (= 3 (count e)))
             (= 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)
        (and (= 'property fe)
             (= 2 (count e)))
             (= 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))
        (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)
        (= '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)
        (= 'sort-by fe)
        (let [[k order] (rest e)
        (let [[k order] (rest e)
@@ -361,29 +419,10 @@
             ['?parent :block/name page]]))
             ['?parent :block/name page]]))
 
 
        (= 'page-property fe)
        (= '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)
        (= '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)
        (= 'all-page-tags fe)
        [['?e :block/tags '?p]]
        [['?e :block/tags '?p]]