use Encoding.default_internal

This commit is contained in:
Brian Lopez 2010-06-13 15:50:03 -07:00
parent ef37f7ef76
commit 6751a98873
3 changed files with 115 additions and 7 deletions

View File

@ -301,6 +301,9 @@ static VALUE rb_mysql_client_escape(VALUE self, VALUE str) {
MYSQL * client; MYSQL * client;
VALUE newStr; VALUE newStr;
unsigned long newLen, oldLen; unsigned long newLen, oldLen;
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *default_internal_enc = rb_default_internal_encoding();
#endif
Check_Type(str, T_STRING); Check_Type(str, T_STRING);
oldLen = RSTRING_LEN(str); oldLen = RSTRING_LEN(str);
@ -318,7 +321,10 @@ static VALUE rb_mysql_client_escape(VALUE self, VALUE str) {
} else { } else {
newStr = rb_str_new(escaped, newLen); newStr = rb_str_new(escaped, newLen);
#ifdef HAVE_RUBY_ENCODING_H #ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate_index(newStr, utf8Encoding); rb_enc_associate(newStr, utf8Encoding);
if (default_internal_enc) {
newStr = rb_str_export_to_enc(newStr, default_internal_enc);
}
#endif #endif
return newStr; return newStr;
} }
@ -473,6 +479,9 @@ static VALUE rb_mysql_result_fetch_row(int argc, VALUE * argv, VALUE self) {
unsigned int i = 0, symbolizeKeys = 0; unsigned int i = 0, symbolizeKeys = 0;
unsigned long * fieldLengths; unsigned long * fieldLengths;
void * ptr; void * ptr;
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *default_internal_enc = rb_default_internal_encoding();
#endif
GetMysql2Result(self, wrapper); GetMysql2Result(self, wrapper);
@ -511,7 +520,10 @@ static VALUE rb_mysql_result_fetch_row(int argc, VALUE * argv, VALUE self) {
} else { } else {
field = rb_str_new(fields[i].name, fields[i].name_length); field = rb_str_new(fields[i].name, fields[i].name_length);
#ifdef HAVE_RUBY_ENCODING_H #ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate_index(field, utf8Encoding); rb_enc_associate(field, utf8Encoding);
if (default_internal_enc) {
field = rb_str_export_to_enc(field, default_internal_enc);
}
#endif #endif
} }
rb_ary_store(wrapper->fields, i, field); rb_ary_store(wrapper->fields, i, field);
@ -595,9 +607,12 @@ static VALUE rb_mysql_result_fetch_row(int argc, VALUE * argv, VALUE self) {
#ifdef HAVE_RUBY_ENCODING_H #ifdef HAVE_RUBY_ENCODING_H
// rudimentary check for binary content // rudimentary check for binary content
if ((fields[i].flags & BINARY_FLAG) || fields[i].charsetnr == 63) { if ((fields[i].flags & BINARY_FLAG) || fields[i].charsetnr == 63) {
rb_enc_associate_index(val, binaryEncoding); rb_enc_associate(val, binaryEncoding);
} else { } else {
rb_enc_associate_index(val, utf8Encoding); rb_enc_associate(val, utf8Encoding);
if (default_internal_enc) {
val = rb_str_export_to_enc(val, default_internal_enc);
}
} }
#endif #endif
break; break;
@ -737,7 +752,7 @@ void Init_mysql2_ext() {
sym_async = ID2SYM(rb_intern("async")); sym_async = ID2SYM(rb_intern("async"));
#ifdef HAVE_RUBY_ENCODING_H #ifdef HAVE_RUBY_ENCODING_H
utf8Encoding = rb_enc_find_index("UTF-8"); utf8Encoding = rb_utf8_encoding();
binaryEncoding = rb_enc_find_index("binary"); binaryEncoding = rb_enc_find("binary");
#endif #endif
} }

View File

@ -15,7 +15,7 @@
#ifdef HAVE_RUBY_ENCODING_H #ifdef HAVE_RUBY_ENCODING_H
#include <ruby/encoding.h> #include <ruby/encoding.h>
static int utf8Encoding, binaryEncoding; static rb_encoding *utf8Encoding, *binaryEncoding;
#endif #endif
#if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(__GNUC__) && (__GNUC__ >= 3)

View File

@ -193,16 +193,73 @@ describe Mysql2::Result do
@test_result['enum_test'].should eql('val1') @test_result['enum_test'].should eql('val1')
end end
if RUBY_VERSION =~ /^1.9/
context "string encoding for ENUM values" do
it "should default to utf-8 if Encoding.default_internal is nil" do
Encoding.default_internal = nil
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['enum_test'].encoding.should eql(Encoding.find('utf-8'))
end
it "should use Encoding.default_internal" do
Encoding.default_internal = Encoding.find('utf-8')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['enum_test'].encoding.should eql(Encoding.default_internal)
Encoding.default_internal = Encoding.find('us-ascii')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['enum_test'].encoding.should eql(Encoding.default_internal)
end
end
end
it "should return String for a SET value" do it "should return String for a SET value" do
@test_result['set_test'].class.should eql(String) @test_result['set_test'].class.should eql(String)
@test_result['set_test'].should eql('val1,val2') @test_result['set_test'].should eql('val1,val2')
end end
if RUBY_VERSION =~ /^1.9/
context "string encoding for SET values" do
it "should default to utf-8 if Encoding.default_internal is nil" do
Encoding.default_internal = nil
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['set_test'].encoding.should eql(Encoding.find('utf-8'))
end
it "should use Encoding.default_internal" do
Encoding.default_internal = Encoding.find('utf-8')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['set_test'].encoding.should eql(Encoding.default_internal)
Encoding.default_internal = Encoding.find('us-ascii')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['set_test'].encoding.should eql(Encoding.default_internal)
end
end
end
it "should return String for a BINARY value" do it "should return String for a BINARY value" do
@test_result['binary_test'].class.should eql(String) @test_result['binary_test'].class.should eql(String)
@test_result['binary_test'].should eql("test#{"\000"*6}") @test_result['binary_test'].should eql("test#{"\000"*6}")
end end
if RUBY_VERSION =~ /^1.9/
context "string encoding for BINARY values" do
it "should default to binary if Encoding.default_internal is nil" do
Encoding.default_internal = nil
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['binary_test'].encoding.should eql(Encoding.find('binary'))
end
it "should not use Encoding.default_internal" do
Encoding.default_internal = Encoding.find('utf-8')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['binary_test'].encoding.should eql(Encoding.find('binary'))
Encoding.default_internal = Encoding.find('us-ascii')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['binary_test'].encoding.should eql(Encoding.find('binary'))
end
end
end
{ {
'char_test' => 'CHAR', 'char_test' => 'CHAR',
'varchar_test' => 'VARCHAR', 'varchar_test' => 'VARCHAR',
@ -220,6 +277,42 @@ describe Mysql2::Result do
@test_result[field].class.should eql(String) @test_result[field].class.should eql(String)
@test_result[field].should eql("test") @test_result[field].should eql("test")
end end
if RUBY_VERSION =~ /^1.9/
context "string encoding for #{type} values" do
if ['VARBINARY', 'TINYBLOB', 'BLOB', 'MEDIUMBLOB', 'LONGBLOB'].include?(type)
it "should default to binary if Encoding.default_internal is nil" do
Encoding.default_internal = nil
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['binary_test'].encoding.should eql(Encoding.find('binary'))
end
it "should not use Encoding.default_internal" do
Encoding.default_internal = Encoding.find('utf-8')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['binary_test'].encoding.should eql(Encoding.find('binary'))
Encoding.default_internal = Encoding.find('us-ascii')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result['binary_test'].encoding.should eql(Encoding.find('binary'))
end
else
it "should default to utf-8 if Encoding.default_internal is nil" do
Encoding.default_internal = nil
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result[field].encoding.should eql(Encoding.find('utf-8'))
end
it "should use Encoding.default_internal" do
Encoding.default_internal = Encoding.find('utf-8')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result[field].encoding.should eql(Encoding.default_internal)
Encoding.default_internal = Encoding.find('us-ascii')
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
result[field].encoding.should eql(Encoding.default_internal)
end
end
end
end
end end
end end
end end