{:lq/property
 {:query [:find (pull ?b [*])
          :in $ ?prop ?prop-value %
          :where
          [(keyword ?prop) ?prop-k]
          (property ?b ?prop-k ?prop-value)]
  :desc "List all blocks that have property equal to property value"}

 :lq/property-all
 {:query [:find (pull ?b [*])
          :where
          [?b :block/properties _]
          [(missing? $ ?b :block/name)]]
  :desc "List all blocks that have properties"}

 :lq/property-counts
 {:parent :lq/property-all
  :result-transform (fn [result]
                      (->> result
                           (map (fn [m] (zipmap (keys (:block/properties m)) (repeat 1))))
                           (apply merge-with +)
                           (sort-by val >)))
  :desc "Counts for all block properties"}

 :lq/has-property
 {:query [:find (pull ?b [*])
          :in $ ?ks %
          :where
          [(keyword ?ks) ?k]
          (has-property ?b ?k)]
  :desc "List blocks that have given property"}

 :lq/task
 {:query [:find (pull ?b [*])
          :in $ ?markers %
          :where
          (task ?b ?markers)]
  :default-args [#{"TODO" "DOING"}]
  :usage "MARKER [& MARKERS]"
  :args-transform (fn [args]
                    (set (map (comp clojure.string/upper-case name) args)))
  :desc "Todos that contain one of the markers"}

 :lq/content-search
 {:query [:find (pull ?b [*])
          :in $ ?query %
          :where
          (block-content ?b ?query)]
  :desc "Full text search on :block/content"}

 :lq/property-search
 {:query [:find (pull ?b [*])
          :in $ ?prop ?query %
          :where
          [(keyword ?prop) ?prop-k]
          (property ?b ?prop-k ?prop-value)
          [(clojure.string/includes? ?prop-value ?query)]]
  :desc "Full text search on property"}}
