Updating sorting to new syntax
This commit is contained in:
parent
22588828f8
commit
20f65039f3
|
@ -23,4 +23,7 @@ module Mongo
|
|||
|
||||
# Raised when an invalid name is used.
|
||||
class InvalidName < RuntimeError; end
|
||||
|
||||
# Raised when the client supplies an invalid values for a sorting.
|
||||
class InvalidSortValueError < RuntimeError; end
|
||||
end
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
|
||||
require 'mongo/message/message'
|
||||
require 'mongo/message/opcodes'
|
||||
require 'mongo/util/conversions'
|
||||
require 'mongo/util/ordered_hash'
|
||||
|
||||
module Mongo
|
||||
|
||||
class QueryMessage < Message
|
||||
include Mongo::Conversions
|
||||
|
||||
attr_reader :query
|
||||
|
||||
|
@ -37,24 +38,14 @@ module Mongo
|
|||
sel = OrderedHash.new
|
||||
sel['query'] = query.selector
|
||||
if query.order_by && query.order_by.length > 0
|
||||
sel['orderby'] = case query.order_by
|
||||
when String
|
||||
{query.order_by => 1}
|
||||
when Array
|
||||
h = OrderedHash.new
|
||||
query.order_by.each { |ob|
|
||||
case ob
|
||||
when String
|
||||
h[ob] = 1
|
||||
when Hash # should have one entry; will handle all
|
||||
ob.each { |k,v| h[k] = v }
|
||||
else
|
||||
raise "illegal query order_by value #{query.order_by.inspect}"
|
||||
end
|
||||
}
|
||||
h
|
||||
order_by = query.order_by
|
||||
sel['orderby'] = case order_by
|
||||
when String then string_as_sort_parameters(order_by)
|
||||
when Symbol then symbol_as_sort_parameters(order_by)
|
||||
when Array then array_as_sort_parameters(order_by)
|
||||
when Hash # Should be an ordered hash, but this message doesn't care
|
||||
query.order_by
|
||||
warn_if_deprecated(order_by)
|
||||
order_by
|
||||
else
|
||||
raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
|
||||
end
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
# --
|
||||
# Copyright (C) 2008-2009 10gen Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ++
|
||||
module Mongo #:nodoc:
|
||||
|
||||
# Utility module to include when needing to convert certain types of
|
||||
# objects to mongo-friendly parameters.
|
||||
module Conversions
|
||||
|
||||
ASCENDING = ["ascending", "asc", "1"]
|
||||
DESCENDING = ["descending", "desc", "-1"]
|
||||
|
||||
# Converts the supplied +Array+ to a +Hash+ to pass to mongo as
|
||||
# sorting parameters. The returned +Hash+ will vary depending
|
||||
# on whether the passed +Array+ is one or two dimensional.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# *DEPRECATED
|
||||
#
|
||||
# <tt>array_as_sort_parameters(["field1", "field2"])</tt> =>
|
||||
# <tt>{ "field1" => "1", "field2" => "1" }</tt>
|
||||
#
|
||||
# *New Syntax:
|
||||
#
|
||||
# <tt>array_as_sort_parameters([["field1", :asc], ["field2", :desc]])</tt> =>
|
||||
# <tt>{ "field1" => 1, "field2" => -1}</tt>
|
||||
def array_as_sort_parameters(value)
|
||||
warn_if_deprecated(value)
|
||||
order_by = OrderedHash.new
|
||||
value.each do |param|
|
||||
if (param.class.name == "String")
|
||||
order_by[param] = 1
|
||||
else
|
||||
order_by[param[0]] = sort_value(param[1]) unless param[1].nil?
|
||||
end
|
||||
end
|
||||
order_by
|
||||
end
|
||||
|
||||
# Converts the supplied +String+ to a +Hash+ to pass to mongo as
|
||||
# a sorting parameter with ascending order. If the +String+
|
||||
# is empty then an empty +Hash+ will be returned.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# *DEPRECATED
|
||||
#
|
||||
# <tt>string_as_sort_parameters("field")</tt> => <tt>{ "field" => 1 }</tt>
|
||||
# <tt>string_as_sort_parameters("")</tt> => <tt>{}</tt>
|
||||
def string_as_sort_parameters(value)
|
||||
warn_if_deprecated(value)
|
||||
return {} if value.empty?
|
||||
{ value => 1 }
|
||||
end
|
||||
|
||||
# Converts the supplied +Symbol+ to a +Hash+ to pass to mongo as
|
||||
# a sorting parameter with ascending order.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# *DEPRECATED
|
||||
#
|
||||
# <tt>symbol_as_sort_parameters(:field)</tt> => <tt>{ "field" => 1 }</tt>
|
||||
def symbol_as_sort_parameters(value)
|
||||
warn_if_deprecated(value)
|
||||
{ value.to_s => 1 }
|
||||
end
|
||||
|
||||
# Converts the +String+, +Symbol+, or +Integer+ to the
|
||||
# corresponding sort value in MongoDB.
|
||||
#
|
||||
# Valid conversions (case-insensitive):
|
||||
#
|
||||
# <tt>ascending, asc, :ascending, :asc, 1</tt> => <tt>1</tt>
|
||||
# <tt>descending, desc, :descending, :desc, -1</tt> => <tt>-1</tt>
|
||||
#
|
||||
# If the value is invalid then an error will be raised.
|
||||
def sort_value(value)
|
||||
val = value.to_s.downcase
|
||||
return 1 if ASCENDING.include?(val)
|
||||
return -1 if DESCENDING.include?(val)
|
||||
raise InvalidSortValueError.new(
|
||||
"#{self} was supplied as a sort value when acceptable values are: " +
|
||||
"ascending, asc, :ascending, :asc, 1, descending, desc, :descending, :desc, -1.")
|
||||
end
|
||||
|
||||
# This is the method to call when the client needs to be warned of
|
||||
# deprecation in the way sorting parameters are supplied.
|
||||
def warn_if_deprecated(value)
|
||||
unless value.is_a?(Array) && value.first.is_a?(Array)
|
||||
warn("\nSorting has been deprecated in favor of a new syntax: \n" +
|
||||
" :sort => [['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,121 @@
|
|||
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
||||
require 'mongo/errors'
|
||||
require 'mongo/util/conversions'
|
||||
require 'mongo/util/ordered_hash'
|
||||
require 'test/unit'
|
||||
|
||||
class ConversionsTest < Test::Unit::TestCase
|
||||
include Mongo::Conversions
|
||||
|
||||
def test_array_as_sort_parameters_with_array_of_strings
|
||||
params = array_as_sort_parameters(["field1", "field2"])
|
||||
assert_equal({ "field1" => 1, "field2" => 1 }, params)
|
||||
end
|
||||
|
||||
def test_array_as_sort_parameters_with_array_of_string_and_values
|
||||
params = array_as_sort_parameters([["field1", :asc], ["field2", :desc]])
|
||||
assert_equal({ "field1" => 1, "field2" => -1 }, params)
|
||||
end
|
||||
|
||||
def test_string_as_sort_parameters_with_string
|
||||
params = string_as_sort_parameters("field")
|
||||
assert_equal({ "field" => 1 }, params)
|
||||
end
|
||||
|
||||
def test_string_as_sort_parameters_with_empty_string
|
||||
params = string_as_sort_parameters("")
|
||||
assert_equal({}, params)
|
||||
end
|
||||
|
||||
def test_symbol_as_sort_parameters
|
||||
params = symbol_as_sort_parameters(:field)
|
||||
assert_equal({ "field" => 1 }, params)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_one
|
||||
assert_equal 1, sort_value(1)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_one_as_a_string
|
||||
assert_equal 1, sort_value("1")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_negative_one
|
||||
assert_equal -1, sort_value(-1)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_negative_one_as_a_string
|
||||
assert_equal -1, sort_value("-1")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_ascending
|
||||
assert_equal 1, sort_value("ascending")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_asc
|
||||
assert_equal 1, sort_value("asc")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_uppercase_ascending
|
||||
assert_equal 1, sort_value("ASCENDING")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_uppercase_asc
|
||||
assert_equal 1, sort_value("ASC")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_symbol_ascending
|
||||
assert_equal 1, sort_value(:ascending)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_symbol_asc
|
||||
assert_equal 1, sort_value(:asc)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_symbol_uppercase_ascending
|
||||
assert_equal 1, sort_value(:ASCENDING)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_symbol_uppercase_asc
|
||||
assert_equal 1, sort_value(:ASC)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_descending
|
||||
assert_equal -1, sort_value("descending")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_desc
|
||||
assert_equal -1, sort_value("desc")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_uppercase_descending
|
||||
assert_equal -1, sort_value("DESCENDING")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_uppercase_desc
|
||||
assert_equal -1, sort_value("DESC")
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_symbol_descending
|
||||
assert_equal -1, sort_value(:descending)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_symbol_desc
|
||||
assert_equal -1, sort_value(:desc)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_uppercase_symbol_descending
|
||||
assert_equal -1, sort_value(:DESCENDING)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_uppercase_symbol_desc
|
||||
assert_equal -1, sort_value(:DESC)
|
||||
end
|
||||
|
||||
def test_sort_value_when_value_is_invalid
|
||||
assert_raise Mongo::InvalidSortValueError do
|
||||
sort_value(2)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue