I’ve been playing around with and kicking the tyres of CouchDB for a couple of weeks and I’m truly excited about the project. If I was to use tags to describe CouchDB I’d use the following:
apache, opensource, documents, metadata, database, json, javascript, REST, addressability, horizontal scaling, erlang.
So I found myself at Railscamp UK on the weekend without a ruby+rails topic to really talk about during the presentations part of the camp. I’m still a noob wrt. Rails, you see. Realising that CouchDB is relevant to most web developers because most developers deal with document-based content at some point and that Ruby, Rails, and Erlang are kindda like the current bratpack (in a John Hughes-sense) of computer languages, I thought it would be a great little topic for a 15-minute presentation.
So I thought I share the slides and some of the code I hacked up on the weekend. First of all the slides…
You can play about with some sample code that was expanded upon after the presentation. Here’s a little helper class to interface into CouchDB using JSON and HTTP:
require 'rubygems' require 'httparty' require 'json/pure' require 'find' class CouchHack include HTTParty base_uri 'http://127.0.0.1:5984' format :json def update( path, document ) options = { :body => JSON.generate(document) } puts self.class.put(path, options ) end def get(path) self.class.get(path) end def create(db_path, document ) options = { :body => JSON.generate(document) } self.class.post(db_path, options ) end def define_view(db_path, design_doc_name, views ) document = { "views" => views } options = { :body => JSON.generate(document) } self.class.put("#{db_path}/_design/#{design_doc_name}", options) end end
Once that’s in place you can use the CouchHack class by defining a view like so:
ch = CouchHack.new gem_views = { "small_gems" => { "map" => "function(doc) { if (doc.length < 3000) emit(doc.path, doc) }", }, "large_gems" => { "map" => "function(doc) { if (doc.length > 3000) emit(doc.path, doc) }", } } ch.define_view("/railscamp", "gems", gem_views)
This design document, as is its known in CouchDB parleance, defines two views (think ‘baked queries’), to return a list of small gems – those less than 3000 bytes – and a list of large gems – those larger than 3000 bytes.
So where do these gems come from and how do they end up in CouchDB ? That’s what the next and last little fragment of Ruby code does.
Find.find('/Library/Ruby/Gems/1.8/gems/' ) do |f| if File.file?(f) and f.ends_with?('.rb' ) begin gem_contents = IO.read(f) gem_document = { "path" => f, "length" => gem_contents.length, "content" => gem_contents } ch.create( "/railscamp", gem_document ) rescue Exception => bang puts "Skipping #{f}" end end end
So what happens is that the last little fragment traverses the filesystem starting at /Library/Ruby/Gems/1.8/gems/ and looks for *.rb files. When it finds one it POSTs that whole document including the file length to CouchDB, where it becomes part of the resultset of one of the pre-defined views. These views can be accessed through the following two URLs (assuming the ‘railscamp’ DB was used).
Feel free to post comments and ask questions.
Enjoy.
P.S. and if you get a chance to go to a *camp conference, GO! They’re an amazing format and you’ll learn soooo much!.
Hi Ijonas,
Thanks for putting these up and for introducing us all to CouchDB over the weekend. I’ve already started refactoring some of my Ext MVC framework to fit in with Couch on the backend – should be pretty awesome!
Oh yeah if you ever want your arse kicking at Urban Terror again, you know where to find me
Cheers,
Ed
My pleasure, Ed.
You’re demo of the Ext MVC framework was eye-opening. Certainly changed my opinion of “puny little Javascript” forever. Much appreciated, I learned a great deal.
If you need any help on CouchDB, you know where to find… also the IRC channel #couchdb is excellent and the people involved are more than eager to see CouchDB succeed.
Regs,
Ij.