Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Support comments on commands #140

Merged
merged 2 commits into from

2 participants

@nelhage

This branch adds support for comments on commands, and adds an option to counts and all the aggregate queries.

nelhage added some commits
@nelhage nelhage Support comments on commands.
Pass these through to the underlying query against the command
collection.
3b5ee7f
@nelhage nelhage Support comments on counts and various aggregate queries. 7e15f97
@brandonblack

Thanks @nelhage

Going forward, please squash your commits on each of these pull requests into a single commit. It makes it easier to review on our end. If it doesn't make sense to combine into a single commit then they should probably be submitted as separate pull requests.

@nelhage

Will do. IME different groups have different preferences and so I tend to err on the side of more commits, but I am happy to comply with local conventions.

@brandonblack

Thanks, appreciate the help. Everyone is definitely different regarding what they prefer in that respect and we actually don't ask for it in our CONTRIBUTING.md file yet (but we should).

This specific pull request is actually fine, but when there are a half a dozen or more commits in a single pull request its kind of hard to sift through and it's easier if they're squashed ahead of time.

@brandonblack brandonblack merged commit 97d4855 into mongodb:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 6, 2012
  1. @nelhage

    Support comments on commands.

    nelhage authored
    Pass these through to the underlying query against the command
    collection.
  2. @nelhage
This page is out of date. Refresh to see the latest.
View
55 lib/mongo/collection.rb
@@ -654,6 +654,7 @@ def find_and_modify(opts={})
#
# @option opts [:primary, :secondary] :read Read preference indicating which server to perform this query
# on. See Collection#find for more details.
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
#
# @return [Array] An Array with the aggregate command's results.
#
@@ -664,17 +665,11 @@ def aggregate(pipeline=nil, opts={})
raise MongoArgumentError, "pipeline must be an array of operators" unless pipeline.class == Array
raise MongoArgumentError, "pipeline operators must be hashes" unless pipeline.all? { |op| op.class == Hash }
- if read_pref = opts[:read]
- Mongo::Support.validate_read_preference(read_pref)
- else
- read_pref = read_preference
- end
-
hash = BSON::OrderedHash.new
hash['aggregate'] = self.name
hash['pipeline'] = pipeline
- result = @db.command(hash, :read => read_pref)
+ result = @db.command(hash, command_options(opts))
unless Mongo::Support.ok?(result)
raise Mongo::OperationFailure, "aggregate failed: #{result['errmsg']}"
end
@@ -706,6 +701,7 @@ def aggregate(pipeline=nil, opts={})
# or an ArgumentError will be raised.
# @option opts [:primary, :secondary] :read Read preference indicating which server to run this map-reduce
# on. See Collection#find for more details.
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
#
# @return [Collection, Hash] a Mongo::Collection object or a Hash with the map-reduce command's results.
#
@@ -719,12 +715,6 @@ def map_reduce(map, reduce, opts={})
reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
raw = opts.delete(:raw)
- if read_pref = opts[:read]
- Mongo::Support.validate_read_preference(read_pref)
- else
- read_pref = read_preference
- end
-
hash = BSON::OrderedHash.new
hash['mapreduce'] = self.name
hash['map'] = map
@@ -734,7 +724,7 @@ def map_reduce(map, reduce, opts={})
hash[:sort] = Mongo::Support.format_order_clause(hash[:sort])
end
- result = @db.command(hash, :read => read_pref)
+ result = @db.command(hash, command_options(opts))
unless Mongo::Support.ok?(result)
raise Mongo::OperationFailure, "map-reduce failed: #{result['errmsg']}"
end
@@ -771,6 +761,7 @@ def map_reduce(map, reduce, opts={})
# set to true.
# @option opts [:primary, :secondary] :read Read preference indicating which server to perform this group
# on. See Collection#find for more details.
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
#
# @return [Array] the command response consisting of grouped items.
def group(opts, condition={}, initial={}, reduce=nil, finalize=nil)
@@ -836,12 +827,6 @@ def new_group(opts={})
raise MongoArgumentError, "Group requires at minimum values for initial and reduce."
end
- if read_pref = opts[:read]
- Mongo::Support.validate_read_preference(read_pref)
- else
- read_pref = read_preference
- end
-
cmd = {
"group" => {
"ns" => @name,
@@ -866,7 +851,7 @@ def new_group(opts={})
cmd["group"]["$keyf"] = keyf.to_bson_code
end
- result = @db.command(cmd, :read => read_pref)
+ result = @db.command(cmd, command_options(opts))
result["retval"]
end
@@ -882,6 +867,7 @@ def new_group(opts={})
#
# @option opts [:primary, :secondary] :read Read preference indicating which server to perform this query
# on. See Collection#find for more details.
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
#
# @example Saving zip codes and ages and returning distinct results.
# @collection.save({:zip => 10010, :name => {:age => 27}})
@@ -908,13 +894,7 @@ def distinct(key, query=nil, opts={})
command[:key] = key.to_s
command[:query] = query
- if read_pref = opts[:read]
- Mongo::Support.validate_read_preference(read_pref)
- else
- read_pref = read_preference
- end
-
- @db.command(command, :read => read_pref)["values"]
+ @db.command(command, command_options(opts))["values"]
end
# Rename this collection.
@@ -981,19 +961,36 @@ def stats
# @option opts [Integer] :limit (nil) The number of documents to limit.
# @option opts [:primary, :secondary] :read Read preference for this command. See Collection#find for
# more details.
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
#
# @return [Integer]
def count(opts={})
find(opts[:query],
:skip => opts[:skip],
:limit => opts[:limit],
- :read => opts[:read]).count(true)
+ :read => opts[:read],
+ :comment => opts[:comment]).count(true)
end
alias :size :count
protected
+ # Parse common options for read-only commands from an input @opts
+ # hash and return a hash suitable for passing to DB#command.
+ def command_options(opts)
+ out = {}
+
+ if read_pref = opts[:read]
+ Mongo::Support.validate_read_preference(read_pref)
+ else
+ read_pref = read_preference
+ end
+ out[:read] = read_pref
+ out[:comment] = opts[:comment] if opts[:comment]
+ out
+ end
+
def normalize_hint_fields(hint)
case hint
when String
View
2  lib/mongo/cursor.rb
@@ -188,7 +188,7 @@ def count(skip_and_limit = false)
command.merge!(BSON::OrderedHash["fields", @fields])
- response = @db.command(command, :read => @read_preference)
+ response = @db.command(command, :read => @read_preference, :comment => @comment)
return response['n'].to_i if Mongo::Support.ok?(response)
return 0 if response['errmsg'] == "ns missing"
raise OperationFailure.new("Count failed: #{response['errmsg']}", response['code'], response)
View
7 lib/mongo/db.rb
@@ -514,6 +514,7 @@ def ok?(doc)
# @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.
# @option opts [:primary, :secondary] :read Read preference for this command. See Collection#find for
# more details.
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
#
# @return [Hash]
#
@@ -535,7 +536,11 @@ def command(selector, opts={})
begin
result = Cursor.new(system_command_collection,
- :limit => -1, :selector => selector, :socket => socket, :read => read_pref).next_document
+ :limit => -1,
+ :selector => selector,
+ :socket => socket,
+ :read => read_pref,
+ :comment => opts[:comment]).next_document
rescue OperationFailure => ex
raise OperationFailure, "Database command '#{selector.keys.first}' failed: #{ex.message}"
end
View
27 test/unit/cursor_test.rb
@@ -140,4 +140,31 @@ class CursorTest < Test::Unit::TestCase
assert_nil @cursor.fields
end
end
+
+ context "counts" do
+ setup do
+ @logger = mock()
+ @logger.stubs(:debug)
+ @connection = stub(:class => Connection, :logger => @logger,
+ :slave_ok? => false, :read_preference => :primary, :log_duration => false,
+ :tag_sets => {}, :acceptable_latency => 10)
+ @db = stub(:name => "testing", :slave_ok? => false,
+ :connection => @connection, :read_preference => :primary,
+ :tag_sets => {}, :acceptable_latency => 10)
+ @collection = stub(:db => @db, :name => "items", :read_preference => :primary,
+ :tag_sets => {}, :acceptable_latency => 10)
+ @cursor = Cursor.new(@collection)
+ end
+
+ should "pass the comment parameter" do
+ query = {:field => 7}
+ @db.expects(:command).with({ 'count' => "items",
+ 'query' => query,
+ 'fields' => nil},
+ { :read => :primary,
+ :comment => "my comment"}).
+ returns({'ok' => 1, 'n' => 1})
+ assert_equal(1, Cursor.new(@collection, :selector => query, :comment => 'my comment').count())
+ end
+ end
end
View
17 test/unit/db_test.rb
@@ -44,7 +44,8 @@ class DBTest < Test::Unit::TestCase
should "create the proper cursor" do
@cursor = mock(:next_document => {"ok" => 1})
Cursor.expects(:new).with(@collection,
- :limit => -1, :selector => {:buildinfo => 1}, :socket => nil, :read => nil).returns(@cursor)
+ :limit => -1, :selector => {:buildinfo => 1},
+ :socket => nil, :read => nil, :comment => nil).returns(@cursor)
command = {:buildinfo => 1}
@db.command(command, :check_response => true)
end
@@ -52,13 +53,25 @@ class DBTest < Test::Unit::TestCase
should "raise an error when the command fails" do
@cursor = mock(:next_document => {"ok" => 0})
Cursor.expects(:new).with(@collection,
- :limit => -1, :selector => {:buildinfo => 1}, :socket => nil, :read => nil).returns(@cursor)
+ :limit => -1, :selector => {:buildinfo => 1},
+ :socket => nil, :read => nil, :comment => nil).returns(@cursor)
assert_raise OperationFailure do
command = {:buildinfo => 1}
@db.command(command, :check_response => true)
end
end
+ should "pass on the comment" do
+ @cursor = mock(:next_document => {"ok" => 0})
+ Cursor.expects(:new).with(@collection,
+ :limit => -1, :selector => {:buildinfo => 1},
+ :socket => nil, :read => nil, :comment => "my comment").returns(@cursor)
+ assert_raise OperationFailure do
+ command = {:buildinfo => 1}
+ @db.command(command, :check_response => true, :comment => 'my comment')
+ end
+ end
+
should "raise an error if logging out fails" do
@db.expects(:command).returns({})
@client.expects(:pool_size).returns(1)
Something went wrong with that request. Please try again.