Added support for multi-update (available in mongo >= 1.1.3)
This commit is contained in:
parent
f891b4ece3
commit
867783c665
@ -235,30 +235,37 @@ module Mongo
|
||||
|
||||
# Update a single document in this collection.
|
||||
#
|
||||
# :spec :: a hash specifying elements which must be present for
|
||||
# a document to be updated
|
||||
# :selector :: a hash specifying elements which must be present for a document to be updated. Note:
|
||||
# the update command currently updates only the first document matching the
|
||||
# given selector. If you want all matching documents to be updated, be sure
|
||||
# to specify :multi => true.
|
||||
# :document :: a hash specifying the fields to be changed in the
|
||||
# selected document, or (in the case of an upsert) the document to
|
||||
# be inserted
|
||||
#
|
||||
# Options:
|
||||
# :upsert :: if true, perform an upsert operation
|
||||
# :multi :: update all documents matching the selector, as opposed to
|
||||
# just the first matching document. Note: only works in 1.1.3 or later.
|
||||
# :safe :: if true, check that the update succeeded. OperationFailure
|
||||
# will be raised on an error. Checking for safety requires an extra
|
||||
# round-trip to the database
|
||||
def update(spec, document, options={})
|
||||
def update(selector, document, options={})
|
||||
message = ByteBuffer.new
|
||||
message.put_int(0)
|
||||
BSON.serialize_cstr(message, "#{@db.name}.#{@name}")
|
||||
message.put_int(options[:upsert] ? 1 : 0) # 1 if a repsert operation (upsert)
|
||||
message.put_array(BSON.new.serialize(spec, false).to_a)
|
||||
update_options = 0
|
||||
update_options += 1 if options[:upsert]
|
||||
update_options += 2 if options[:multi]
|
||||
message.put_int(update_options)
|
||||
message.put_array(BSON.new.serialize(selector, false).to_a)
|
||||
message.put_array(BSON.new.serialize(document, false).to_a)
|
||||
if options[:safe]
|
||||
@db.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message,
|
||||
"db.#{@name}.update(#{spec.inspect}, #{document.inspect})")
|
||||
"db.#{@name}.update(#{selector.inspect}, #{document.inspect})")
|
||||
else
|
||||
@db.send_message_with_operation(Mongo::Constants::OP_UPDATE, message,
|
||||
"db.#{@name}.update(#{spec.inspect}, #{document.inspect})")
|
||||
"db.#{@name}.update(#{selector.inspect}, #{document.inspect})")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -465,7 +465,7 @@ module Mongo
|
||||
end
|
||||
end
|
||||
|
||||
# Note: this method is a stub. Will be completed in an upcoming refactoring.
|
||||
# Send a message to the database and wait for the response.
|
||||
def receive_message_with_operation(operation, message, log_message=nil)
|
||||
message_with_headers = add_message_headers(operation, message).to_s
|
||||
@logger.debug(" MONGODB #{log_message || message}") if @logger
|
||||
|
@ -97,6 +97,20 @@ class TestCollection < Test::Unit::TestCase
|
||||
assert_equal 1, @@test.find_one(:_id => id2)["x"]
|
||||
end
|
||||
|
||||
if @@version >= "1.1.3"
|
||||
def test_multi_update
|
||||
@@test.save("num" => 10)
|
||||
@@test.save("num" => 10)
|
||||
@@test.save("num" => 10)
|
||||
assert_equal 3, @@test.count
|
||||
|
||||
@@test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true)
|
||||
@@test.find.each do |doc|
|
||||
assert_equal 100, doc["num"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_upsert
|
||||
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
||||
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
||||
|
@ -38,7 +38,6 @@ class CollectionTest < Test::Unit::TestCase
|
||||
op == 2001 && log.include?("db.books.update")
|
||||
end
|
||||
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
||||
|
||||
end
|
||||
|
||||
should "send safe insert message" do
|
||||
|
Loading…
Reference in New Issue
Block a user