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.
|
# Update a single document in this collection.
|
||||||
#
|
#
|
||||||
# :spec :: a hash specifying elements which must be present for
|
# :selector :: a hash specifying elements which must be present for a document to be updated. Note:
|
||||||
# a document to be updated
|
# 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
|
# :document :: a hash specifying the fields to be changed in the
|
||||||
# selected document, or (in the case of an upsert) the document to
|
# selected document, or (in the case of an upsert) the document to
|
||||||
# be inserted
|
# be inserted
|
||||||
#
|
#
|
||||||
# Options:
|
# Options:
|
||||||
# :upsert :: if true, perform an upsert operation
|
# :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
|
# :safe :: if true, check that the update succeeded. OperationFailure
|
||||||
# will be raised on an error. Checking for safety requires an extra
|
# will be raised on an error. Checking for safety requires an extra
|
||||||
# round-trip to the database
|
# round-trip to the database
|
||||||
def update(spec, document, options={})
|
def update(selector, document, options={})
|
||||||
message = ByteBuffer.new
|
message = ByteBuffer.new
|
||||||
message.put_int(0)
|
message.put_int(0)
|
||||||
BSON.serialize_cstr(message, "#{@db.name}.#{@name}")
|
BSON.serialize_cstr(message, "#{@db.name}.#{@name}")
|
||||||
message.put_int(options[:upsert] ? 1 : 0) # 1 if a repsert operation (upsert)
|
update_options = 0
|
||||||
message.put_array(BSON.new.serialize(spec, false).to_a)
|
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)
|
message.put_array(BSON.new.serialize(document, false).to_a)
|
||||||
if options[:safe]
|
if options[:safe]
|
||||||
@db.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message,
|
@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
|
else
|
||||||
@db.send_message_with_operation(Mongo::Constants::OP_UPDATE, message,
|
@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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ module Mongo
|
|||||||
end
|
end
|
||||||
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)
|
def receive_message_with_operation(operation, message, log_message=nil)
|
||||||
message_with_headers = add_message_headers(operation, message).to_s
|
message_with_headers = add_message_headers(operation, message).to_s
|
||||||
@logger.debug(" MONGODB #{log_message || message}") if @logger
|
@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"]
|
assert_equal 1, @@test.find_one(:_id => id2)["x"]
|
||||||
end
|
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
|
def test_upsert
|
||||||
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
||||||
@@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")
|
op == 2001 && log.include?("db.books.update")
|
||||||
end
|
end
|
||||||
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
should "send safe insert message" do
|
should "send safe insert message" do
|
||||||
|
Loading…
Reference in New Issue
Block a user