anchor.diff:      :initarg :server
       :reader database-server)
      (name
  -    :initarg :name
       :reader database-name))
     (:documentation
      "Base database class. These objects represent the information required in order to communicate
      with a particular CouchDB database."))
  +
  +(defun url-encode (string)
  +  ;; TODO - escape other characters.
  +  (with-output-to-string (s)
  +    (loop for char across string
  +       do (case char
  +            (#\/ (princ "%2F" s))
  +            (otherwise (write-char char s))))))
  +
  +(defmethod initialize-instance :after ((db standard-database) &key name)
  +  (setf (slot-value db 'name) (url-encode name)))
   
   (defmethod print-object ((db standard-database) stream)
     (print-database db stream))
  
positive.code: ;;; Basic database API
  ;;;
  
  ;; TODO - CouchDB places restrictions on what sort of URLs are accepted, such as everything having
  ;;        to be downcase, and only certain characters being accepted. There is also special meaning
  ;;        behing the use of /, so a mechanism to escape it in certain situations would be good.
  
  (defun url-encode (uri)
    (cl-ppcre:regex-replace-all "/" uri "%2F"))
  
  ;; Database protocol
  (defgeneric make-db-object (server name)
    (:documentation
  
negative.code:   "Sends a CouchDB request to DB."
    (apply #'couch-request (database-server db) (strcat (database-name db) "/" uri) all-keys))
  
  (defmacro handle-request ((result-var db uri &rest db-request-keys &key &allow-other-keys)
                            &body expected-responses)
    "Provides a nice interface to the relatively manual, low-level status-code checking that Chillax
  uses to understand CouchDB's responses. The format for EXPECTED-RESPONSES is the same as the CASE
  macro: The keys should be either keywords, or lists o keywords (not evaluated), which correspond to
  