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

View File

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

View File

@ -193,16 +193,73 @@ describe Mysql2::Result do
@test_result['enum_test'].should eql('val1')
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
@test_result['set_test'].class.should eql(String)
@test_result['set_test'].should eql('val1,val2')
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
@test_result['binary_test'].class.should eql(String)
@test_result['binary_test'].should eql("test#{"\000"*6}")
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',
'varchar_test' => 'VARCHAR',
@ -220,6 +277,42 @@ describe Mysql2::Result do
@test_result[field].class.should eql(String)
@test_result[field].should eql("test")
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