Browse Source

feat: enable dsl query in advanced queries

Tienson Qin 4 years ago
parent
commit
221febe5cb

+ 6 - 1
src/main/frontend/db.cljs

@@ -5,6 +5,7 @@
             [frontend.db.model]
             [frontend.db.react]
             [frontend.db.query-custom]
+            [frontend.db.query-react]
             [frontend.util :as util]
             [datascript.core :as d]
             [frontend.state :as state]
@@ -61,7 +62,11 @@
   query-state query-components query-entity-in-component remove-custom-query! set-new-result! sub-key-value]
 
  [frontend.db.query-custom
-  custom-query custom-query-result-transform])
+  custom-query]
+
+ [frontend.db.query-react
+  react-query custom-query-result-transform]
+ )
 
 ;; persisting DBs between page reloads
 (defn persist! [repo]

+ 10 - 101
src/main/frontend/db/query_custom.cljs

@@ -1,106 +1,11 @@
 (ns frontend.db.query-custom
   "Custom queries."
-  (:require [datascript.core :as d]
-            [frontend.db.utils :as db-utils :refer [date->int]]
-            [frontend.db.model :as model]
-            [cljs-time.core :as t]
-            [frontend.state :as state]
+  (:require [frontend.state :as state]
             [clojure.string :as string]
             [cljs.reader :as reader]
-            [frontend.extensions.sci :as sci]
-            [lambdaisland.glogi :as log]
-            [frontend.util :as util]
-            [frontend.db.react :as react]
-            [frontend.text :as text]
-            [clojure.walk :as walk]))
-
-(defn- resolve-input
-  [input]
-  (cond
-    (= :today input)
-    (date->int (t/today))
-    (= :yesterday input)
-    (date->int (t/yesterday))
-    (= :tomorrow input)
-    (date->int (t/plus (t/today) (t/days 1)))
-    (= :current-page input)
-    (string/lower-case (state/get-current-page))
-    (and (keyword? input)
-         (re-find #"^\d+d(-before)?$" (name input)))
-    (let [input (name input)
-          days (util/parse-int (subs input 0 (dec (count input))))]
-      (date->int (t/minus (t/today) (t/days days))))
-    (and (keyword? input)
-         (re-find #"^\d+d(-after)?$" (name input)))
-    (let [input (name input)
-          days (util/parse-int (subs input 0 (dec (count input))))]
-      (date->int (t/plus (t/today) (t/days days))))
-
-    (and (string? input) (text/page-ref? input))
-    (-> (text/page-ref-un-brackets! input)
-        (string/lower-case))
-
-    :else
-    input))
-
-(defn custom-query-result-transform
-  [query-result remove-blocks q]
-  (try
-    (let [repo (state/get-current-repo)
-         result (db-utils/seq-flatten query-result)
-         block? (:block/uuid (first result))]
-     (let [result (if block?
-                    (let [result (if (seq remove-blocks)
-                                   (let [remove-blocks (set remove-blocks)]
-                                     (remove (fn [h]
-                                               (contains? remove-blocks (:block/uuid h)))
-                                             result))
-                                   result)]
-                      (some->> result
-                               (db-utils/with-repo repo)
-                               (model/with-block-refs-count repo)
-                               (model/sort-blocks)))
-                    result)]
-       (if-let [result-transform (:result-transform q)]
-         (if-let [f (sci/eval-string (pr-str result-transform))]
-           (try
-             (sci/call-fn f result)
-             (catch js/Error e
-               (log/error :sci/call-error e)
-               result))
-           result)
-         (if block?
-           (db-utils/group-by-page result)
-           result))))
-    (catch js/Error e
-      (log/error :query/failed e))))
-
-(defn- resolve-query
-  [query]
-  (let [page-ref? #(and (string? %) (text/page-ref? %))]
-    (walk/postwalk
-     (fn [f]
-       (if (and (list? f)
-                (= (first f) '=)
-                (= 3 (count f))
-                (some page-ref? (rest f)))
-         (let [[x y] (rest f)
-               [page-ref sym] (if (page-ref? x) [x y] [y x])
-               page-ref (string/lower-case page-ref)]
-           (list 'contains? sym (text/page-ref-un-brackets! page-ref)))
-         f)) query)))
-
-(defn react-query
-  [repo {:keys [query inputs] :as query'} query-opts]
-  (try
-    (let [query (resolve-query query)
-          inputs (map resolve-input inputs)
-          repo (or repo (state/get-current-repo))
-          k [:custom query']]
-      (apply react/q repo k query-opts query inputs))
-    (catch js/Error e
-      (println "Custom query failed: ")
-      (js/console.dir e))))
+            [frontend.db.query-react :as react]
+            [frontend.template :as template]
+            [frontend.db.query-dsl :as dsl]))
 
 (defn custom-query
   ([query]
@@ -109,11 +14,15 @@
    (when-let [query' (cond
                        (and (string? query)
                             (not (string/blank? query)))
-                       (reader/read-string query)
+                       (let [query-string (template/resolve-dynamic-template! query)]
+                         (reader/read-string query))
 
                        (map? query)
                        query
 
                        :else
                        nil)]
-     (react-query (state/get-current-repo) query' query-opts))))
+     (let [repo (state/get-current-repo)]
+       (if (list? (:query query')) ; dsl query
+         (dsl/custom-query repo query' query-opts )
+         (react/react-query repo query' query-opts))))))

+ 22 - 6
src/main/frontend/db/query_dsl.cljs

@@ -4,9 +4,8 @@
             [datascript.core :as d]
             [lambdaisland.glogi :as log]
             [clojure.string :as string]
-            [frontend.db :as db]
             [frontend.text :as text]
-            [frontend.db.query-custom :as query-custom]
+            [frontend.db.query-react :as react]
             [frontend.date :as date]
             [cljs-time.core :as t]
             [cljs-time.coerce :as tc]
@@ -384,10 +383,27 @@
           {:keys [query sort-by blocks?]} (parse repo query-string)]
       (when query
         (let [query (query-wrapper query blocks?)]
-          (query-custom/react-query repo
-                                    {:query query}
-                                    (if sort-by
-                                      {:transform-fn sort-by})))))))
+          (react/react-query repo
+                             {:query query}
+                             (if sort-by
+                               {:transform-fn sort-by})))))))
+
+(defn custom-query
+  [repo query-m query-opts]
+  (when (seq (:query query-m))
+    (let [query-string (pr-str (:query query-m))
+          query-string (template/resolve-dynamic-template! query-string)
+          {:keys [query sort-by blocks?]} (parse repo query-string)]
+      (when query
+        (let [query (query-wrapper query blocks?)]
+          (react/react-query repo
+                             (merge
+                              query-m
+                              {:query query})
+                             (merge
+                              query-opts
+                              (if sort-by
+                                {:transform-fn sort-by}))))))))
 
 (comment
   ;; {{query (and (page-property foo bar) [[hello]])}}

+ 103 - 0
src/main/frontend/db/query_react.cljs

@@ -0,0 +1,103 @@
+(ns frontend.db.query-react
+  "Custom queries."
+  (:require [datascript.core :as d]
+            [frontend.db.utils :as db-utils :refer [date->int]]
+            [frontend.db.model :as model]
+            [cljs-time.core :as t]
+            [frontend.state :as state]
+            [clojure.string :as string]
+            [cljs.reader :as reader]
+            [frontend.extensions.sci :as sci]
+            [lambdaisland.glogi :as log]
+            [frontend.util :as util]
+            [frontend.db.react :as react]
+            [frontend.text :as text]
+            [clojure.walk :as walk]))
+
+(defn- resolve-input
+  [input]
+  (cond
+    (= :today input)
+    (date->int (t/today))
+    (= :yesterday input)
+    (date->int (t/yesterday))
+    (= :tomorrow input)
+    (date->int (t/plus (t/today) (t/days 1)))
+    (= :current-page input)
+    (string/lower-case (state/get-current-page))
+    (and (keyword? input)
+         (re-find #"^\d+d(-before)?$" (name input)))
+    (let [input (name input)
+          days (util/parse-int (subs input 0 (dec (count input))))]
+      (date->int (t/minus (t/today) (t/days days))))
+    (and (keyword? input)
+         (re-find #"^\d+d(-after)?$" (name input)))
+    (let [input (name input)
+          days (util/parse-int (subs input 0 (dec (count input))))]
+      (date->int (t/plus (t/today) (t/days days))))
+
+    (and (string? input) (text/page-ref? input))
+    (-> (text/page-ref-un-brackets! input)
+        (string/lower-case))
+
+    :else
+    input))
+
+(defn custom-query-result-transform
+  [query-result remove-blocks q]
+  (try
+    (let [repo (state/get-current-repo)
+         result (db-utils/seq-flatten query-result)
+         block? (:block/uuid (first result))]
+     (let [result (if block?
+                    (let [result (if (seq remove-blocks)
+                                   (let [remove-blocks (set remove-blocks)]
+                                     (remove (fn [h]
+                                               (contains? remove-blocks (:block/uuid h)))
+                                             result))
+                                   result)]
+                      (some->> result
+                               (db-utils/with-repo repo)
+                               (model/with-block-refs-count repo)
+                               (model/sort-blocks)))
+                    result)]
+       (if-let [result-transform (:result-transform q)]
+         (if-let [f (sci/eval-string (pr-str result-transform))]
+           (try
+             (sci/call-fn f result)
+             (catch js/Error e
+               (log/error :sci/call-error e)
+               result))
+           result)
+         (if block?
+           (db-utils/group-by-page result)
+           result))))
+    (catch js/Error e
+      (log/error :query/failed e))))
+
+(defn- resolve-query
+  [query]
+  (let [page-ref? #(and (string? %) (text/page-ref? %))]
+    (walk/postwalk
+     (fn [f]
+       (if (and (list? f)
+                (= (first f) '=)
+                (= 3 (count f))
+                (some page-ref? (rest f)))
+         (let [[x y] (rest f)
+               [page-ref sym] (if (page-ref? x) [x y] [y x])
+               page-ref (string/lower-case page-ref)]
+           (list 'contains? sym (text/page-ref-un-brackets! page-ref)))
+         f)) query)))
+
+(defn react-query
+  [repo {:keys [query inputs] :as query'} query-opts]
+  (try
+    (let [query (resolve-query query)
+          inputs (map resolve-input inputs)
+          repo (or repo (state/get-current-repo))
+          k [:custom query']]
+      (apply react/q repo k query-opts query inputs))
+    (catch js/Error e
+      (println "Custom query failed: ")
+      (js/console.dir e))))