Created
January 10, 2012 18:08
-
-
Save pandeiro/1590298 to your computer and use it in GitHub Desktop.
CouchDB type in Clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns noir-couchdb.core | |
(:use [com.ashafa.clutch :only [get-database put-document delete-document | |
get-document database-info all-documents | |
get-view]]) | |
(:require [com.ashafa.clutch.utils :as clutch] | |
[clojure.string :as string]) | |
(:refer-clojure :exclude (conj! assoc! dissoc!))) | |
(defprotocol CouchOps | |
"Defines side-effecting operations on a CouchDB database. | |
All operations return the CouchDB database reference — | |
with the return value from the underlying clutch function | |
added to its :result metadata — for easy threading and | |
reduction usage." | |
(create! [this] | |
"Ensures that the database exists, and returns the database's meta info.") | |
(conj! [this document] | |
"PUTs a document into CouchDB. Accepts either a document map (using an :_id value | |
if present as the document id), or a vector/map entry consisting of a | |
[id document-map] pair.") | |
(assoc! [this id document] | |
"PUTs a document into CouchDB. Equivalent to (conj! couch [id document]).") | |
(dissoc! [this id-or-doc] | |
"DELETEs a document from CouchDB. Uses a given document map's :_id and :_rev | |
if provided; alternatively, if passed a string, will blindly attempt to | |
delete the current revision of the corresponding document.")) | |
(defprotocol CouchView | |
"Defines method(s) for retrieving a CouchDB view" | |
(view [this view-key] | |
"GETs a pre-defined CouchDB view") | |
(add-view [this view-key design view opts] | |
"Registers a view and its options to key")) | |
(defn- with-result-meta [couch result] | |
(vary-meta couch assoc :result result)) | |
(defn- add-view-to-meta [couch view] | |
(assoc-in (meta couch) [:views] view)) | |
(deftype CouchDB [url meta] | |
CouchView | |
(view [this view-key] | |
(meta this)) | |
(add-view [this view-key design view opts] | |
(add-view-to-meta this {view-key (fn [] (get-view url design view opts))})) | |
CouchOps | |
(create! [this] (with-result-meta this (get-database url))) | |
(conj! [this doc] | |
(let [[id doc] (cond | |
(map? doc) [(:_id doc) doc] | |
(or (vector? doc) (instance? java.util.Map$Entry)) doc)] | |
(with-result-meta this (put-document url doc :id id)))) | |
(assoc! [this id document] (conj! this [id document])) | |
(dissoc! [this id] | |
(if-let [d (if (#'com.ashafa.clutch/document? id) | |
id | |
(get this id))] | |
(with-result-meta this (delete-document url d)) | |
(with-result-meta this nil))) | |
clojure.lang.ILookup | |
(valAt [this k] (get-document url k)) | |
(valAt [this k default] (or (.valAt this k) default)) | |
clojure.lang.Counted | |
(count [this] (:doc_count (database-info url))) | |
clojure.lang.Seqable | |
(seq [this] | |
(->> (all-documents url {:include_docs true}) | |
(map :doc) | |
(map #(clojure.lang.MapEntry. (:_id %) %)))) | |
clojure.lang.IMeta | |
(meta [this] meta) | |
clojure.lang.IObj | |
(withMeta [this meta] (CouchDB. url meta))) | |
(defn couch | |
([url] | |
(CouchDB. (assoc (clutch/url url) | |
:username "moi" :password "password") nil)) | |
([url meta] | |
(CouchDB. (assoc (clutch/url url) | |
:username "moi" :password "password") meta))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment