public
Fork of chuyeow/activecouch
Description: ActiveCouch is a simple, convenient, Ruby-idiomatic wrapper for CouchDB

ActiveCouch Migrations

Introduction

CouchDB has the concept of views which are used to query and report on CouchDB databases. There are two types of views – permanent and temporary (btw this information is listed in more detail here.) At present, since the performance penalty of temporary views is not known (other than it is more expensive than a query done on a permanent view), the author has decided that CouchDB will only support permanent views.

Enter ActiveCouch Migrations, as this will give a nice elegant way

  • to define views in Ruby
    • which requires a Gisele Bundchen-esque DSL
  • to add views to a CouchDB database
    • which requires translation of the Gisele Bundchen-esque DSL to Ugly Betty-esque javascript
  • removing views (by going back a migration)
    • which requires deleting view documents upto the required version number
  • changing
    • not sure yet how this will work, but I think I have to use _rev field which is present in all ActiveCouch? documents. Maybe for now, only support adding and deleting views?

DSL Design


class ViewName < ActiveCouch::Migration
  define :view_name, :for => :database_name do
    with_key :name
    # Contents of filter to be in JS.
    with_filter 'doc.name == "John"'
    # The include_attributes option will only accept ActiveCouch attributes for now
    # associations-support for later.
    # Attributes to return when the view returns results
    include_attributes :name, :age, :sex
  end
end

This will translate into


function(doc) {
  if(doc.name == "John") {
    map(doc.name, {name: doc.name, age: doc.age, sex: doc.sex});
  }
}

This will create a very simple view, named ‘view_name’ for the database ‘database_name’ with the key ‘name’ and filter ‘doc.name == “John”’. The convention will be for views to start with the words by_ . This is so that the ActiveCouch?::Base class can have a find_by_xxx method which will directly map to the by_xxx view.

The define method of ActiveCouch?::Migration will accept the name of the view as the first argument and a hash as the second argument. The name of the view can be omitted – if omitted, ActiveCouch?::Migration will guess the name of the view from the class which inherits it. So if you define a migration as listed below,


class ByName < ActiveCouch::Migration
  define :for => :database_name do
    with_key :name
    # Contents of filter to be in JS.
    with_filter 'doc.name == "John"'
    # The include_attributes option will only accept ActiveCouch attributes for now
    # associations-support for later.
    # Attributes to return when the view returns results
    include_attributes :name, :age, :sex
  end
end

it will assign the view name to be by_name

If you need a handy script which will do the migrations for you in Rails, you can use this little snippet (This will be bundled along with a future release, so bear with this until then). The script assumes you have the migrations defined in RAILS_ROOT/app/couch_db_views/


#!/usr/bin/env ruby

if(migration_name = ARGV[0]).nil?
  puts "You must specify the migration class you want to migrate"; exit
end

# Since the loading of the Rails env takes some time, first check if the user has given a
# view to migrate first, before loading it
require File.dirname(__FILE__) + '/../config/environment'

unless (migration = Object.const_get(migration_name)).nil?
  # TODO: Must get hostname from a config file
  migration_status = ActiveCouch::Migrator.migrate('http://localhost:5984/', migration)
  if(migration_status == true)
    puts "Migration of #{migration_name} is successful." 
  else
    puts "There was an error in the migration, please check the CouchDB logs." 
  end
else
  puts "Have you defined your view? They should go in app/couch_db_views/" 
end

Last edited by arunthampi, 5 months ago
Versions: