       (doto (BatchGetItemRequest.)
         (.setRequestItems (batch-request-items requests))))))
 
-(defn- delete-request [item]
-  (doto (DeleteRequest.)
-    (.setKey (clj-item->db-item item))))
-
-(defn- put-request [item]
-  (doto (PutRequest.)
-    (.setItem
-      (into {}
-        (for [[k v] item]
-          {(name k) (clj-val->db-val v)})))))
-
-(defn- write-request [action item]
-  (let [wr (WriteRequest.)]
-    (case action :delete (.setDeleteRequest wr (delete-request item))
-                 :put    (.setPutRequest    wr (put-request    item)))
-    wr))
+(defn- put-request    [i] (doto (PutRequest.)    (.setItem (clj-item->db-item i))))
+(defn- delete-request [i] (doto (DeleteRequest.) (.setKey  (clj-item->db-item i))))
+(defn- write-request  [action item]
+  (case action
+    :delete (doto (WriteRequest.) (.setDeleteRequest (delete-request item)))
+    :put    (doto (WriteRequest.) (.setPutRequest    (put-request    item)))))
 
 (defn batch-write-item
-  "Execute a batch of Puts and/or Deletes in a single request.
-   DynamoDB limits apply - 25 items max. No transaction
-   guarantees are provided, nor conditional puts.
-
-   Example:
+  "Executes a batch of Puts and/or Deletes in a single request.
+   Limits apply, Ref. http://goo.gl/Bj9TC. No transaction guarantees are
+   provided, nor conditional puts.
+
    (batch-write-item creds
-     [:put :users {:user-id 1 :username \"sally\"}]
-     [:put :users {:user-id 2 :username \"jane\"}]
-     [:delete :users {:hash-key 3}])"
+     [:put    :users {:user-id 1 :username \"sally\"}]
+     [:put    :users {:user-id 2 :username \"jane\"}]
+     [:delete :users {:user-id 3}])"
   [creds & requests]
   (as-map
     (.batchWriteItem (db-client creds)


;;;; TODO
;; * Finish up code walk-through.
;; * Go through Rotary PRs, non-PR forks.
;; * README docs.
;; * Benchmarks.
;; * Further tests.
;; * Parallel scans.
;; * Async API.
;; * Auto throughput adjusting.

;;;; API - exceptions


              (ExpectedAttributeValue. (clj-val->db-val %)))
     expected)))

(defn- keys-and-attrs "Returns a new KeysAndAttributes object."
  [{:keys [key vals attrs consistent?] :as request}]
  (doto (KeysAndAttributes.)
    (.setKeys (for [v vals] {(name key) (clj-val->db-val v)}))
    (.setAttributesToGet (when attrs (mapv name attrs)))
    (.setConsistentRead  consistent?)))

(defn- batch-request-items
  "{<table> <request> ...} -> {<table> KeysAndAttributes> ...}"
  [requests]
  (into {} (for [[table request] requests]
             [(name table) (keys-and-attrs request)])))

;;;; Coercion - objects

(defprotocol AsMap (as-map [x]))
