Skip to content
RichMorin edited this page Dec 31, 2012 · 8 revisions

Ignored

Query Example: commit-dates

commit-dates - list initial commit date for a specified function

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

Problem

You need to find out when a specified function was first committed.

Solution

First, we define a few helper rules:

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

     [ ( 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 commit-dates
  "list initial commit date for fn_name"
  [fn_name]
  (map first
       (d/q '[:find (min ?date) ?sha
              :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/sha            ?sha      ]    ;; and matching SHAs (checksums)
              ( codeq-commits  ?codeq               ?commit   )    ;; get matching commit entities
              [ ?commit        :commit/committedAt  ?date     ] ]  ;; and matching committedAt dates
            db rules fn_name)))

The function is used as follows:

(commit-dates "clojure.core/pmap")

Discussion

This function assumes that db is a database connection.

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

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

See Also

Clone this wiki locally