Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #56 from matthiasjakel/master

Add bulk document loading
  • Loading branch information...
commit fe9d4df07cdd7618befd4b0711f3c6b78fe935ee 2 parents 33bf953 + 833aac3
@langalex authored
View
5 README.md
@@ -156,7 +156,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
Please sign in to comment.
Something went wrong with that request. Please try again.