zdzolton / cambric

Opinionated management and usage of CouchDB from your Ruby apps.

This URL has Read+Write access

name age message
file .document Thu May 14 12:40:51 -0700 2009 Initial commit to cambric. [zdzolton]
file .gitignore Thu May 14 12:40:51 -0700 2009 Initial commit to cambric. [zdzolton]
file LICENSE Thu May 14 12:40:51 -0700 2009 Initial commit to cambric. [zdzolton]
file README.rdoc Wed Oct 28 18:30:49 -0700 2009 updated documentation [zdzolton]
file Rakefile Tue Aug 25 14:05:21 -0700 2009 changed CouchRest dependency to Matt Aimonetti'... [zdzolton]
file VERSION Thu Nov 05 17:46:57 -0800 2009 Version bump to 0.7.4 [zdzolton]
file cambric.gemspec Thu Nov 05 17:46:57 -0800 2009 Regenerated gemspec for version 0.7.4 [zdzolton]
directory lib/ Thu Nov 05 17:43:10 -0800 2009 simplify configurator code and allow for userna... [zdzolton]
directory spec/ Tue Sep 01 15:16:18 -0700 2009 added basic support for priming changes in view... [zdzolton]
README.rdoc

Cambric

Mildly opinionated management and usage of CouchDB from your Ruby apps.

Cambric supports applications that wish to use multiple CouchDB databases/hosts, in a manner that wont muck up your application code. Moreover, it encourages you to use one design document per database used by the application.

BTW, there’s nothing specific to Rails in how this works. (^_-)

Usage

1) Configure the Cambric instances:

  Cambric.configure do |config|
    config.design_doc_name = 'twitter-clone'
    config.environment = ENV['RAILS_ENV']

    config.databases = {
      :users => {
        :development => 'http://127.0.0.1:5984/users-development',
        :test => 'http://127.0.0.1:5984/users-test',
        :production => 'http://prod.server:5984/users'
      },
      :tweets => {
        :development => 'http://127.0.0.1:5984/tweets-development',
        :test => 'http://127.0.0.1:5984/tweets-test',
        :production => 'http://prod.server:5984/tweets'
      }
    }
  end

2) Use one of the following methods:

  Cambric.prepare_database  # Creates databases for the configured environment
                            # and pushes up their design docs.

  Cambric.prepare_database! # Or, the bang method forcibly recreates your
                            # databases for the configured environment.

3) Interact with CouchRest::Database instances:

  tweet_db = Cambric[:tweets]

  # Just like normal...
  tweet_db.save_doc :author => 'marbles',
                    :message => 'Is this pork or beef, @Randy?',
                    :followers => ['randy','zdzolton','trevorturk'],
                    :created_at => Time.now

  # Except, you do NOT need to re-specify the design doc name when
  # calling CouchRest::Database#view —since you're only using one!
  tweet_db.view 'by_follower_and_created_at', :limit => 1

  # Also, we can auto-cast doc from map-only views for you!
  tweet_db.get_docs_from_view :by_follower_and_created_at, :cast_as => 'type'
  # Or:
  tweet_db.get_docs_from_view :by_follower_and_created_at, :cast_as => Tweet

4) Write unit tests for your JavaScript map-reduce functions:

  class CambricViewTest < ActiveSupport::TestCase
    include Cambric::TestHelpers

    test "should map a user to be keyed by who he follows" do
      kv_pairs = execute_map :users,                                               # Database name
                             :followers,                                           # View name
                             '_id' => 'poddle', 'following' => ['jack', 'russel']  # Document attributes

      assert_equal 2, kv_pairs.size
      assert_equal 'jack',   kv_pairs[0]['key']
      assert_equal 'poddle', kv_pairs[0]['value']
      assert_equal 'russel', kv_pairs[1]['key']
      assert_equal 'poddle', kv_pairs[1]['value']
    end

    test "should reduce to a count of followers for a user" do
      count = execute_reduce :users,                         # Database name
                             :followers,                     # View name
                             :values => ['poddle', 'larry']  # :keys don't matter for this reduce
      assert_equal 2, count
    end

    test "should re-reduce counts of followers for a user" do
      count = execute_reduce :users,                # Database name
                             :followers,            # View name
                             :values => [2, 5, 1],
                             :rereduce => true      # defaults to false
      assert_equal 8, count
    end

  end

5) Push view/design doc changes to CouchDB:

  Cambric.push_design_docs

  # Alternatively, you can just call this, since it wont create
  # your database, if they already exist:
  Cambric.prepare_database

  # Now for the real trick! This invocation will block until
  # your changed design docs have primed their views:
  Cambric.prime_view_changes_in_temp

Installation

  • Install gems:

    $ sudo gem install couchrest-couchrest zdzolton-cambric

  • Configure Rails:
    • create a config/initializers/cambric.rb file as follows:
        Cambric.configure do |config|
          config.design_doc_name = 'YOUR_APP_NAME'
          config.environment = RAILS_ENV
      
          config.databases = {
            :YOUR_DB_NAME => {
              :development => "http://localhost:5984/YOUR_DB_NAME-development",
              :test => "http://localhost:5984/YOUR_DB_NAME-test"
            },
            :YOUR_OTHER_DB => {
              :development => "http://localhost:5984/YOUR_OTHER_DB-development",
              :test => "http://localhost:5984/YOUR_OTHER_DB-test"
            }
          }
        end
      
        ActionController::Dispatcher.to_prepare(:cambric) do
          case RAILS_ENV
          when 'test'
            Cambric.prepare_databases!
          when 'production'
            # Let's not automagically do anything!
          else
            Cambric.prepare_databases
          end
        end
      
    • create a couchdb directory within your project:
        $ cd /your/app/root
        $ mkdir -p ./couchdb/your_db/views/some_view_name
      

Copyright

Copyright © 2009 Zachary Zolton. See LICENSE for details.