                                                       :my-range ["0" "1"]}]
                                           :attrs []}}))
 
-;; TODO Add loops+merging for :unprocessed-keys (meta) and :unprocessed-items
-
-;; BatchGetItem will return a partial result if the response size limit is
-;; exceeded, the table's provisioned throughput is exceeded, or an internal
-;; processing failure occurs. If a partial result is returned, the operation
-;; returns a value for UnprocessedKeys . You can use this value to retry the
-;; operation starting with the next item to get.
-
-;; * The UnprocessedKeys value is in the same form as RequestItems, so the value
-;; can be provided directly to a subsequent BatchGetItem operation. For more
-;; information, see RequestItems in the Request Parameters section.
-
-;; Typically, you would call BatchWriteItem in a loop. Each iteration would
-;; check for unprocessed items and submit a new BatchWriteItem request with
-;; those unprocessed items until all items have been processed.
+(defn- merge-unprocessed
+  [creds more-f last-result]
+  (loop [{:keys [items unprocessed consumed-capacity]} last-result]
+    (when (seq unprocessed) (println "REPROCESSING!: " unprocessed))
+    (if-not (seq unprocessed)
+      (if items
+        (with-meta items {:consumed-capacity consumed-capacity})
+        last-result)
+
+      (let [{items* :items unprocessed* :unprocessed
+             consumed-capacity* :consumed-capacity}
+            (more-f creds unprocessed)]
+
+        (recur (merge {:unprocessed       unprocessed*
+                       :consumed-capacity (when consumed-capacity
+                                            (+ consumed-capacity
+                                               consumed-capacity*))}
+                      (when (or items items*)
+                        {:items (into (or items []) items*)})))))))
+
+(defn- batch-get-item* [creds raw-request]
+  (merge-unprocessed creds batch-get-item*
+   (as-map
+    (.batchGetItem (db-client creds)
+      (doto (BatchGetItemRequest.) ; {table-str KeysAndAttributes}
+        (.setRequestItems raw-request))))))
 
 (defn batch-get-item
   "Retrieves a batch of items in a single request.

            com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
            java.nio.ByteBuffer))

;;;; Connections

(def ^:private db-client*

(def db-item->clj-item (partial utils/keyword-map db-val->clj-val))
(def clj-item->db-item (partial utils/name-map    clj-val->db-val))

(defn- cc-units [^ConsumedCapacity cc] (some-> cc (.getCapacityUnits)))

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

(defmacro ^:private am-item-result [result get-form]
  `(when-let [get-form# ~get-form]
     (with-meta (db-item->clj-item get-form#)
       {:consumed-capacity (cc-units (.getConsumedCapacity ~result))})))

(defmacro ^:private am-query|scan-result [result & [meta]]
  `(let [result# ~result]
     (with-meta (mapv db-item->clj-item (.getItems result#))
       (merge {:count (.getCount result#)
               :consumed-capacity (cc-units (.getConsumedCapacity result#))
               :last-prim-kvs (as-map (.getLastEvaluatedKey result#))}
              ~meta))))

