Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add bulk document loading #56

Merged
merged 3 commits into from

2 participants

@matthiasjakel

No description provided.

@langalex
Owner

how about using load for this as well instead of adding another method? e.g. when passing load just one id it loads just one doc, when passing more, it returns multiple docs.

@matthiasjakel

fixed ;)

@langalex langalex merged commit fe9d4df into langalex:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 23, 2012
  1. @matthiasjakel
Commits on Feb 26, 2012
  1. @matthiasjakel
  2. @matthiasjakel

    Fix exception raising

    matthiasjakel authored
This page is out of date. Refresh to see the latest.
View
5 README.md
@@ -158,7 +158,12 @@ Now you can save your objects. All database operations are encapsulated in the C
You can of course also retrieve your instance:
CouchPotato.database.load_document "id_of_the_user_document" # => <#User 0x3075>
+
+#### Operations on multiple documents
+You can also load a bunch of documents with one request.
+
+ CouchPotato.database.load ['user1', 'user2', 'user3'] # => [<#User 0x3075>, <#User 0x3076>, <#User 0x3077>]
#### Properties
View
32 lib/couch_potato/database.rb
@@ -99,21 +99,30 @@ def destroy_document(document)
end
alias_method :destroy, :destroy_document
- # loads a document by its id
+ # loads a document by its id(s)
def load_document(id)
raise "Can't load a document without an id (got nil)" if id.nil?
- begin
- instance = couchrest_database.get(id)
- instance.database = self
- instance
- rescue(RestClient::ResourceNotFound)
- nil
+
+ if id.is_a?(Array)
+ bulk_load id
+ else
+ begin
+ instance = couchrest_database.get(id)
+ instance.database = self
+ instance
+ rescue(RestClient::ResourceNotFound)
+ nil
+ end
end
end
alias_method :load, :load_document
def load!(id)
- load(id) || raise(CouchPotato::NotFound)
+ doc = load(id)
+ if id.is_a?(Array)
+ missing_docs = id - doc.map(&:id)
+ end
+ raise(CouchPotato::NotFound, missing_docs) if doc.nil? || !missing_docs.empty?
end
def inspect #:nodoc:
@@ -126,6 +135,13 @@ def couchrest_database
end
private
+
+ def bulk_load(ids)
+ response = couchrest_database.bulk_load ids
+ existing_rows = response['rows'].select{|row| row.key? 'doc'}
+ docs = existing_rows.map{|row| row["doc"]}
+ docs.each{|doc| doc.database = self}
+ end
def create_document(document, validate)
document.database = self
View
71 spec/unit/database_spec.rb
@@ -45,8 +45,11 @@ class Child
end
describe CouchPotato::Database, 'load' do
+
+ let(:couchrest_db) { stub('couchrest db', :info => nil) }
+ let(:db) { CouchPotato::Database.new couchrest_db }
+
it "should raise an exception if nil given" do
- db = CouchPotato::Database.new(stub('couchrest db', :info => nil))
lambda {
db.load nil
}.should raise_error("Can't load a document without an id (got nil)")
@@ -55,26 +58,82 @@ class Child
it "should set itself on the model" do
user = mock('user').as_null_object
DbTestUser.stub!(:new).and_return(user)
- db = CouchPotato::Database.new(stub('couchrest db', :info => nil, :get => DbTestUser.json_create({JSON.create_id => 'DbTestUser'})))
+ couchrest_db.stub(:get).and_return DbTestUser.json_create({JSON.create_id => 'DbTestUser'})
user.should_receive(:database=).with(db)
db.load '1'
end
it "should load namespaced models" do
- db = CouchPotato::Database.new(stub('couchrest db', :info => nil, :get => Parent::Child.json_create({JSON.create_id => 'Parent::Child'})))
+ couchrest_db.stub(:get).and_return Parent::Child.json_create({JSON.create_id => 'Parent::Child'})
db.load('1').class.should == Parent::Child
end
+
+ context "when several ids given" do
+
+ let(:doc1) { DbTestUser.new }
+ let(:doc2) { DbTestUser.new }
+ let(:response) do
+ {"rows" => [{}, {"doc" => doc1}, {"doc" => doc2}]}
+ end
+
+ before(:each) do
+ couchrest_db.stub(:bulk_load).and_return response
+ end
+
+ it "requests the couchrest bulk method" do
+ couchrest_db.should_receive(:bulk_load).with(['1', '2', '3'])
+ db.load ['1', '2', '3']
+ end
+
+ it "returns only found documents" do
+ db.load(['1', '2', '3']).should have(2).items
+ end
+
+ it "writes itself to each of the documents" do
+ db.load(['1', '2', '3']).each do |doc|
+ doc.database.should eql(db)
+ end
+ end
+ end
end
describe CouchPotato::Database, 'load!' do
+
+ let(:db) { CouchPotato::Database.new(stub('couchrest db', :info => nil)) }
+
it "should raise an error if no document found" do
- couchrest_db = stub('couchrest db', :info => nil)
- couchrest_db.stub(:get).and_raise(RestClient::ResourceNotFound)
- db = CouchPotato::Database.new(couchrest_db)
+ db.couchrest_database.stub(:get).and_raise(RestClient::ResourceNotFound)
lambda {
db.load! '1'
}.should raise_error(CouchPotato::NotFound)
end
+
+ context "when several ids given" do
+
+ let(:docs) do
+ [
+ DbTestUser.new(:id => '1'),
+ DbTestUser.new(:id => '2')
+ ]
+ end
+
+ before(:each) do
+ db.stub(:load).and_return(docs)
+ end
+
+ it "raises an exception when not all documents could be found" do
+ lambda {
+ db.load! ['1', '2', '3']
+ }.should raise_error(CouchPotato::NotFound, ['3'])
+ end
+
+ it "raises no exception when all documents are found" do
+ docs << DbTestUser.new(:id => '3')
+ lambda {
+ db.load! ['1', '2', '3']
+ }.should_not raise_error(CouchPotato::NotFound)
+ end
+ end
end
describe CouchPotato::Database, 'save_document' do
Something went wrong with that request. Please try again.