added find_and_modify helper
This commit is contained in:
parent
45d3b91882
commit
35dac1f31e
|
@ -27,9 +27,9 @@ end
|
||||||
|
|
||||||
require 'bson'
|
require 'bson'
|
||||||
|
|
||||||
|
require 'mongo/util/conversions'
|
||||||
require 'mongo/util/support'
|
require 'mongo/util/support'
|
||||||
require 'mongo/util/core_ext'
|
require 'mongo/util/core_ext'
|
||||||
require 'mongo/util/conversions'
|
|
||||||
require 'mongo/util/server_version'
|
require 'mongo/util/server_version'
|
||||||
|
|
||||||
require 'mongo/collection'
|
require 'mongo/collection'
|
||||||
|
|
|
@ -405,7 +405,6 @@ module Mongo
|
||||||
|
|
||||||
# Note: calling drop_indexes with no args will drop them all.
|
# Note: calling drop_indexes with no args will drop them all.
|
||||||
@db.drop_index(@name, '*')
|
@db.drop_index(@name, '*')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Drop the entire collection. USE WITH CAUTION.
|
# Drop the entire collection. USE WITH CAUTION.
|
||||||
|
@ -413,6 +412,30 @@ module Mongo
|
||||||
@db.drop_collection(@name)
|
@db.drop_collection(@name)
|
||||||
end
|
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.
|
# Perform a map/reduce operation on the current collection.
|
||||||
#
|
#
|
||||||
# @param [String, BSON::Code] map a map function, written in JavaScript.
|
# @param [String, BSON::Code] map a map function, written in JavaScript.
|
||||||
|
|
|
@ -365,7 +365,7 @@ module Mongo
|
||||||
return @selector if @selector.has_key?('$query')
|
return @selector if @selector.has_key?('$query')
|
||||||
spec = OrderedHash.new
|
spec = OrderedHash.new
|
||||||
spec['$query'] = @selector
|
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['$hint'] = @hint if @hint && @hint.length > 0
|
||||||
spec['$explain'] = true if @explain
|
spec['$explain'] = true if @explain
|
||||||
spec['$snapshot'] = true if @snapshot
|
spec['$snapshot'] = true if @snapshot
|
||||||
|
@ -377,16 +377,6 @@ module Mongo
|
||||||
@order || @explain || @hint || @snapshot
|
@order || @explain || @hint || @snapshot
|
||||||
end
|
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
|
def to_s
|
||||||
"DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from)"
|
"DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from)"
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,6 +18,7 @@ require 'digest/md5'
|
||||||
|
|
||||||
module Mongo
|
module Mongo
|
||||||
module Support
|
module Support
|
||||||
|
include Mongo::Conversions
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
# Generate an MD5 for authentication.
|
# 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?
|
raise Mongo::InvalidNSName, "database name cannot be the empty string" if db_name.empty?
|
||||||
db_name
|
db_name
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ class TestCollection < Test::Unit::TestCase
|
||||||
@@version = @@connection.server_version
|
@@version = @@connection.server_version
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@@test.drop()
|
@@test.remove
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_optional_pk_factory
|
def test_optional_pk_factory
|
||||||
|
@ -161,6 +161,7 @@ class TestCollection < Test::Unit::TestCase
|
||||||
assert_raise OperationFailure do
|
assert_raise OperationFailure do
|
||||||
@@test.update({}, {"$inc" => {"x" => 1}}, :safe => true)
|
@@test.update({}, {"$inc" => {"x" => 1}}, :safe => true)
|
||||||
end
|
end
|
||||||
|
@@test.drop
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
def test_safe_update
|
def test_safe_update
|
||||||
|
@ -176,6 +177,7 @@ class TestCollection < Test::Unit::TestCase
|
||||||
assert_raise OperationFailure do
|
assert_raise OperationFailure do
|
||||||
@@test.update({}, {"x" => 10}, :safe => true)
|
@@test.update({}, {"x" => 10}, :safe => true)
|
||||||
end
|
end
|
||||||
|
@@test.drop
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -188,6 +190,7 @@ class TestCollection < Test::Unit::TestCase
|
||||||
assert_raise OperationFailure do
|
assert_raise OperationFailure do
|
||||||
@@test.save({"hello" => "world"}, :safe => true)
|
@@test.save({"hello" => "world"}, :safe => true)
|
||||||
end
|
end
|
||||||
|
@@test.drop
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_mocked_safe_remove
|
def test_mocked_safe_remove
|
||||||
|
@ -374,6 +377,28 @@ class TestCollection < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
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
|
def test_saving_dates_pre_epoch
|
||||||
begin
|
begin
|
||||||
@@test.save({'date' => Time.utc(1600)})
|
@@test.save({'date' => Time.utc(1600)})
|
||||||
|
|
Loading…
Reference in New Issue