Browse Source

feat: add namespace query support

Tienson Qin 4 years ago
parent
commit
d965394be2

+ 7 - 6
src/main/frontend/components/query_table.cljs

@@ -40,7 +40,7 @@
                   (remove (property/built-in-properties))
                   (remove #{:template}))
         keys (if page? (cons :page keys) (cons :block keys))
-        keys (if page? (concat keys [:created-at :updated-at]) keys)]
+        keys (if page? (distinct (concat keys [:created-at :updated-at])) keys)]
     keys))
 
 (defn attach-clock-property
@@ -85,11 +85,12 @@
                  query-properties
                  (get-keys result page?))
           included-keys #{:created-at :updated-at}
-          keys (if (some included-keys keys)
-                 (concat included-keys
-                         (remove included-keys keys)
-                         (filter included-keys keys))
-                 keys)
+          keys (distinct
+                (if (some included-keys keys)
+                  (concat (remove included-keys keys)
+                          (filter included-keys keys)
+                          included-keys)
+                  keys))
           sort-by-fn (fn [item]
                        (let [key sort-by-item]
                          (case key

+ 2 - 26
src/main/frontend/db/model.cljs

@@ -13,36 +13,12 @@
             [frontend.format :as format]
             [frontend.state :as state]
             [frontend.util :as util :refer [react]]
-            [medley.core :as medley]))
+            [medley.core :as medley]
+            [frontend.db.rules :refer [rules]]))
 
 ;; TODO: extract to specific models and move data transform logic to the
 ;; correponding handlers.
 
-(def rules
-  '[[(parent ?p ?c)
-     [?c :block/parent ?p]]
-    [(parent ?p ?c)
-     [?c :block/parent ?t]
-     (parent ?p ?t)]
-
-    ;; from https://stackoverflow.com/questions/43784258/find-entities-whose-ref-to-many-attribute-contains-all-elements-of-input
-    ;; Quote:
-    ;; You're tackling the general problem of 'dynamic conjunction' in Datomic's Datalog.
-    ;; Write a dynamic Datalog query which uses 2 negations and 1 disjunction or a recursive rule
-    ;; Datalog has no direct way of expressing dynamic conjunction (logical AND / 'for all ...' / set intersection).
-    ;; However, you can achieve it in pure Datalog by combining one disjunction
-    ;; (logical OR / 'exists ...' / set union) and two negations, i.e
-    ;; (For all ?g in ?Gs p(?e,?g)) <=> NOT(Exists ?g in ?Gs, such that NOT(p(?e, ?g)))
-
-    ;; [(matches-all ?e ?a ?vs)
-    ;;  [(first ?vs) ?v0]
-    ;;  [?e ?a ?v0]
-    ;;  (not-join [?e ?vs]
-    ;;            [(identity ?vs) [?v ...]]
-    ;;            (not-join [?e ?v]
-    ;;                      [?e ?a ?v]))]
-    ])
-
 ;; Use it as an input argument for datalog queries
 (defonce block-attrs
   '[:db/id

+ 9 - 1
src/main/frontend/db/query_dsl.cljs

@@ -317,10 +317,18 @@
            nil))
 
        (= 'page fe)
-       (let [page-name (string/lower-case (first (rest e)))
+       (let [page-name (string/lower-case (str (first (rest e))))
              page-name (text/page-ref-un-brackets! page-name)]
          [['?b :block/page [:block/name page-name]]])
 
+       (and (= 'namespace fe)
+            (= 2 (count e)))
+       (let [page-name (string/lower-case (str (first (rest e))))
+             page (text/page-ref-un-brackets! page-name)]
+         (when-not (string/blank? page)
+           [['?p :block/namespace '?parent]
+            ['?parent :block/name page]]))
+
        (= 'page-property fe)
        (let [[k v] (rest e)
              k (string/replace (name k) "_" "-")]

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

@@ -12,7 +12,8 @@
             [frontend.db.utils :as db-utils]
             [frontend.state :as state]
             [frontend.util :as util :refer [profile react]]
-            [frontend.util.marker :as marker]))
+            [frontend.util.marker :as marker]
+            [frontend.db.rules :as rules]))
 
 ;; Query atom of map of Key ([repo q inputs]) -> atom
 ;; TODO: replace with LRUCache, only keep the latest 20 or 50 items?
@@ -129,6 +130,10 @@
          (set! (.-state result-atom) result)
          (add-q! k nil nil result-atom identity identity identity))))))
 
+(defn add-rules-to-inputs
+  [inputs]
+  (conj (vec inputs) rules/rules))
+
 (defn q
   [repo k {:keys [use-cache? transform-fn query-fn inputs-fn]
            :or {use-cache? true

+ 32 - 0
src/main/frontend/db/rules.cljs

@@ -0,0 +1,32 @@
+(ns frontend.db.rules)
+
+(def rules
+  '[[(parent ?p ?c)
+     [?c :block/parent ?p]]
+    [(parent ?p ?c)
+     [?c :block/parent ?t]
+     (parent ?p ?t)]
+
+    [(namespace ?p ?c)
+     [?c :block/namespace ?p]]
+    [(namespace ?p ?c)
+     [?c :block/namespace ?t]
+     (namespace ?p ?t)]
+
+    ;; from https://stackoverflow.com/questions/43784258/find-entities-whose-ref-to-many-attribute-contains-all-elements-of-input
+    ;; Quote:
+    ;; You're tackling the general problem of 'dynamic conjunction' in Datomic's Datalog.
+    ;; Write a dynamic Datalog query which uses 2 negations and 1 disjunction or a recursive rule
+    ;; Datalog has no direct way of expressing dynamic conjunction (logical AND / 'for all ...' / set intersection).
+    ;; However, you can achieve it in pure Datalog by combining one disjunction
+    ;; (logical OR / 'exists ...' / set union) and two negations, i.e
+    ;; (For all ?g in ?Gs p(?e,?g)) <=> NOT(Exists ?g in ?Gs, such that NOT(p(?e, ?g)))
+
+    ;; [(matches-all ?e ?a ?vs)
+    ;;  [(first ?vs) ?v0]
+    ;;  [?e ?a ?v0]
+    ;;  (not-join [?e ?vs]
+    ;;            [(identity ?vs) [?v ...]]
+    ;;            (not-join [?e ?v]
+    ;;                      [?e ?a ?v]))]
+    ])