mirror of https://github.com/logseq/logseq
feat: add namespace query support
parent
4f1402ea42
commit
d965394be2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) "_" "-")]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]))]
|
||||
])
|
Loading…
Reference in New Issue