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.
|
# 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.
|
||||||
|
class InvalidSortValueError < RuntimeError; end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
|
|
||||||
require 'mongo/message/message'
|
require 'mongo/message/message'
|
||||||
require 'mongo/message/opcodes'
|
require 'mongo/message/opcodes'
|
||||||
|
require 'mongo/util/conversions'
|
||||||
require 'mongo/util/ordered_hash'
|
require 'mongo/util/ordered_hash'
|
||||||
|
|
||||||
module Mongo
|
module Mongo
|
||||||
|
|
||||||
class QueryMessage < Message
|
class QueryMessage < Message
|
||||||
|
include Mongo::Conversions
|
||||||
|
|
||||||
attr_reader :query
|
attr_reader :query
|
||||||
|
|
||||||
|
@ -37,24 +38,14 @@ module Mongo
|
||||||
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 && query.order_by.length > 0
|
||||||
sel['orderby'] = case query.order_by
|
order_by = query.order_by
|
||||||
when String
|
sel['orderby'] = case order_by
|
||||||
{query.order_by => 1}
|
when String then string_as_sort_parameters(order_by)
|
||||||
when Array
|
when Symbol then symbol_as_sort_parameters(order_by)
|
||||||
h = OrderedHash.new
|
when Array then array_as_sort_parameters(order_by)
|
||||||
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
|
|
||||||
when Hash # Should be an ordered hash, but this message doesn't care
|
when Hash # Should be an ordered hash, but this message doesn't care
|
||||||
query.order_by
|
warn_if_deprecated(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 "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
|
||||||
end
|
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