Cushion: A slim CouchDB client
Cushion is a Ruby client for accessing CouchDB servers that’s light on the extras and heavy on the syntatical sugar.
Credit goes to CouchRest (github.com/jchris/couchrest/tree/master) for the inspiration.
Getting Started
# myapp.rb
require 'cushion'
db = Cushion!(:mydb)
Document Basics
Storing documents is simple. Just supply a hash of attributes. Leave out the _id attribute if you want to use an auto-generated UUID. Set the _rev attribute to update a document:
db.store("baz" => "bat")
# => {"ok"=>true, "id"=> "bdd39a3f9a1e5894d3d1283aa0d0f53f", "rev"=> "2699240268"}
response = db.store("_id" => "mydoc", "foo" => "bar")
# => {"ok"=>true, "id"=>"mydoc", "rev"=>"882534292"}
db.store("_id" => "mydoc", "foo" => "baz", "_rev" => response['rev'])
# => {"ok"=>true, "id"=>"mydoc", "rev"=>"3617508982"}
Fetching documents is just as simple.
db.key?("mydoc") # => true
db.fetch("mydoc") # => {"_id"=>"mydoc", "_rev"=>"3617508982", "foo"=>"baz"}
db.fetch("bogusid") # => raises RestClient::ResourceNotFound
# Use etags to perform a conditional GET
db.fetch("mydoc", :etag => cur_rev) # => raises RestClient::NotModified
Store attachments inline or via CouchDB’s standalone attachment API. The standalone method accepts both IO objects and strings:
Inline:
db.store("_id" => "hasfiles", ..., "_attachments" => {
"foo.txt" => {
"content_type" => "text/plain",
"data" => "Hello World!"
}})
Standalone:
res = @db.store("_id" => "savemefirst", ...)
db.attach("savemefirst", "foo.txt", "Hello World!", :rev => res['rev'],
:content_type => "text/plain")
# => Foo now contains an attachment hash similar to the above example
Fetch attachment data:
db.fetch("savemefirst", "foo.txt") # => "Hello World!"
Cushion returns parsed JSON by default. In those cases where you need the raw JSON string, simply set an accept header:
db.fetch("mydoc", :headers => { :accept => "text/plain" })
# => "{\"_id\":\"mydoc\",\"_rev\":\"3617508982\",\"foo\":\"baz\"}\n"
The technique above works for nearly every Cushion request method.
Document Macros
You can use CouchDB’s bulk docs feature to create, update and delete many documents at once:
docs = [
{ "_id" => "0", "_rev" => "123456", "_deleted" => true }, #=> Delete
{ "_id" => "1", "_rev" => "32486671", "foo" => "bar" }, #=> Update
{ "_id" => "2", "baz" => "bat" } #=> Create
]
db.bulk(docs) # => returns a hash of updated documents
db.bulk(docs, :delete => true) # => deletes the selected docs
Documents may be copied within the same database.
db.copy("mydoc", "new_doc")
# => {"ok"=>true, "id"=>"new_doc", "rev"=> ...}
db.copy("mydoc", "existing_doc", :dest_rev => ...)
# => overwrites the existing doc
Attachments may also be copied.
db.copy_attachment("mydoc", "foo.txt", "bar.txt")
# => copies an attachment within the same doc
db.copy_attachment("mydoc", "foo.txt", "bar.txt", :dest_id => 'existing_doc', :dest_rev => ...)
# => copies an attachment to an existing doc
Creating Views
Querying Views
Query regular views by passing in the design doc name and view name along with an optional hash of parameters.
db.view("people/by_first_name", :key => "gomer")
db.view("foo/bar", :keys => ["a", "b", "c"])
db.view(:all)
You may also query the database using temporary views.
temp_view = { :map => "function(doc){emit(doc.status,null)}" }
db.view(:temp, :funcs => temp_view, :key => "verified")
Temp view queries are slow, so they should only be used as a convenience during development. Whenever possible you should query against saved views.
Servers and Databases
The server location defaults to 127.0.0.1:5984, so you may omit the host when initializing a server if you are satisfied with the default.
Display various bits of server metadata as follows:
server = Cushion.server :uri => 'http://myhost:5984'
server.info #=> welcome message
server.all_dbs #=> all dbs available
server.active_tasks #=> running tasks (e.g., replication or compaction)
server.config #=> server config
server.restart #=> restart the server
server.stats #=> detailed runtime stats
Cushion::Server can also replicate local and remote databases:
server.replicate("db1", "db2")
server.replicate("db1", "http://host2:5984/bar")
Creating database instances:
-
top level methods
-
options
DB Operations:
db.create
db.delete
db.compact
Cushion::Document
Tricks
Use the #headers method to obtain response headers on any request:
db.fetch("mydoc").headers
# => {:server=>"CouchDB/0.9.0a (Erlang OTP/R12B)", :etag=>"\"3617508982\"",
:date=>"Fri, 06 Mar 2009 10:21:59 GMT", :content_type=>"application/json",
:content_length=>"48", :cache_control=>"must-revalidate"}