cleanup and credits

This commit is contained in:
Mike Dirolf 2009-10-08 10:02:54 -04:00
parent 20f65039f3
commit 4fdcad1327
9 changed files with 53 additions and 43 deletions

View File

@ -320,8 +320,9 @@ Paul Dlug, paul.dlug@gmail.com
* Generate _id on the client side if not provided * Generate _id on the client side if not provided
* Collection#insert and Collection#save return _id * Collection#insert and Collection#save return _id
Durran Jordan and Les Hill, durran@gmail.com Durran Jordan, durran@gmail.com
* DB#collections * DB#collections
* Support for specifying sort order as array of [key, direction] pairs
Cyril Mougel, cyril.mougel@gmail.com Cyril Mougel, cyril.mougel@gmail.com
* Initial logging support * Initial logging support

View File

@ -91,9 +91,9 @@ module Mongo
# :skip :: Number of documents to omit (from the start of the result set) # :skip :: Number of documents to omit (from the start of the result set)
# when returning the results # when returning the results
# :limit :: Maximum number of records to return # :limit :: Maximum number of records to return
# :sort :: Either hash of field names as keys and 1/-1 as values; 1 == # :sort :: An array of [key, direction] pairs to sort by. Direction should
# ascending, -1 == descending, or array of field names (all # be specified as Mongo::ASCENDING (or :ascending / :asc) or
# assumed to be sorted in ascending order). # Mongo::DESCENDING (or :descending / :desc)
# :hint :: See #hint. This option overrides the collection-wide value. # :hint :: See #hint. This option overrides the collection-wide value.
# :snapshot :: If true, snapshot mode will be used for this query. # :snapshot :: If true, snapshot mode will be used for this query.
# Snapshot mode assures no duplicates are returned, or # Snapshot mode assures no duplicates are returned, or

View File

@ -75,16 +75,24 @@ module Mongo
# Sort this cursor's result # Sort this cursor's result
# #
# Takes either a hash of field names as keys and 1/-1 as values; 1 == # Takes either a single key and a direction, or an array of [key,
# ascending, -1 == descending, or array of field names (all assumed to be # direction] pairs. Directions should be specified as Mongo::ASCENDING
# sorted in ascending order). # or Mongo::DESCENDING (or :ascending or :descending) (or :asc or :desc).
# #
# Raises InvalidOperation if this cursor has already been used. # Raises InvalidOperation if this cursor has already been used. Raises
# InvalidSortValueError if specified order is invalid.
# #
# This method overrides any sort order specified in the Collection#find # This method overrides any sort order specified in the Collection#find
# method, and only the last sort applied has an effect # method, and only the last sort applied has an effect
def sort(order) def sort(key_or_list, direction=nil)
check_modifiable check_modifiable
if !direction.nil?
order = [[key_or_list, direction]]
else
order = key_or_list
end
@query.order_by = order @query.order_by = order
self self
end end

View File

@ -24,6 +24,6 @@ module Mongo
# Raised when an invalid name is used. # Raised when an invalid name is used.
class InvalidName < RuntimeError; end class InvalidName < RuntimeError; end
# Raised when the client supplies an invalid values for a sorting. # Raised when the client supplies an invalid value to sort by.
class InvalidSortValueError < RuntimeError; end class InvalidSortValueError < RuntimeError; end
end end

View File

@ -37,7 +37,7 @@ module Mongo
if query.contains_special_fields if query.contains_special_fields
sel = OrderedHash.new sel = OrderedHash.new
sel['query'] = query.selector sel['query'] = query.selector
if query.order_by && query.order_by.length > 0 if query.order_by
order_by = query.order_by order_by = query.order_by
sel['orderby'] = case order_by sel['orderby'] = case order_by
when String then string_as_sort_parameters(order_by) when String then string_as_sort_parameters(order_by)
@ -47,7 +47,7 @@ module Mongo
warn_if_deprecated(order_by) warn_if_deprecated(order_by)
order_by order_by
else else
raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash" raise InvalidSortValueError.new("illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash")
end end
end end
sel['$hint'] = query.hint if query.hint && query.hint.length > 0 sel['$hint'] = query.hint if query.hint && query.hint.length > 0

View File

@ -108,7 +108,7 @@ module Mongo
end end
def contains_special_fields def contains_special_fields
(@order_by != nil && @order_by.length > 0) || @explain || @hint || @snapshot @order_by || @explain || @hint || @snapshot
end end
def to_s def to_s

View File

@ -93,15 +93,15 @@ module Mongo #:nodoc:
return 1 if ASCENDING.include?(val) return 1 if ASCENDING.include?(val)
return -1 if DESCENDING.include?(val) return -1 if DESCENDING.include?(val)
raise InvalidSortValueError.new( raise InvalidSortValueError.new(
"#{self} was supplied as a sort value when acceptable values are: " + "#{self} was supplied as a sort direction when acceptable values are: " +
"ascending, asc, :ascending, :asc, 1, descending, desc, :descending, :desc, -1.") "Mongo::ASCENDING, 'ascending', 'asc', :ascending, :asc, 1, Mongo::DESCENDING, 'descending', 'desc', :descending, :desc, -1.")
end end
# This is the method to call when the client needs to be warned of # This is the method to call when the client needs to be warned of
# deprecation in the way sorting parameters are supplied. # deprecation in the way sorting parameters are supplied.
def warn_if_deprecated(value) def warn_if_deprecated(value)
unless value.is_a?(Array) && value.first.is_a?(Array) unless value.is_a?(Array) && value.first.is_a?(Array)
warn("\nSorting has been deprecated in favor of a new syntax: \n" + warn("Specifying sort order as #{value.inspect} has been deprecated in favor of a new syntax: \n" +
" :sort => [['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]") " :sort => [['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]")
end end
end end

View File

@ -62,22 +62,30 @@ class CursorTest < Test::Unit::TestCase
@@coll.clear @@coll.clear
5.times{|x| @@coll.insert({"a" => x}) } 5.times{|x| @@coll.insert({"a" => x}) }
assert_kind_of Cursor, @@coll.find().sort({:a => 1}) assert_kind_of Cursor, @@coll.find().sort(:a, 1)
assert_equal 0, @@coll.find().sort({:a => 1}).next_object["a"] assert_equal 0, @@coll.find().sort(:a, 1).next_object["a"]
assert_equal 4, @@coll.find().sort({:a => -1}).next_object["a"] assert_equal 4, @@coll.find().sort(:a, -1).next_object["a"]
assert_equal 0, @@coll.find().sort(["a"]).next_object["a"] assert_equal 0, @@coll.find().sort([["a", :asc]]).next_object["a"]
assert_kind_of Cursor, @@coll.find().sort({:a => -1, :b => 1}) assert_kind_of Cursor, @@coll.find().sort([[:a, -1], [:b, 1]])
assert_equal 4, @@coll.find().sort({:a => 1}).sort({:a => -1}).next_object["a"] assert_equal 4, @@coll.find().sort(:a, 1).sort(:a, -1).next_object["a"]
assert_equal 0, @@coll.find().sort({:a => -1}).sort({:a => 1}).next_object["a"] assert_equal 0, @@coll.find().sort(:a, -1).sort(:a, 1).next_object["a"]
cursor = @@coll.find() cursor = @@coll.find()
cursor.next_object() cursor.next_object()
assert_raise InvalidOperation do assert_raise InvalidOperation do
cursor.sort(["a"]) cursor.sort(["a"])
end end
assert_raise InvalidSortValueError do
@@coll.find().sort(:a, 25).next_object
end
assert_raise InvalidSortValueError do
@@coll.find().sort(25).next_object
end
end end
def test_limit def test_limit

View File

@ -149,7 +149,7 @@ class DBAPITest < Test::Unit::TestCase
@@coll.insert('a' => 4, 'b' => 1) @@coll.insert('a' => 4, 'b' => 1)
# Sorting (ascending) # Sorting (ascending)
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => {'a' => 1}).to_a docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', 1]]).to_a
assert_equal 4, docs.size assert_equal 4, docs.size
assert_equal 1, docs[0]['a'] assert_equal 1, docs[0]['a']
assert_equal 2, docs[1]['a'] assert_equal 2, docs[1]['a']
@ -157,7 +157,7 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 4, docs[3]['a'] assert_equal 4, docs[3]['a']
# Sorting (descending) # Sorting (descending)
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => {'a' => -1}).to_a docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', -1]]).to_a
assert_equal 4, docs.size assert_equal 4, docs.size
assert_equal 4, docs[0]['a'] assert_equal 4, docs[0]['a']
assert_equal 3, docs[1]['a'] assert_equal 3, docs[1]['a']
@ -187,16 +187,10 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 1, docs[2]['a'] assert_equal 1, docs[2]['a']
assert_equal 3, docs[3]['a'] assert_equal 3, docs[3]['a']
# Sorting using empty array; no order guarantee (Mongo bug #898) but # Sorting using empty array; no order guarantee should not blow up.
# should not blow up.
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a
assert_equal 4, docs.size assert_equal 4, docs.size
# Sorting using array of hashes; no order guarantee (Mongo bug #898) but
# should not blow up.
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [{'b' => 1}, {'a' => -1}]).to_a
assert_equal 4, docs.size
# Sorting using ordered hash. You can use an unordered one, but then the # Sorting using ordered hash. You can use an unordered one, but then the
# order of the keys won't be guaranteed thus your sort won't make sense. # order of the keys won't be guaranteed thus your sort won't make sense.
oh = OrderedHash.new oh = OrderedHash.new
@ -208,16 +202,15 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 2, docs[2]['a'] assert_equal 2, docs[2]['a']
assert_equal 1, docs[3]['a'] assert_equal 1, docs[3]['a']
# TODO this will not pass due to known Mongo bug #898 oh = OrderedHash.new
# oh = OrderedHash.new oh['b'] = -1
# oh['b'] = -1 oh['a'] = 1
# oh['a'] = 1 docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
# docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a assert_equal 4, docs.size
# assert_equal 4, docs.size assert_equal 1, docs[0]['a']
# assert_equal 1, docs[0]['a'] assert_equal 3, docs[1]['a']
# assert_equal 3, docs[1]['a'] assert_equal 2, docs[2]['a']
# assert_equal 2, docs[2]['a'] assert_equal 4, docs[3]['a']
# assert_equal 4, docs[3]['a']
end end
def test_find_limits def test_find_limits