Skip to content

qx_find commits for fn

RichMorin edited this page Dec 31, 2012 · 17 revisions

Ignored

Query Example: find-commits-for-fn

find-commits-for-fn - list all commits of a function

This example comes from the core.clj file in Devin Walter's nifty codeq-playground.

Problem

You need to identify every commit of a specified function.

Solution

First, we define a few helper rules:

(def
  ^{:doc "http://blog.datomic.com/2012/10/codeq.html"}
  rules
  '[ [ ( file-commits   ?file         ?commit   )     ;; get commits for a file
       ( object-nodes   ?file         ?node     )     ;; by getting its nodes
       [ ?commit        :commit/tree  ?node     ] ]   ;; and their commits

     [ ( object-nodes   ?object       ?node     )     ;; get nodes for an object
       [ ?node          :node/object  ?object   ] ]   ;; by asking for them

     [ ( object-nodes   ?object       ?node     )     ;; get nodes for an object
       [ ?node2         :node/object  ?object   ]     ;; by asking for trees,
       [ ?tree          :tree/nodes   ?node2    ]     ;; getting tree nodes,
       ( object-nodes   ?tree         ?node     ) ]   ;; and their descendants
   ] )

Now, we define the desired function:

(defn find-commits-for-fn
  "list all commits of a function"
  [fq-fn]
  (d/q '[:find ?code_src (min ?date)
         :in $ % ?fn_name
         :where
         [ ?name_ent     :code/name          ?fn_name  ]    ;; get matching name   entities
         [ ?codeq        :clj/def            ?name_ent ]    ;; and matching codeqs
         [ ?codeq        :codeq/code         ?code_ent ]    ;; and matching code   entities
         [ ?code_ent     :code/text          ?code_src ]    ;; and matching code   sources
         [ ?codeq        :codeq/file         ?file_ent ]    ;; and matching file   entities
         ( file-commits  ?file_ent           ?commit   )    ;; get matching commit entities
         [ ?commit       :commit/authoredAt  ?date     ] ]  ;; and matching authoredAt dates
       db rules fq-fn))

The function is used as follows:

(find-commits-for-fn "clojure.core/map")

Discussion

This function assumes that db is a database connection.

Here's a summary of rule use for the query:

file-commits -> object-nodes -> object-nodes (recursively)

See Also

Clone this wiki locally