namespaced the OrderedHash class

This commit is contained in:
sleverbor 2010-05-06 18:25:18 -07:00
parent 7b89523315
commit ed76126a12
14 changed files with 173 additions and 171 deletions

View File

@ -532,7 +532,7 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
}
// we have to check for an OrderedHash and handle that specially
if (strcmp(rb_obj_classname(hash), "OrderedHash") == 0) {
if (strcmp(rb_obj_classname(hash), "BSON::OrderedHash") == 0) {
VALUE keys = rb_funcall(hash, rb_intern("keys"), 0);
int i;
for(i = 0; i < RARRAY_LEN(keys); i++) {
@ -909,7 +909,7 @@ void Init_cbson() {
InvalidStringEncoding = rb_const_get(bson, rb_intern("InvalidStringEncoding"));
InvalidDocument = rb_const_get(bson, rb_intern("InvalidDocument"));
rb_require("bson/ordered_hash");
OrderedHash = rb_const_get(rb_cObject, rb_intern("OrderedHash"));
OrderedHash = rb_const_get(bson, rb_intern("OrderedHash"));
CBson = rb_define_module("CBson");
ext_version = rb_str_new2(VERSION);

View File

@ -182,7 +182,7 @@ module BSON
end
@buf.rewind
@buf.get_int # eat message size
doc = OrderedHash.new
doc = BSON::OrderedHash.new
while @buf.more?
type = @buf.get
case type
@ -383,7 +383,7 @@ module BSON
end
def serialize_dbref_element(buf, key, val)
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh['$ref'] = val.namespace
oh['$id'] = val.object_id
serialize_object_element(buf, key, oh, false)
@ -450,7 +450,7 @@ module BSON
def serialize_array_element(buf, key, val, check_keys)
# Turn array into hash with integer indices as keys
h = OrderedHash.new
h = BSON::OrderedHash.new
i = 0
val.each { |v| h[i] = v; i += 1 }
serialize_object_element(buf, key, h, check_keys, ARRAY)

View File

@ -18,123 +18,125 @@
#
# Under Ruby 1.9 and greater, this class has no added methods because Ruby's
# Hash already keeps its keys ordered by order of insertion.
class OrderedHash < Hash
module BSON
class OrderedHash < Hash
def ==(other)
begin
!other.nil? &&
keys == other.keys &&
values == other.values
rescue
false
end
end
# We only need the body of this class if the RUBY_VERSION is before 1.9
if RUBY_VERSION < '1.9'
attr_accessor :ordered_keys
def self.[] *args
oh = OrderedHash.new
if Hash === args[0]
oh.merge! args[0]
elsif (args.size % 2) != 0
raise ArgumentError, "odd number of elements for Hash"
else
0.step(args.size - 1, 2) do |key|
value = key + 1
oh[args[key]] = args[value]
end
end
oh
end
def initialize(*a, &b)
super
@ordered_keys = []
end
def keys
@ordered_keys || []
end
def []=(key, value)
@ordered_keys ||= []
@ordered_keys << key unless @ordered_keys.include?(key)
super(key, value)
end
def each
@ordered_keys ||= []
@ordered_keys.each { |k| yield k, self[k] }
self
end
alias :each_pair :each
def to_a
@ordered_keys ||= []
@ordered_keys.map { |k| [k, self[k]] }
end
def values
collect { |k, v| v }
end
def merge(other)
oh = self.dup
oh.merge!(other)
oh
end
def merge!(other)
@ordered_keys ||= []
@ordered_keys += other.keys # unordered if not an OrderedHash
@ordered_keys.uniq!
super(other)
end
alias :update :merge!
def inspect
str = '{'
str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
str << '}'
end
def delete(key, &block)
@ordered_keys.delete(key) if @ordered_keys
super
end
def delete_if(&block)
self.each { |k,v|
if yield k, v
delete(k)
end
}
end
def clear
super
@ordered_keys = []
end
def hash
code = 17
each_pair do |key, value|
code = 37 * code + key.hash
code = 37 * code + value.hash
end
code & 0x7fffffff
end
def eql?(o)
if o.instance_of? OrderedHash
self.hash == o.hash
else
def ==(other)
begin
!other.nil? &&
keys == other.keys &&
values == other.values
rescue
false
end
end
# We only need the body of this class if the RUBY_VERSION is before 1.9
if RUBY_VERSION < '1.9'
attr_accessor :ordered_keys
def self.[] *args
oh = BSON::OrderedHash.new
if Hash === args[0]
oh.merge! args[0]
elsif (args.size % 2) != 0
raise ArgumentError, "odd number of elements for Hash"
else
0.step(args.size - 1, 2) do |key|
value = key + 1
oh[args[key]] = args[value]
end
end
oh
end
def initialize(*a, &b)
super
@ordered_keys = []
end
def keys
@ordered_keys || []
end
def []=(key, value)
@ordered_keys ||= []
@ordered_keys << key unless @ordered_keys.include?(key)
super(key, value)
end
def each
@ordered_keys ||= []
@ordered_keys.each { |k| yield k, self[k] }
self
end
alias :each_pair :each
def to_a
@ordered_keys ||= []
@ordered_keys.map { |k| [k, self[k]] }
end
def values
collect { |k, v| v }
end
def merge(other)
oh = self.dup
oh.merge!(other)
oh
end
def merge!(other)
@ordered_keys ||= []
@ordered_keys += other.keys # unordered if not an BSON::OrderedHash
@ordered_keys.uniq!
super(other)
end
alias :update :merge!
def inspect
str = '{'
str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
str << '}'
end
def delete(key, &block)
@ordered_keys.delete(key) if @ordered_keys
super
end
def delete_if(&block)
self.each { |k,v|
if yield k, v
delete(k)
end
}
end
def clear
super
@ordered_keys = []
end
def hash
code = 17
each_pair do |key, value|
code = 37 * code + key.hash
code = 37 * code + value.hash
end
code & 0x7fffffff
end
def eql?(o)
if o.instance_of? BSON::OrderedHash
self.hash == o.hash
else
false
end
end
end
end
end
end

View File

@ -373,7 +373,7 @@ module Mongo
# @core indexes create_index-instance_method
def create_index(spec, opts={})
opts.assert_valid_keys(:min, :max, :background, :unique, :dropDups)
field_spec = OrderedHash.new
field_spec = BSON::OrderedHash.new
if spec.is_a?(String) || spec.is_a?(Symbol)
field_spec[spec.to_s] = 1
elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
@ -445,7 +445,7 @@ module Mongo
#
# @core findandmodify find_and_modify-instance_method
def find_and_modify(opts={})
cmd = OrderedHash.new
cmd = BSON::OrderedHash.new
cmd[:findandmodify] = @name
cmd.merge!(opts)
cmd[:sort] = Mongo::Support.format_order_clause(opts[:sort]) if opts[:sort]
@ -478,7 +478,7 @@ module Mongo
map = BSON::Code.new(map) unless map.is_a?(BSON::Code)
reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
hash = OrderedHash.new
hash = BSON::OrderedHash.new
hash['mapreduce'] = self.name
hash['map'] = map
hash['reduce'] = reduce
@ -570,7 +570,7 @@ module Mongo
# @return [Array] an array of distinct values.
def distinct(key, query=nil)
raise MongoArgumentError unless [String, Symbol].include?(key.class)
command = OrderedHash.new
command = BSON::OrderedHash.new
command[:distinct] = @name
command[:key] = key.to_s
command[:query] = query
@ -652,7 +652,7 @@ module Mongo
when nil
nil
else
h = OrderedHash.new
h = BSON::OrderedHash.new
hint.to_a.each { |k| h[k] = 1 }
h
end

View File

@ -269,7 +269,7 @@ module Mongo
# @param [String] username username for authentication against from_db (>=1.3.x).
# @param [String] password password for authentication against from_db (>=1.3.x).
def copy_database(from, to, from_host="localhost", username=nil, password=nil)
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:copydb] = 1
oh[:fromhost] = from_host
oh[:fromdb] = from
@ -278,7 +278,7 @@ module Mongo
unless username && password
raise MongoArgumentError, "Both username and password must be supplied for authentication."
end
nonce_cmd = OrderedHash.new
nonce_cmd = BSON::OrderedHash.new
nonce_cmd[:copydbgetnonce] = 1
nonce_cmd[:fromhost] = from_host
result = self["admin"].command(nonce_cmd, true, true)
@ -659,7 +659,7 @@ module Mongo
BSON::BSON_RUBY.serialize_cstr(message, "#{db_name}.$cmd")
message.put_int(0)
message.put_int(-1)
cmd = OrderedHash.new
cmd = BSON::OrderedHash.new
cmd[:getlasterror] = 1
if opts.is_a?(Hash)
opts.assert_valid_keys(:w, :wtimeout, :fsync)

View File

@ -94,7 +94,7 @@ module Mongo
#
# @raise [OperationFailure] on a database error.
def count
command = OrderedHash["count", @collection.name,
command = BSON::OrderedHash["count", @collection.name,
"query", @selector,
"fields", @fields]
response = @db.command(command)
@ -366,7 +366,7 @@ module Mongo
def construct_query_spec
return @selector if @selector.has_key?('$query')
spec = OrderedHash.new
spec = BSON::OrderedHash.new
spec['$query'] = @selector
spec['$orderby'] = Mongo::Support.format_order_clause(@order) if @order
spec['$hint'] = @hint if @hint && @hint.length > 0

View File

@ -89,7 +89,7 @@ module Mongo
raise "error retrieving nonce: #{doc}" unless ok?(doc)
nonce = doc['nonce']
auth = OrderedHash.new
auth = BSON::OrderedHash.new
auth['authenticate'] = 1
auth['user'] = username
auth['nonce'] = nonce
@ -212,7 +212,7 @@ module Mongo
end
# Create a new collection.
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:create] = name
doc = command(oh.merge(options || {}))
ok = doc['ok']
@ -255,7 +255,7 @@ module Mongo
# error has occurred.
def error(opts={})
opts.assert_valid_keys(:w, :wtimeout, :fsync)
cmd = OrderedHash.new
cmd = BSON::OrderedHash.new
cmd[:getlasterror] = 1
cmd.merge!(opts) unless opts.empty?
doc = command(cmd)
@ -337,7 +337,7 @@ module Mongo
code = BSON::Code.new(code)
end
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:$eval] = code
oh[:args] = args
doc = command(oh)
@ -354,7 +354,7 @@ module Mongo
#
# @raise MongoDBError if there's an error renaming the collection.
def rename_collection(from, to)
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:renameCollection] = "#{@name}.#{from}"
oh[:to] = "#{@name}.#{to}"
doc = command(oh, true)
@ -371,7 +371,7 @@ module Mongo
#
# @raise MongoDBError if there's an error renaming the collection.
def drop_index(collection_name, index_name)
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:deleteIndexes] = collection_name
oh[:index] = index_name
doc = command(oh)
@ -502,7 +502,7 @@ module Mongo
#
# @core profiling profiling_level-instance_method
def profiling_level
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:profile] = -1
doc = command(oh)
raise "Error with profile command: #{doc.inspect}" unless ok?(doc) && doc['was'].kind_of?(Numeric)
@ -523,7 +523,7 @@ module Mongo
#
# @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+.
def profiling_level=(level)
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh[:profile] = case level
when :off
0

View File

@ -197,7 +197,7 @@ module Mongo
private
def create_chunk(n)
chunk = OrderedHash.new
chunk = BSON::OrderedHash.new
chunk['_id'] = BSON::ObjectID.new
chunk['n'] = n
chunk['files_id'] = @files_id
@ -319,7 +319,7 @@ module Mongo
end
def to_mongo_object
h = OrderedHash.new
h = BSON::OrderedHash.new
h['_id'] = @files_id
h['filename'] = @filename if @filename
h['contentType'] = @content_type
@ -335,7 +335,7 @@ module Mongo
# Get a server-side md5 and validate against the client if running in safe mode.
def get_md5
md5_command = OrderedHash.new
md5_command = BSON::OrderedHash.new
md5_command['filemd5'] = @files_id
md5_command['root'] = @fs_name
@server_md5 = @files.db.command(md5_command)['md5']

View File

@ -31,7 +31,7 @@ module Mongo #:nodoc:
# <tt>array_as_sort_parameters([["field1", :asc], ["field2", :desc]])</tt> =>
# <tt>{ "field1" => 1, "field2" => -1}</tt>
def array_as_sort_parameters(value)
order_by = OrderedHash.new
order_by = BSON::OrderedHash.new
if value.first.is_a? Array
value.each do |param|
if (param.class.name == "String")

View File

@ -150,7 +150,7 @@ class Features14Test < Test::Unit::TestCase
end
should "use geoNear command to return distances from a point" do
cmd = OrderedHash.new
cmd = BSON::OrderedHash.new
cmd['geoNear'] = 'places'
cmd['near'] = @empire_state
cmd['num'] = 6

View File

@ -323,14 +323,14 @@ class TestCollection < Test::Unit::TestCase
assert_equal @@test.find_one(nil), @@test.find_one()
assert_equal @@test.find_one({}), @@test.find_one()
assert_equal @@test.find_one("hello" => "world"), @@test.find_one()
assert_equal @@test.find_one(OrderedHash["hello", "world"]), @@test.find_one()
assert_equal @@test.find_one(BSON::OrderedHash["hello", "world"]), @@test.find_one()
assert @@test.find_one(nil, :fields => ["hello"]).include?("hello")
assert !@@test.find_one(nil, :fields => ["foo"]).include?("hello")
assert_equal ["_id"], @@test.find_one(nil, :fields => []).keys()
assert_equal nil, @@test.find_one("hello" => "foo")
assert_equal nil, @@test.find_one(OrderedHash["hello", "foo"])
assert_equal nil, @@test.find_one(BSON::OrderedHash["hello", "foo"])
assert_equal nil, @@test.find_one(ObjectID.new)
assert_raise TypeError do

View File

@ -46,14 +46,14 @@ class DBAPITest < Test::Unit::TestCase
end
def test_save_ordered_hash
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh['a'] = -1
oh['b'] = 'foo'
oid = @@coll.save(oh)
assert_equal 'foo', @@coll.find_one(oid)['b']
oh = OrderedHash['a' => 1, 'b' => 'foo']
oh = BSON::OrderedHash['a' => 1, 'b' => 'foo']
oid = @@coll.save(oh)
assert_equal 'foo', @@coll.find_one(oid)['b']
end
@ -187,7 +187,7 @@ class DBAPITest < Test::Unit::TestCase
# 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.
oh = OrderedHash.new
oh = BSON::OrderedHash.new
oh['a'] = -1
assert_raise InvalidSortValueError do
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a

View File

@ -123,7 +123,7 @@ class BSONTest < Test::Unit::TestCase
end
def test_ordered_hash
doc = OrderedHash.new
doc = BSON::OrderedHash.new
doc["b"] = 1
doc["a"] = 2
doc["c"] = 3
@ -284,16 +284,16 @@ class BSONTest < Test::Unit::TestCase
end
def test_put_id_first
val = OrderedHash.new
val = BSON::OrderedHash.new
val['not_id'] = 1
val['_id'] = 2
roundtrip = BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(val, false, true).to_a)
assert_kind_of OrderedHash, roundtrip
assert_kind_of BSON::OrderedHash, roundtrip
assert_equal '_id', roundtrip.keys.first
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
roundtrip = BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(val, false, true).to_a)
assert_kind_of OrderedHash, roundtrip
assert_kind_of BSON::OrderedHash, roundtrip
assert_equal '_id', roundtrip.keys.first
end
@ -354,7 +354,7 @@ class BSONTest < Test::Unit::TestCase
end
def test_do_not_change_original_object
val = OrderedHash.new
val = BSON::OrderedHash.new
val['not_id'] = 1
val['_id'] = 2
assert val.keys.include?('_id')
@ -426,7 +426,7 @@ class BSONTest < Test::Unit::TestCase
end
def test_move_id
a = OrderedHash.new
a = BSON::OrderedHash.new
a['text'] = 'abc'
a['key'] = 'abc'
a['_id'] = 1
@ -441,10 +441,10 @@ class BSONTest < Test::Unit::TestCase
end
def test_move_id_with_nested_doc
b = OrderedHash.new
b = BSON::OrderedHash.new
b['text'] = 'abc'
b['_id'] = 2
c = OrderedHash.new
c = BSON::OrderedHash.new
c['text'] = 'abc'
c['hash'] = b
c['_id'] = 3

View File

@ -3,7 +3,7 @@ require 'test/test_helper'
class OrderedHashTest < Test::Unit::TestCase
def setup
@oh = OrderedHash.new
@oh = BSON::OrderedHash.new
@oh['c'] = 1
@oh['a'] = 2
@oh['z'] = 3
@ -11,31 +11,31 @@ class OrderedHashTest < Test::Unit::TestCase
end
def test_initialize
a = OrderedHash.new
a = BSON::OrderedHash.new
a['x'] = 1
a['y'] = 2
b = OrderedHash['x' => 1, 'y' => 2]
b = BSON::OrderedHash['x' => 1, 'y' => 2]
assert_equal a, b
end
def test_hash_code
o = OrderedHash.new
o = BSON::OrderedHash.new
o['number'] = 50
assert o.hash
end
def test_empty
assert_equal [], OrderedHash.new.keys
assert_equal [], BSON::OrderedHash.new.keys
end
def test_uniq
list = []
doc = OrderedHash.new
doc = BSON::OrderedHash.new
doc['_id'] = 'ab12'
doc['name'] = 'test'
same_doc = OrderedHash.new
same_doc = BSON::OrderedHash.new
same_doc['_id'] = 'ab12'
same_doc['name'] = 'test'
list << doc
@ -46,23 +46,23 @@ class OrderedHashTest < Test::Unit::TestCase
end
def test_equality
a = OrderedHash.new
a = BSON::OrderedHash.new
a['x'] = 1
a['y'] = 2
b = OrderedHash.new
b = BSON::OrderedHash.new
b['y'] = 2
b['x'] = 1
c = OrderedHash.new
c = BSON::OrderedHash.new
c['x'] = 1
c['y'] = 2
d = OrderedHash.new
d = BSON::OrderedHash.new
d['x'] = 2
d['y'] = 3
e = OrderedHash.new
e = BSON::OrderedHash.new
e['z'] = 1
e['y'] = 2
@ -105,7 +105,7 @@ class OrderedHashTest < Test::Unit::TestCase
end
def test_merge
other = OrderedHash.new
other = BSON::OrderedHash.new
other['f'] = 'foo'
noob = @oh.merge(other)
assert_equal @ordered_keys + ['f'], noob.keys
@ -113,7 +113,7 @@ class OrderedHashTest < Test::Unit::TestCase
end
def test_merge_bang
other = OrderedHash.new
other = BSON::OrderedHash.new
other['f'] = 'foo'
@oh.merge!(other)
assert_equal @ordered_keys + ['f'], @oh.keys
@ -121,7 +121,7 @@ class OrderedHashTest < Test::Unit::TestCase
end
def test_merge_bang_with_overlap
other = OrderedHash.new
other = BSON::OrderedHash.new
other['a'] = 'apple'
other['c'] = 'crab'
other['f'] = 'foo'
@ -141,7 +141,7 @@ class OrderedHashTest < Test::Unit::TestCase
end
def test_update
other = OrderedHash.new
other = BSON::OrderedHash.new
other['f'] = 'foo'
noob = @oh.update(other)
assert_equal @ordered_keys + ['f'], noob.keys