             "must be expressable as EDN")
     cand))
 
+(defn add-bin! 
+  "Adds a binary key and value to an open DB.  If the key exists, then
+there is no change to the DB.  
+
+Returns `true` if it succeeds, `false` on an error."
+  [^DB db ^bytes key ^bytes value]
+  (.add db key value))
+
+(defn add-edn!
+  "Adds a string key and a Clojure data structure to an open DB.  It
+uses `add-bin!` to do the heavy-lifting (which there isn't any).  If 
+the key already exists in the database, then there is no change.
+
+Returns `true` on success, `false` on an error."
+  [^DB db ^String key value]
+  (add-bin! db (.getBytes key)
+            (bytes (.getBytes (edn-str value)))))
+
+(defn get-bin!
+  "Gets binary data from an open DB using a binary key.
+
+Returns a byte array on success, 'nil' if it errors."
+  [^DB db ^bytes key]
+  (.get db key))
+
+(defn get-edn!
+  "Gets parsed Clojure data from an open DB using a string key.
+
+Returns Clojure on success, 'nil' if it errors."
+  [^DB db ^String key]
+  (if-let [^bytes result (get-bin! db (.getBytes key))]
+    (-> (String. result)
+        edn/read-string)))

          "dbs-and-specs must not be empty.")
  (assert (even? (count dbs-and-specs))
          "dbs-and-specs must be of even length")
  (if (= 2 (length dbs-and-specs))
    `(with-db ~(vec dbs-and-specs) ~@body)
    `(with-db ~(vec (take 2 dbs-and-specs))
       (with-dbs ~(drop 2 dbs-and-specs)

initial parameters, with simlar syntax to `let`.

An example would be merging hashes of people and animals together to see
who owns which pet, assuming that Ronin is being used to drive a graph 
database:

    (with-dbs [merged {:type :cache-hash :modes [:create :write :read]}
               people (assoc people-spec :modes [:read])
               animals (assoc animal-spec :modes [:read])]
      (merge-dbs! :add merged people animals)
