       (apply vector (format "(%s)" sql) params)))
 
 (defn- alias-subqueries
+  "Produce distinct aliases for a list of queries, suitable for a join
+operation."
   [queries]
   (let [ids (range (count queries))]
     (map #(format "%s resources_%d" %1 %2) queries ids)))
 
 (defmethod compile-query->sql "and"
+  "Join a set of predicates together with an 'and' relationship, performing an
+intersection (via natural join)."
   [db [op & terms]]
   {:pre [(every? vector? terms)]
    :post [(string? (first %))

    (apply vector query params)))

(defmethod compile-query->sql "or"
  [db [op & terms]]
  {:pre [(every? vector? terms)]
   :post [(string? (first %))

;; ## Request Format
;;
;; The single available route is `/resources?query=<query>`. The `query`
;; parameter is a JSON array of query predicates in prefix form.
;;
;; ### Predicates
;;
;; #### =
;;
;; Resources tagged with "foo" (irrespective of other tags):
;;
;;     ["=" "tag" "foo"]
;;
;; Resources for the node "foo.example.com":
;;
;;     ["=" ["node" "<this value is ignored>"] "foo.example.com"]
;;
;; Resources whose owner parameter is "joe":
;;
;;     ["=" ["parameter" "owner"] "joe"]
;;
;; Resources whose title is "/etc/hosts"; "title" may be replaced with any legal column of the `resources` table, to query against that column:
;;
;;     ["=" "title" "/etc/hosts"]
;;
;; #### and
;;
;; Resources whose owner is "joe" and group is "people":
;;
;;     ["and" ["=" ["parameter" "owner"] "joe"]
;;            ["=" ["parameter" "group"] "people"]]
;;
;; #### or
;;
;; Resources whose owner is "joe" or "jim":
;;
;;     ["or" ["=" ["parameter" "owner"] "joe"]
;;           ["=" ["parameter" "owner"] "jim"]]
;;
;; #### not
;;
;; Resources whose owner is not "joe" AND is not "jim":
;;
;;     ["not" ["=" ["parameter" "owner"] "joe"]
;;            ["=" ["parameter" "owner"] "jim"]]
;;
;; ## Response Format
;;
;; The response is a list of resource objects, returned in JSON form. Each
;; resource object is a map of the following form:
;;
;;     {:hash       "the resource's unique hash"
;;      :type       "File"
;;      :title      "/etc/hosts"
;;      :exported   "true"
;;      :sourcefile "/etc/puppet/manifests/site.pp"
;;      :sourceline "1"
;;      :parameters {<parameter> <value>
;;                   <parameter> <value>
;;                   ...}}

(ns com.puppetlabs.cmdb.query.resource
  (:require [com.puppetlabs.utils :as utils]
            [clojure.contrib.logging :as log]
