I want to catch from page TODO that has no sub todo
Example:
- TODO Task1
- Description without marker
- TODO Task 2
- Description
- TODO subtask 2.1
in that case I should catch two rows:
So my current implementation is:
#+BEGIN_QUERY
{
:query [:find (pull ?block [* ])
:in $ ?current-page
:where
[?page :block/name ?current-page]
[?block :block/page ?page]
[?page :block/name ?pagename]
[?block :block/marker ?marker]
[(contains? #{"TODO"} ?marker)]
[?child :block/parent ?block]
[?child :block/marker ?childmarker]
(not [(contains? #{"TODO"} ?childmarker)])
]
:inputs [:current-page]
:view (fn [r] [:pre.code (pprint r)])
}
#+END_QUERY
But the query runs without returning rows
Welcome. Try this:
#+BEGIN_QUERY
{
:query [:find (pull ?block [* ])
:in $ ?current-page
:where
[?page :block/name ?current-page] ; in current page
[?block :block/page ?page] ; any blocks
[?block :block/marker ?marker] ; that have marker
[(contains? #{"TODO"} ?marker)] ; TODO
(not ; but don't have
[?child :block/parent ?block] ; any child
[?child :block/marker ?childmarker] ; with own marker
[(contains? #{"TODO"} ?childmarker)] ; TODO
)
]
:inputs [:current-page]
}
#+END_QUERY
Look like fine for now. Thanks!
In one test it failed, like:
- TODO Task1
- Description without marker
- TODO Task 2
- Description
- TODO subtask 2.1
- desc
- TODO subtask 2.1.1
- TODO subtask 2.2
it also will return subtask 2.1
but shouldn’t.
Can we search recursively?
We can, by using rules:
#+BEGIN_QUERY
{
:query [:find (pull ?block [* ])
:in $ ?current-page %
:where
[?page :block/name ?current-page] ; in current page
[?block :block/page ?page] ; any blocks
[?block :block/marker ?marker] ; that have marker
[(contains? #{"TODO"} ?marker)] ; TODO
(not ; but don't have
(descendant ?d ?block) ; any descendant
[?d :block/marker ?dmarker] ; with own marker
[(contains? #{"TODO"} ?dmarker)] ; TODO
)
]
:inputs [
:current-page
[
[
[descendant ?d ?b]
[?d :block/parent ?b]
]
[
[descendant ?d ?b]
[?d :block/parent ?parent]
(descendant ?parent ?b)
]
]
]
}
#+END_QUERY