Every repository with this icon (
Every repository with this icon (
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




