From 2d160ac602db375f8cca70a0521b35f66ee3c528 Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Thu, 6 May 2010 22:05:01 -0400 Subject: [PATCH 1/2] RUBY-127 --- lib/mongo/cursor.rb | 6 +++--- test/db_api_test.rb | 14 ++++++++++++-- test/mongo_bson/bson_test.rb | 6 ++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/mongo/cursor.rb b/lib/mongo/cursor.rb index 75cb69c..967d868 100644 --- a/lib/mongo/cursor.rb +++ b/lib/mongo/cursor.rb @@ -299,10 +299,10 @@ module Mongo selector when nil {} - when String - {"$where" => Code.new(selector)} - when Code + when BSON::Code {"$where" => selector} + when String + {"$where" => BSON::Code.new(selector)} end end diff --git a/test/db_api_test.rb b/test/db_api_test.rb index 5a5113b..9bc88f5 100644 --- a/test/db_api_test.rb +++ b/test/db_api_test.rb @@ -469,8 +469,18 @@ class DBAPITest < Test::Unit::TestCase @@coll.insert('a' => 3) assert_equal 3, @@coll.count - assert_equal 1, @@coll.find('$where' => Code.new('this.a > 2')).count() - assert_equal 2, @@coll.find('$where' => Code.new('this.a > i', {'i' => 1})).count() + assert_equal 1, @@coll.find('$where' => BSON::Code.new('this.a > 2')).count() + assert_equal 2, @@coll.find('$where' => BSON::Code.new('this.a > i', {'i' => 1})).count() + end + + def test_implicit_where + @@coll.remove + @@coll.insert('a' => 2) + @@coll.insert('a' => 3) + + assert_equal 2, @@coll.count + assert_equal 1, @@coll.find('this.a > 2').count() + assert_equal 2, @@coll.find(BSON::Code.new('this.a > z', {'z' => 1})).to_a.length end def test_eval diff --git a/test/mongo_bson/bson_test.rb b/test/mongo_bson/bson_test.rb index 0290802..53f664a 100644 --- a/test/mongo_bson/bson_test.rb +++ b/test/mongo_bson/bson_test.rb @@ -98,6 +98,12 @@ class BSONTest < Test::Unit::TestCase assert_equal doc, BSON::BSON_CODER.deserialize(bson) end + def test_code_with_scope + doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})} + bson = BSON::BSON_CODER.serialize(doc) + assert_equal doc, BSON::BSON_CODER.deserialize(bson) + end + def test_number doc = {'doc' => 41.99} bson = BSON::BSON_CODER.serialize(doc) From 2cf0f2c597e9750cd94bf220bd10d43a73a1f58a Mon Sep 17 00:00:00 2001 From: Mike Dirolf Date: Fri, 7 May 2010 17:00:33 +0300 Subject: [PATCH 2/2] respect Encoding.default_internal in BSON decoder --- ext/cbson/cbson.c | 10 +++++++++- lib/bson/bson_ruby.rb | 25 +++++++++++++------------ test/mongo_bson/bson_test.rb | 17 +++++++++++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/ext/cbson/cbson.c b/ext/cbson/cbson.c index 5ff6999..225a236 100644 --- a/ext/cbson/cbson.c +++ b/ext/cbson/cbson.c @@ -88,7 +88,15 @@ static VALUE DigestMD5; #if HAVE_RUBY_ENCODING_H #include "ruby/encoding.h" -#define STR_NEW(p,n) rb_enc_str_new((p), (n), rb_utf8_encoding()) +#define STR_NEW(p,n) \ + ({ \ + VALUE _str = rb_enc_str_new((p), (n), rb_utf8_encoding()); \ + rb_encoding* internal_encoding = rb_default_internal_encoding(); \ + if (internal_encoding) { \ + _str = rb_str_export_to_enc(_str, internal_encoding); \ + } \ + _str; \ + }) /* MUST call TO_UTF8 before calling write_utf8. */ #define TO_UTF8(string) rb_str_export_to_enc((string), rb_utf8_encoding()) static void write_utf8(buffer_t buffer, VALUE string, char check_null) { diff --git a/lib/bson/bson_ruby.rb b/lib/bson/bson_ruby.rb index d046f54..db249a2 100644 --- a/lib/bson/bson_ruby.rb +++ b/lib/bson/bson_ruby.rb @@ -325,6 +325,16 @@ module BSON Regexp.new(str, options) end + def encoded_str(str) + if RUBY_VERSION >= '1.9' + str.force_encoding("utf-8") + if Encoding.default_internal + str.encode!(Encoding.default_internal) + end + end + str + end + def deserialize_string_data(buf) len = buf.get_int bytes = buf.get(len) @@ -332,10 +342,7 @@ module BSON if str.respond_to? "pack" str = str.pack("C*") end - if RUBY_VERSION >= '1.9' - str.force_encoding("utf-8") - end - str + encoded_str(str) end def deserialize_code_w_scope_data(buf) @@ -345,15 +352,12 @@ module BSON if code.respond_to? "pack" code = code.pack("C*") end - if RUBY_VERSION >= '1.9' - code.force_encoding("utf-8") - end scope_size = buf.get_int buf.position -= 4 scope = BSON_CODER.new().deserialize(buf.get(scope_size)) - Code.new(code, scope) + Code.new(encoded_str(code), scope) end def deserialize_oid_data(buf) @@ -536,10 +540,7 @@ module BSON break if b == 0 chars << b.chr end - if RUBY_VERSION >= '1.9' - chars.force_encoding("utf-8") # Mongo stores UTF-8 - end - chars + encoded_str(chars) end def bson_type(o) diff --git a/test/mongo_bson/bson_test.rb b/test/mongo_bson/bson_test.rb index 53f664a..4b645bb 100644 --- a/test/mongo_bson/bson_test.rb +++ b/test/mongo_bson/bson_test.rb @@ -90,6 +90,23 @@ class BSONTest < Test::Unit::TestCase bson = BSON::BSON_CODER.serialize({'aé'.encode('iso-8859-1') => 'hello'}) assert_equal 'hello', BSON::BSON_CODER.deserialize(bson)['aé'] end + + # Based on a test from sqlite3-ruby + def test_default_internal_is_honored + before_enc = Encoding.default_internal + + str = "壁に耳あり、障子に目あり" + bson = BSON::BSON_CODER.serialize("x" => str) + + Encoding.default_internal = 'EUC-JP' + out = BSON::BSON_CODER.deserialize(bson)["x"] + + assert_equal Encoding.default_internal, out.encoding + assert_equal str.encode('EUC-JP'), out + assert_equal str, out.encode(str.encoding) + ensure + Encoding.default_internal = before_enc + end end def test_code