Skip to content

Commit

Permalink
Cleaning up for v0.2.0 release. Added find_from_url and count_all met…
Browse files Browse the repository at this point in the history
…hods to ActiveCouch::Base. Moved ActiveCouch::Exporter to be under lib/support
  • Loading branch information
Arun Thampi authored and Arun Thampi committed Oct 22, 2008
1 parent 24c2644 commit 38b50ec
Show file tree
Hide file tree
Showing 16 changed files with 184 additions and 130 deletions.
16 changes: 3 additions & 13 deletions README
Expand Up @@ -6,7 +6,7 @@ With ActiveCouch, you can easily save, query, delete documents to/from a CouchDB

Why?
----
As they say, necessity is the mother of invention. And as they also say, death before inconvenience. Our company, Bezurk (http://www.bezurk.com) is experimenting with CouchDB as we have a need for a document-model to store vast amounts of information, and we needed a convenience mapper in our favourite language, in order to use CouchDB elegantly. Since, the Rubyists here at Bezurk are already very familiar with ActiveRecord semantics, care has been taken to ensure that ActiveCouch resembled it in many ways.
As they say, necessity is the mother of invention. And as they also say, death before inconvenience. Our company, Wego (http://www.wego.com) has been using CouchDB for the past six months now, as we have a need for a document-model to store vast amounts of information, and we needed a convenience mapper in our favourite language, in order to use CouchDB elegantly. Since, the Rubyists here at Wego are already very familiar with ActiveRecord semantics, care has been taken to ensure that ActiveCouch resembled it in many ways.

Contributors
------------
Expand All @@ -20,19 +20,9 @@ Requirements
- rubygems 0.9.4 (http://rubygems.org)
- JSON gem (http://json.rubyforge.org) [Used for JSON encoding/decoding]
- RSpec gem (http://rspec.rubyforge.org) [Used to run specs]
- CouchDB 0.7.x (alpha) or 0.8.0 and upwards (http://incubator.apache.org/couchdb/community/code.html) [Some specs require running CouchDB at localhost:5984]
- CouchDB 0.8.0 and upwards (http://incubator.apache.org/couchdb/community/code.html) [Some specs require running CouchDB at localhost:5984]

Important Notice
----------------

- If you are running specs against the 'alpha' versions of CouchDB, i.e. pre 0.8.0 versions, please set the environment variable COUCHDB_IS_ALPHA to true

In bash, this is achieved like so:

% export COUCHDB_IS_ALPHA=true

- Also, for all migrations, if you need to run them against 'alpha' versions of CouchDB, i.e. pre-0.8.0, please us pass the :is_alpha => true variable as part of the define block

Refer spec/migration/view_js_spec.rb

We would also recommend installing ZenTest (http://www.zenspider.com/ZSS/Products/ZenTest/) which provides a very convenient way to run specs.
ActiveCouch v0.2.0 does not support pre-0.8.0 versions of CouchDB
5 changes: 0 additions & 5 deletions ROADMAP

This file was deleted.

5 changes: 0 additions & 5 deletions STATUS

This file was deleted.

2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.1.95
0.2.0
31 changes: 31 additions & 0 deletions lib/active_couch/base.rb
Expand Up @@ -354,6 +354,22 @@ def find(*arguments)
end
end

# Retrieves one or more object(s) from a CouchDB database, based on the search
# parameters given. This method is similar to the find_by_sql method in
# ActiveRecord, in a way that instead of using any conditions, we use a raw
# URL to query a CouchDB view.
#
# Example:
# class Person < ActiveCouch::Base
# has :name
# end
#
# # This returns a single instance of an ActiveCouch::Base subclass
# people = Person.find_from_url("/people/_view/by_name/by_name?key=%22Mclovin%22")
def find_from_url(url)
instantiate_collection(connection.get(url))
end

# Retrieves the count of the number of objects in the CouchDB database, based on the
# search parameters given.
#
Expand All @@ -371,6 +387,21 @@ def count(search_params = {})
JSON.parse(result)['total_rows'].to_i
end

# Retrieves the count of the number of objects in the CouchDB database, irrespective of
# any search criteria
#
# Example:
# class Person < ActiveCouch::Base
# has :name
# end
#
# # This returns the count of the number of objects
# people_count = Person.count_all
def count_all
result = connection.get("/#{database_name}")
JSON.parse(result)['doc_count'].to_i
end

# Initializes a new subclass of ActiveCouch::Base and saves in the CouchDB database
# as a new document
#
Expand Down
3 changes: 2 additions & 1 deletion lib/active_couch/support.rb
@@ -1,2 +1,3 @@
require 'active_couch/support/inflector'
require 'active_couch/support/extensions'
require 'active_couch/support/extensions'
require 'active_couch/support/exporter'
Expand Up @@ -6,7 +6,6 @@ class Exporter
class << self # Class methods
def export(site, view, opts = {})
existing_view = {}

if view.name.nil? || (view.database.nil? && opts[:database].nil?)
raise ActiveCouch::ViewError, "Both the name and the database need to be defined in your view"
end
Expand All @@ -30,7 +29,6 @@ def export(site, view, opts = {})

def delete(site, view, opts = {})
rev = nil

if view.name.nil? || (view.database.nil? && opts[:database].nil?)
raise ActiveCouch::ViewError, "Both the name and the database need to be defined in your view"
end
Expand All @@ -45,15 +43,15 @@ def delete(site, view, opts = {})
# http://#{host}:#{port}/activecouch_test/_design/by_name.
response = conn.delete("/#{database_name}/_design/#{view.name}?rev=#{rev}")
if response.code =~ /20[0,2]/
true # 201 = success
true # 20[0,2] = success
else
raise ActiveCouch::ViewError, "Error deleting view - got HTTP response #{response.code}"
end
end

def exists?(site, name)
conn = Connection.new(site)
response = conn.get("/#{name}")
response = conn.get("#{name}")
response
rescue ActiveCouch::ResourceNotFound
false
Expand Down
3 changes: 1 addition & 2 deletions lib/active_couch/views.rb
@@ -1,3 +1,2 @@
require 'active_couch/views/errors.rb'
require 'active_couch/views/view.rb'
require 'active_couch/views/exporter.rb'
require 'active_couch/views/view.rb'
29 changes: 29 additions & 0 deletions spec/base/count_all_spec.rb
@@ -0,0 +1,29 @@
require File.dirname(__FILE__) + '/../spec_helper.rb'

describe "ActiveCouch::Base #count_all method with multiple documents in the CouchDB database" do
before(:each) do
class Person < ActiveCouch::Base
site 'http://localhost:5984'

has :first_name
has :last_name
end

# Create the database first
ActiveCouch::Exporter.create_database('http://localhost:5984', 'people')
# Save two objects
Person.create(:last_name => 'McLovin', :first_name => 'Seth')
Person.create(:last_name => 'McLovin', :first_name => 'Bob')
end

after(:each) do
# Delete the database last
ActiveCouch::Exporter.delete_database('http://localhost:5984', 'people')
Object.send(:remove_const, :Person)
end

it "should find all objects in the database when find method is sent the param :all" do
count = Person.count_all
count.should == 2
end
end
14 changes: 6 additions & 8 deletions spec/base/count_spec.rb
@@ -1,7 +1,5 @@
require File.dirname(__FILE__) + '/../spec_helper.rb'

IS_ALPHA = ENV['COUCHDB_IS_ALPHA'] == 'true'

describe "ActiveCouch::Base #count method with just simple attributes" do
before(:each) do
# Define the model
Expand All @@ -11,7 +9,7 @@ class Person < ActiveCouch::Base
end
# Define the view
class ByName < ActiveCouch::View
define :for_db => 'people', :is_alpha => IS_ALPHA do
define :for_db => 'people' do
with_key 'name'
end
end
Expand All @@ -29,18 +27,18 @@ class ByName < ActiveCouch::View
Object.send(:remove_const, :Person)
end

it "should respond to the find method" do
it "should respond to the count method" do
Person.should respond_to(:count)
end

it "should return an array with one Person object in it, when sent method find with parameter :all" do
it "should return an array with one Person object in it, when sent method count with search parameters" do
count = Person.count(:params => {:name => 'McLovin'})
count.should == 1
end
end


describe "ActiveCouch::Base #find method with multiple documents in the CouchDB database" do
describe "ActiveCouch::Base #count method with multiple documents in the CouchDB database" do
before(:each) do
class Person < ActiveCouch::Base
site 'http://localhost:5984'
Expand All @@ -51,7 +49,7 @@ class Person < ActiveCouch::Base

# Define the view
class ByLastName < ActiveCouch::View
define :for_db => 'people', :is_alpha => IS_ALPHA do
define :for_db => 'people' do
with_key 'last_name'
end
end
Expand All @@ -70,7 +68,7 @@ class ByLastName < ActiveCouch::View
Object.send(:remove_const, :Person)
end

it "should find all objects in the database when find method is sent the param :all" do
it "should count all objects in the database when count method is sent with valid search parameters" do
count = Person.count(:params => {:last_name => 'McLovin'})
count.should == 2
end
Expand Down
45 changes: 45 additions & 0 deletions spec/base/find_from_url_spec.rb
@@ -0,0 +1,45 @@
require File.dirname(__FILE__) + '/../spec_helper.rb'

describe "ActiveCouch::Base #find method with multiple documents in the CouchDB database" do
before(:each) do
class Person < ActiveCouch::Base
site 'http://localhost:5984'

has :first_name
has :last_name
end

# Define the migration
class ByLastName < ActiveCouch::View
define :for_db => 'people' do
with_key 'last_name'
end
end
# Create the database first
ActiveCouch::Exporter.create_database('http://localhost:5984', 'people')
# Create a view
ActiveCouch::Exporter.export('http://localhost:5984', ByLastName)
# Save two objects
Person.create(:last_name => 'McLovin', :first_name => 'Seth')
Person.create(:last_name => 'McLovin', :first_name => 'Bob')
end

after(:each) do
# Delete the database last
ActiveCouch::Exporter.delete_database('http://localhost:5984', 'people')
Object.send(:remove_const, :Person)
end

it "should find all objects in the database when find_from_url method is used" do
people = Person.find_from_url("/people/_view/by_last_name/by_last_name?key=%22McLovin%22")
# Check if it is an array and if the size is 2
people.class.should == Array
people.size.should == 2
# The id's and rev's for all the objects must not be nil
people.each do |p|
p.id.should_not == nil
p.rev.should_not == nil
end
end

end
36 changes: 36 additions & 0 deletions spec/exporter/delete_spec.rb
@@ -0,0 +1,36 @@
require File.dirname(__FILE__) + '/../spec_helper.rb'

require 'net/http'
require 'uri'

describe ActiveCouch::Exporter, "#export twice (that actually connects to a CouchDB server)" do
before(:each) do
class ByFace < ActiveCouch::View
define :for_db => 'ac_test_4' do
with_key 'face'
end
end

ActiveCouch::Exporter.create_database('http://localhost:5984/', 'ac_test_4')
end

after(:each) do
ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'ac_test_4')
end

it "should be able to create a permanent view when sent the export method, after the view has already been saved" do
ActiveCouch::Exporter.export('http://localhost:5984', ByFace).should == true
# This is the view document. To actually query this particular view, the URL to be used
# is http://#{host}:#{port}/ac_test_1/_view/by_face/by_face
# A little unwieldy I know, but the point of ActiveCouch is to abstract this unwieldiness
response = Net::HTTP.get_response URI.parse("http://localhost:5984/ac_test_4/_design/by_face")
response.code.should == '200'

ActiveCouch::Exporter.delete('http://localhost:5984', ByFace).should == true
# This is the view document. To actually query this particular view, the URL to be used
# is http://#{host}:#{port}/ac_test_1/_view/by_face/by_face
# A little unwieldy I know, but the point of ActiveCouch is to abstract this unwieldiness
response = Net::HTTP.get_response URI.parse("http://localhost:5984/ac_test_4/_design/by_face")
response.code.should == '404'
end
end

0 comments on commit 38b50ec

Please sign in to comment.