added find_and_modify helper
This commit is contained in:
parent
45d3b91882
commit
35dac1f31e
|
@ -27,9 +27,9 @@ end
|
|||
|
||||
require 'bson'
|
||||
|
||||
require 'mongo/util/conversions'
|
||||
require 'mongo/util/support'
|
||||
require 'mongo/util/core_ext'
|
||||
require 'mongo/util/conversions'
|
||||
require 'mongo/util/server_version'
|
||||
|
||||
require 'mongo/collection'
|
||||
|
|
|
@ -405,7 +405,6 @@ module Mongo
|
|||
|
||||
# Note: calling drop_indexes with no args will drop them all.
|
||||
@db.drop_index(@name, '*')
|
||||
|
||||
end
|
||||
|
||||
# Drop the entire collection. USE WITH CAUTION.
|
||||
|
@ -413,6 +412,30 @@ module Mongo
|
|||
@db.drop_collection(@name)
|
||||
end
|
||||
|
||||
|
||||
# Atomically update and return a document using MongoDB's findAndModify command. (MongoDB > 1.3.0)
|
||||
#
|
||||
# @option opts [Hash] :update (nil) the update operation to perform on the matched document.
|
||||
# @option opts [Hash] :query ({}) a query selector document for matching the desired document.
|
||||
# @option opts [Array, String, OrderedHash] :sort ({}) specify a sort option for the query using any
|
||||
# of the sort options available for Cursor#sort. Sort order is important if the query will be matching
|
||||
# multiple documents since only the first matching document will be updated and returned.
|
||||
# @option opts [Boolean] :remove (false) If true, removes the the returned document from the collection.
|
||||
# @option opts [Boolean] :new (false) If true, returns the updated document; otherwise, returns the document
|
||||
# prior to update.
|
||||
#
|
||||
# @return [Hash] the matched document.
|
||||
#
|
||||
# @core mapreduce map_reduce-instance_method
|
||||
def find_and_modify(opts={})
|
||||
cmd = OrderedHash.new
|
||||
cmd[:findandmodify] = @name
|
||||
cmd.merge!(opts)
|
||||
cmd[:sort] = Mongo::Support.format_order_clause(opts[:sort]) if opts[:sort]
|
||||
|
||||
@db.command(cmd, false, true)['value']
|
||||
end
|
||||
|
||||
# Perform a map/reduce operation on the current collection.
|
||||
#
|
||||
# @param [String, BSON::Code] map a map function, written in JavaScript.
|
||||
|
|
|
@ -365,7 +365,7 @@ module Mongo
|
|||
return @selector if @selector.has_key?('$query')
|
||||
spec = OrderedHash.new
|
||||
spec['$query'] = @selector
|
||||
spec['$orderby'] = formatted_order_clause if @order
|
||||
spec['$orderby'] = Mongo::Support.format_order_clause(@order) if @order
|
||||
spec['$hint'] = @hint if @hint && @hint.length > 0
|
||||
spec['$explain'] = true if @explain
|
||||
spec['$snapshot'] = true if @snapshot
|
||||
|
@ -377,16 +377,6 @@ module Mongo
|
|||
@order || @explain || @hint || @snapshot
|
||||
end
|
||||
|
||||
def formatted_order_clause
|
||||
case @order
|
||||
when String, Symbol then string_as_sort_parameters(@order)
|
||||
when Array then array_as_sort_parameters(@order)
|
||||
else
|
||||
raise InvalidSortValueError, "Illegal sort clause, '#{@order.class.name}'; must be of the form " +
|
||||
"[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
"DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from)"
|
||||
end
|
||||
|
|
|
@ -18,6 +18,7 @@ require 'digest/md5'
|
|||
|
||||
module Mongo
|
||||
module Support
|
||||
include Mongo::Conversions
|
||||
extend self
|
||||
|
||||
# Generate an MD5 for authentication.
|
||||
|
@ -55,5 +56,15 @@ module Mongo
|
|||
raise Mongo::InvalidNSName, "database name cannot be the empty string" if db_name.empty?
|
||||
db_name
|
||||
end
|
||||
|
||||
def format_order_clause(order)
|
||||
case order
|
||||
when String, Symbol then string_as_sort_parameters(order)
|
||||
when Array then array_as_sort_parameters(order)
|
||||
else
|
||||
raise InvalidSortValueError, "Illegal sort clause, '#{order.class.name}'; must be of the form " +
|
||||
"[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ class TestCollection < Test::Unit::TestCase
|
|||
@@version = @@connection.server_version
|
||||
|
||||
def setup
|
||||
@@test.drop()
|
||||
@@test.remove
|
||||
end
|
||||
|
||||
def test_optional_pk_factory
|
||||
|
@ -161,6 +161,7 @@ class TestCollection < Test::Unit::TestCase
|
|||
assert_raise OperationFailure do
|
||||
@@test.update({}, {"$inc" => {"x" => 1}}, :safe => true)
|
||||
end
|
||||
@@test.drop
|
||||
end
|
||||
else
|
||||
def test_safe_update
|
||||
|
@ -176,6 +177,7 @@ class TestCollection < Test::Unit::TestCase
|
|||
assert_raise OperationFailure do
|
||||
@@test.update({}, {"x" => 10}, :safe => true)
|
||||
end
|
||||
@@test.drop
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -188,6 +190,7 @@ class TestCollection < Test::Unit::TestCase
|
|||
assert_raise OperationFailure do
|
||||
@@test.save({"hello" => "world"}, :safe => true)
|
||||
end
|
||||
@@test.drop
|
||||
end
|
||||
|
||||
def test_mocked_safe_remove
|
||||
|
@ -374,6 +377,28 @@ class TestCollection < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
if @@version > "1.3.0"
|
||||
def test_find_and_modify
|
||||
@@test << { :a => 1, :processed => false }
|
||||
@@test << { :a => 2, :processed => false }
|
||||
@@test << { :a => 3, :processed => false }
|
||||
|
||||
@@test.find_and_modify(:query => {}, :sort => [['a', -1]], :update => {"$set" => {:processed => true}})
|
||||
|
||||
assert @@test.find_one({:a => 3})['processed']
|
||||
end
|
||||
|
||||
def test_find_and_modify_with_invalid_options
|
||||
@@test << { :a => 1, :processed => false }
|
||||
@@test << { :a => 2, :processed => false }
|
||||
@@test << { :a => 3, :processed => false }
|
||||
|
||||
assert_raise Mongo::OperationFailure do
|
||||
@@test.find_and_modify(:blimey => {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_saving_dates_pre_epoch
|
||||
begin
|
||||
@@test.save({'date' => Time.utc(1600)})
|
||||
|
|
Loading…
Reference in New Issue